⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpgraph_pie.php

📁 通达OA2007SE源代码 非常好的
💻 PHP
📖 第 1 页 / 共 3 页
字号:
	    for($i=0; $sum > 0 && $i < $n; ++$i) {		$j = $n-$i-1;		$d = $this->data[$i];		$angle1 = $angle2;		$accsum += $d;		$angle2 = $this->startangle+2*M_PI*$accsum/$sum;		if( empty($this->explode_radius[$j]) )		    $this->explode_radius[$j]=0;		$la = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1);		$xcm = $xc + $this->explode_radius[$j]*cos($la)*$expscale;		$ycm = $yc - $this->explode_radius[$j]*sin($la)*$expscale;				$xcm += $this->ishadowdrop*$expscale;		$ycm += $this->ishadowdrop*$expscale;		$img->CakeSlice($xcm,$ycm,$radius,$radius,				$angle1*180/M_PI,$angle2*180/M_PI,$this->ishadowcolor);			    }	}	$accsum=0;	$angle2 = $this->startangle;	$img->SetColor($this->color);	for($i=0; $sum>0 && $i < $n; ++$i) {	    $j = $n-$i-1;	    if( empty($this->explode_radius[$j]) )		$this->explode_radius[$j]=0;	    $d = $this->data[$i];	    $angle1 = $angle2;	    $accsum += $d;	    $angle2 = $this->startangle+2*M_PI*$accsum/$sum;	    $this->la[$i] = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1);	    if( $d == 0 ) continue;	    if( $this->setslicecolors==null )		$slicecolor=$colors[$ta[$i%$numcolors]];	    else		$slicecolor=$this->setslicecolors[$i%$numcolors];	    if( $this->pie_interior_border && $aaoption===0 )		$img->SetColor($this->color);	    else		$img->SetColor($slicecolor);	    $arccolor = $this->pie_border && $aaoption===0 ? $this->color : "";	    $xcm = $xc + $this->explode_radius[$j]*cos($this->la[$i])*$expscale;	    $ycm = $yc - $this->explode_radius[$j]*sin($this->la[$i])*$expscale;	    if( $aaoption !== 2 ) {		$img->CakeSlice($xcm,$ycm,$radius-1,$radius-1,				$angle1*180/M_PI,$angle2*180/M_PI,$slicecolor,$arccolor);	    }	    if( $this->csimtargets && $aaoption !== 1 ) {		$this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2);	    }	}	// Format the titles for each slice	if( $aaoption !== 2 ) {	    for( $i=0; $i < $n; ++$i) {		if( $this->labeltype==0 ) {		    if( $sum != 0 )			$l = 100.0*$this->data[$i]/$sum;		    else			$l = 0.0;		}		elseif( $this->labeltype==1 ) {		    $l = $this->data[$i]*1.0;		}		else {		    $l = $this->adjusted_data[$i];		}		if( isset($this->labels[$i]) && is_string($this->labels[$i]) )		    $this->labels[$i]=sprintf($this->labels[$i],$l);		else		    $this->labels[$i]=$l;	    }	}	if( $this->value->show && $aaoption !== 1 ) {	    $this->StrokeAllLabels($img,$xc,$yc,$radius);	}	// Adjust title position	if( $aaoption !== 1 ) {	    $this->title->SetPos($xc,			  $yc-$this->title->GetFontHeight($img)-$radius-$this->title->margin,			  "center","bottom");	    $this->title->Stroke($img);	}    }//---------------// PRIVATE METHODS	    function NormAngle($a) {	while( $a < 0 ) $a += 2*M_PI;	while( $a > 2*M_PI ) $a -= 2*M_PI;	return $a;    }    function Quadrant($a) {	$a=$this->NormAngle($a);	if( $a > 0 && $a <= M_PI/2 )	    return 0;	if( $a > M_PI/2 && $a <= M_PI )	    return 1;	if( $a > M_PI && $a <= 1.5*M_PI )	    return 2;	if( $a > 1.5*M_PI )	    return 3;    }    function StrokeGuideLabels($img,$xc,$yc,$radius) {	$n = count($this->labels);	//-----------------------------------------------------------------------	// Step 1 of the algorithm is to construct a number of clusters	// a cluster is defined as all slices within the same quadrant (almost)	// that has an angualr distance less than the treshold	//-----------------------------------------------------------------------	$tresh_hold=25 * M_PI/180; // 25 degrees difference to be in a cluster	$incluster=false;	// flag if we are currently in a cluster or not	$clusters = array();	// array of clusters	$cidx=-1;		// running cluster index	// Go through all the labels and construct a number of clusters	for($i=0; $i < $n-1; ++$i) {	    // Calc the angle distance between two consecutive slices	    $a1=$this->la[$i];	    $a2=$this->la[$i+1];	    $q1 = $this->Quadrant($a1);	    $q2 = $this->Quadrant($a2);	    $diff = abs($a1-$a2);	    if( $diff < $tresh_hold ) {		if( $incluster ) {		    $clusters[$cidx][1]++;		    // Each cluster can only cover one quadrant		    // Do we cross a quadrant ( and must break the cluster)		    if( $q1 !=  $q2 ) {			// If we cross a quadrant boundary we normally start a 			// new cluster. However we need to take the 12'a clock			// and 6'a clock positions into a special consideration.			// Case 1: WE go from q=1 to q=2 if the last slice on			// the cluster for q=1 is close to 12'a clock and the 			// first slice in q=0 is small we extend the previous			// cluster			if( $q1 == 1 && $q2 == 0 && $a2 > (90-15)*M_PI/180 ) {			    if( $i < $n-2 ) {				$a3 = $this->la[$i+2];				// If there isn't a cluster coming up with the next-next slice				// we extend the previous cluster to cover this slice as well				if( abs($a3-$a2) >= $tresh_hold ) {				    $clusters[$cidx][1]++;				    $i++;				}			    }			}			elseif( $q1 == 3 && $q2 == 2 && $a2 > (270-15)*M_PI/180 ) {			    if( $i < $n-2 ) {				$a3 = $this->la[$i+2];				// If there isn't a cluster coming up with the next-next slice				// we extend the previous cluster to cover this slice as well				if( abs($a3-$a2) >= $tresh_hold ) {				    $clusters[$cidx][1]++;				    $i++;				}			    }			}			if( $q1==2 && $q2==1 && $a2 > (180-15)*M_PI/180 ) {			    $clusters[$cidx][1]++;			    $i++;			    			}						$incluster = false;		    }		}		elseif( $q1 == $q2)  {		    $incluster = true;		    // Now we have a special case for quadrant 0. If we previously		    // have a cluster of one in quadrant 0 we just extend that		    // cluster. If we don't do this then we risk that the label		    // for the cluster of one will cross the guide-line		    if( $q1 == 0 && $cidx > -1 && 			$clusters[$cidx][1] == 1 && 			$this->Quadrant($this->la[$clusters[$cidx][0]]) == 0 ) {			$clusters[$cidx][1]++;		    }		    else {			$cidx++;			$clusters[$cidx][0] = $i;			$clusters[$cidx][1] = 1;		    }		}		else {  		    // Create a "cluster" of one since we are just crossing		    // a quadrant		    $cidx++;		    $clusters[$cidx][0] = $i;		    $clusters[$cidx][1] = 1;	    		}	    }	    else {		if( $incluster ) {		    // Add the last slice		    $clusters[$cidx][1]++;		    $incluster = false;		}		else { // Create a "cluster" of one		    $cidx++;		    $clusters[$cidx][0] = $i;		    $clusters[$cidx][1] = 1;	    		}	    }	}	// Handle the very last slice	if( $incluster ) {	    $clusters[$cidx][1]++;	}	else { // Create a "cluster" of one	    $cidx++;	    $clusters[$cidx][0] = $i;	    $clusters[$cidx][1] = 1;	    	}	/*	if( true ) { 	    // Debug printout in labels	    for( $i=0; $i <= $cidx; ++$i ) {		for( $j=0; $j < $clusters[$i][1]; ++$j ) {		    $a = $this->la[$clusters[$i][0]+$j];		    $aa = round($a*180/M_PI);		    $q = $this->Quadrant($a);		    $this->labels[$clusters[$i][0]+$j]="[$q:$aa] $i:$j";		}	    }	}	*/	//-----------------------------------------------------------------------	// Step 2 of the algorithm is use the clusters and draw the labels	// and guidelines	//-----------------------------------------------------------------------	// We use the font height as the base factor for how far we need to	// spread the labels in the Y-direction.	$this->value->ApplyFont($img);	$fh = $img->GetFontHeight();	$origvstep=$fh*$this->iGuideVFactor;	$this->value->SetMargin(0);	// Number of clusters found	$nc = count($clusters);	// Walk through all the clusters	for($i=0; $i < $nc; ++$i) {	    // Start angle and number of slices in this cluster	    $csize = $clusters[$i][1];	    $a = $this->la[$clusters[$i][0]];	    $q = $this->Quadrant($a);	    // Now set up the start and end conditions to make sure that	    // in each cluster we walk through the all the slices starting with the slice	    // closest to the equator. Since all slices are numbered clockwise from "3'a clock"	    // we have different conditions depending on in which quadrant the slice lies within.	    if( $q == 0 ) {		$start = $csize-1; $idx = $start; $step = -1; $vstep = -$origvstep;	    }	    elseif( $q == 1 ) {		$start = 0; $idx = $start; $step = 1; $vstep = -$origvstep;	    }	    elseif( $q == 2 ) {		$start = $csize-1; $idx = $start; $step = -1; $vstep = $origvstep;	    }	    elseif( $q == 3 ) {		$start = 0; $idx = $start; $step = 1; $vstep = $origvstep;	    }	    // Walk through all slices within this cluster	    for($j=0; $j < $csize; ++$j) {   		// Now adjust the position of the labels in each cluster starting		// with the slice that is closest to the equator of the pie		$a = $this->la[$clusters[$i][0]+$idx];		    		// Guide line start in the center of the arc of the slice		$r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)];		$x = round($r*cos($a)+$xc);		$y = round($yc-$r*sin($a));				// The distance from the arc depends on chosen font and the "R-Factor"		$r += $fh*$this->iGuideLineRFactor;		// Should the labels be placed curved along the pie or in straight columns		// outside the pie?		if( $this->iGuideLineCurve )		    $xt=round($r*cos($a)+$xc);		// If this is the first slice in the cluster we need some first time		// proessing		if( $idx == $start ) {		    if( ! $this->iGuideLineCurve )			$xt=round($r*cos($a)+$xc);		    $yt=round($yc-$r*sin($a));		    // Some special consideration in case this cluster starts		    // in quadrant 1 or 3 very close to the "equator" (< 20 degrees) 		    // and the previous clusters last slice is within the tolerance. 		    // In that case we add a font height to this labels Y-position 		    // so it doesn't collide with		    // the slice in the previous cluster		    $prevcluster = ($i + ($nc-1) ) % $nc;		    $previdx=$clusters[$prevcluster][0]+$clusters[$prevcluster][1]-1;		    if( $q == 1 && $a > 160*M_PI/180 ) {			// Get the angle for the previous clusters last slice			$diff = abs($a-$this->la[$previdx]);			 if( $diff < $tresh_hold ) {			     $yt -= $fh;			 }		    }		    elseif( $q == 3 && $a > 340*M_PI/180 ) {			// We need to subtract 360 to compare angle distance between			// q=0 and q=3			$diff = abs($a-$this->la[$previdx]-360*M_PI/180);			if( $diff < $tresh_hold ) {			     $yt += $fh;			}		    }		}		else {		    // The step is at minimum $vstep but if the slices are relatively large		    // we make sure that we add at least a step that corresponds to the vertical		    // distance between the centers at the arc on the slice		    $prev_a = $this->la[$clusters[$i][0]+($idx-$step)];		    $dy = abs($radius*(sin($a)-sin($prev_a))*1.2);		    if( $vstep > 0 )			$yt += max($vstep,$dy);		    else			$yt += min($vstep,-$dy);		}		$label = $this->labels[$clusters[$i][0]+$idx];		if( $csize == 1 ) {		    // A "meta" cluster with only one slice		    $r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)];		    $rr = $r+$img->GetFontHeight()/2;		    $xt=round($rr*cos($a)+$xc);		    $yt=round($yc-$rr*sin($a));		    $this->StrokeLabel($label,$img,$xc,$yc,$a,$r); 		    if( $this->iShowGuideLineForSingle ) 			$this->guideline->Stroke($img,$x,$y,$xt,$yt);		}		else {		    $this->guideline->Stroke($img,$x,$y,$xt,$yt);		    if( $q==1 || $q==2 ) {			// Left side of Pie			$this->guideline->Stroke($img,$xt,$yt,$xt-$this->guidelinemargin,$yt);			$lbladj = -$this->guidelinemargin-5;			$this->value->halign = "right";			$this->value->valign = "center";		    }		    else {			// Right side of pie			$this->guideline->Stroke($img,$xt,$yt,$xt+$this->guidelinemargin,$yt);			$lbladj = $this->guidelinemargin+5;			$this->value->halign = "left";			$this->value->valign = "center";		    }		    $this->value->Stroke($img,$label,$xt+$lbladj,$yt);		}		// Udate idx to point to next slice in the cluster to process		$idx += $step;	    }	}    }    function StrokeAllLabels($img,$xc,$yc,$radius) {	// First normalize all angles for labels	$n = count($this->la);	for($i=0; $i < $n; ++$i) {	    $this->la[$i] = $this->NormAngle($this->la[$i]);	}	if( $this->guideline->iShow ) {	    $this->StrokeGuideLabels($img,$xc,$yc,$radius);	}	else {	    $n = count($this->labels);	    for($i=0; $i < $n; ++$i) {		$this->StrokeLabel($this->labels[$i],$img,$xc,$yc,				   $this->la[$i],				   $radius + $this->explode_radius[$n-1-$i]); 	    }	}    }    // Position the labels of each slice    function StrokeLabel($label,$img,$xc,$yc,$a,$r) {	// Default value	if( $this->ilabelposadj === 'auto' )	    $this->ilabelposadj = 0.65;	// We position the values diferently depending on if they are inside	// or outside the pie	if( $this->ilabelposadj < 1.0 ) {	    $this->value->SetAlign('center','center');	    $this->value->margin = 0;	    	    $xt=round($this->ilabelposadj*$r*cos($a)+$xc);	    $yt=round($yc-$this->ilabelposadj*$r*sin($a));	    	    $this->value->Stroke($img,$label,$xt,$yt);	}	else {	    $this->value->halign = "left";	    $this->value->valign = "top";	    $this->value->margin = 0;	    	    	    // Position the axis title. 	    // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text	    // that intersects with the extension of the corresponding axis. The code looks a little	    // bit messy but this is really the only way of having a reasonable position of the	    // axis titles.	    $this->value->ApplyFont($img);	    $h=$img->GetTextHeight($label);	    // For numeric values the format of the display value	    // must be taken into account	    if( is_numeric($label) ) {		if( $label > 0 )		    $w=$img->GetTextWidth(sprintf($this->value->format,$label));		else		    $w=$img->GetTextWidth(sprintf($this->value->negformat,$label));	    }	    else		$w=$img->GetTextWidth($label);	    if( $this->ilabelposadj > 1.0 && $this->ilabelposadj < 5.0) {		$r *= $this->ilabelposadj;	    }	    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -