data = $data;
$this->title = new Text("");
$this->title->SetFont(FF_FONT1,FS_BOLD);
}
//---------------
// PUBLIC METHODS
// Specify projection angle for 3D in degrees
// Must be between 20 and 70 degrees
function SetAngle($a) {
if( $a<30 || $a>70 )
JpGraphError::Raise("JpGraph: 3D Pie projection angle must be between 30 and 70 degrees.");
else
$this->angle = $a;
}
function AddSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle
//add coordinates of the centre to the map
$coords = "$xc, $yc";
//add coordinates of the first point on the arc to the map
$xp = floor($width*cos($sa)/2+$xc);
$yp = floor($yc-$height*sin($sa)/2);
$coords.= ", $xp, $yp";
//If on the front half, add the thickness offset
if ($sa >= M_PI && $sa <= 2*M_PI*1.01) {
$yp = floor($yp+($thick*$width));
$coords.= ", $xp, $yp";
}
//add coordinates every 0.2 radians
$a=$sa+0.2;
while ($a<$ea) {
$xp = floor($width*cos($a)/2+$xc);
if ($a >= M_PI && $a <= 2*M_PI*1.01) {
$yp = floor($yc-($height*sin($a)/2)+$thick*$width);
} else {
$yp = floor($yc-$height*sin($a)/2);
}
$coords.= ", $xp, $yp";
$a += 0.2;
}
//Add the last point on the arc
$xp = floor($width*cos($ea)/2+$xc);
$yp = floor($yc-$height*sin($ea)/2);
//If on the front half, add the thickness offset
if ($ea >= M_PI && $ea <= 2*M_PI*1.01) {
$coords.= ", $xp, ".floor($yp+($thick*$width));
}
$coords.= ", $xp, $yp";
if( !empty($this->csimalts[$i]) ) {
$tmp=sprintf($this->csimalts[$i],$this->data[$i]);
$alt="alt=\"$tmp\"";
}
if( !empty($this->csimtargets[$i]) )
$this->csimareas .= "csimtargets[$i]."\" $alt>\r\n";
}
function ExplodeSlice($e) {
JpGraphError::Raise("JpGraph Error: Exploding slices are not (yet) implemented for 3d pies graphs.");
//$this->explode_slice=$e;
}
// Distance from the pie to the labels
function SetLabelMargin($m) {
assert($m>0 && $m<1);
$this->labelmargin=$m;
}
// Show a thin line from the pie to the label for a specific slice
function ShowLabelHint($f=true) {
$this->showlabelhint=$f;
}
// Set color of hint line to label for each slice
function SetLabelHintColor($c) {
$this->labelhintcolor=$c;
}
function Stroke(&$img) {
$colors = array_keys($img->rgb->rgb_table);
sort($colors);
$ta=$this->themearr[$this->theme];
if( $this->setslicecolors==null )
$numcolors=count($ta);
else
$numcolors=count($this->setslicecolors);
// Draw the slices
$sum=0;
foreach($this->data as $d)
$sum += $d;
// Format the titles for each slice
for( $i=0; $idata); ++$i) {
if( $this->labeltype==0 )
if( $sum != 0 )
$l = round(100*$this->data[$i]/$sum,$this->precision);
else
$l=0;
else
$l = $this->data[$i];
$l = sprintf($this->labelformat,$l);
if( $this->show_psign ) $l .= "%";
$this->labels[$i]=$l;
}
// Set up the pie-circle with some heuristic constants
$thick=0.16-($this->angle-20)/60*0.07;
$width = floor(2.0*$this->radius*min($img->width,$img->height));
$height = ($this->angle/90.0)*$width;
$xc = $this->posx*$img->width;
$yc = $this->posy*$img->height;
$img->SetColor($this->color);
$img->Ellipse($xc,$yc,$width,$height);
$img->Arc($xc,$yc+$width*$thick,$width,$height,0,180);
$img->Line($xc+$width/2,$yc,$xc+$width/2,$yc+$width*$thick);
$img->Line($xc-$width/2,$yc,$xc-$width/2,$yc+$width*$thick);
$fillPerimeter[0] = array('x' => round((($xc - ($width / 2)) + 1)),
'y' => round(($yc + ($width * $thick) / 2)));
// Draw the first slice first line
$img->SetColor($this->color);
$img->SetLineWeight($this->weight);
$a = $this->startangle;
$xp = $width*cos($a)/2+$xc;
$yp = $yc-$height*sin($a)/2;
$img->Line($xc,$yc,$xp,$yp);
for($i=0; $sum>0 && $idata); $i++) {
$img->SetColor($this->color);
$d = $this->data[$i];
$la = $a + M_PI*$d/$sum;
$old_a = $a;
$a += 2*M_PI*$d/$sum;
if ($this->csimtargets[$i]) {
$this->AddSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$old_a,$a);
}
$xp = $width*cos($a)/2+$xc;
$yp = $yc-$height*sin($a)/2;
if( $idata)-1)
$img->Line($xc,$yc,$xp,$yp);
if( $a > M_PI && $a < 0.999*2*M_PI )
$img->Line($xp,$yp,$xp,$yp+$width*$thick-1);
if($a < M_PI) {
$fillPerimeter[$i + 1] = $fillPerimeter[$i];
} else {
$fillPerimeter[$i + 1] = array('x' => round(($xp + 1)),
'y' => round(($yp + ($width * $thick) / 2)));
}
if( $this->setslicecolors==null )
$slicecolor=$colors[$ta[$i%$numcolors]];
else
$slicecolor=$this->setslicecolors[$i%$numcolors];
if( $this->show_labels ) {
$margin = 1 + $this->labelmargin;
$xp = $width*cos($la)/2*$margin;
$yp = $height*sin($la)/2*$margin;
if( ($la >= 0 && $la <= M_PI) || $la>2*M_PI*0.98 ) {
$this->StrokeLabels($this->labels[$i],$img,$la,$xc+$xp,$yc-$yp);
if( $this->showlabelhint ) {
$img->SetColor($this->labelhintcolor);
$img->Line($xc+$xp/$margin,$yc-$yp/$margin,$xc+$xp,$yc-$yp);
}
}
else {
$this->StrokeLabels($this->labels[$i],$img,$la,$xc+$xp,$yc-$yp+$width*$thick);
if( $this->showlabelhint ) {
$img->SetColor($this->labelhintcolor);
$img->Line($xc+$xp/$margin,$yc-$yp/$margin+$width*$thick,$xc+$xp,$yc-$yp+$width*$thick);
}
}
$img->SetColor($slicecolor);
$xp = $width*cos($la)/3+$xc;
$yp = $yc-$height*sin($la)/3;
$img->Fill(round($xp), round($yp));
// Make the edge color 35% darker
$img->SetColor($slicecolor.":0.65");
if($fillPerimeter[$i]['x'] <= $xc + ($width / 2)) {
$img->Fill($fillPerimeter[$i]['x'],$fillPerimeter[$i]['y']);
}
}
}
// Adjust title position
$this->title->Pos($xc,$yc-$img->GetFontHeight()-$this->radius,"center","bottom");
$this->title->Stroke($img);
// Draw the pie ellipse one more time since the filling might have
// written partly on the lines due to the filling in the edges.
$img->SetColor($this->color);
$img->Ellipse($xc,$yc,$width,$height);
$img->Arc($xc,$yc+$width*$thick,$width,$height,0,180);
// Draw the first slice first line
$a = $this->startangle;
$xp = $width*cos($a)/2+$xc;
$yp = $yc-$height*sin($a)/2;
$img->Line($xc,$yc,$xp,$yp);
// Draw the rest of the slice lines
for($i=0, $a=0; $sum>0 && $idata); $i++) {
$d = $this->data[$i];
$la = $a + M_PI*$d/$sum;
$old_a = $a;
$a += 2*M_PI*$d/$sum;
$xp = $width*cos($a)/2+$xc;
$yp = $yc-$height*sin($a)/2;
if( $a > M_PI && $a < 0.999*2*M_PI )
$img->Line($xp,$yp,$xp,$yp+$width*$thick-1);
if( $idata)-1)
$img->Line($xc,$yc,$xp,$yp);
}
$img->Line($xc+$width/2,$yc,$xc+$width/2,$yc+$width*$thick);
$img->Line($xc-$width/2,$yc,$xc-$width/2,$yc+$width*$thick);
}
//---------------
// PRIVATE METHODS
// Position the labels of each slice
function StrokeLabels($label,$img,$a,$xp,$yp) {
$img->SetFont($this->font_family,$this->font_style,$this->font_size);
$img->SetColor($this->font_color);
$img->SetTextAlign("left","top");
$marg=6;
// 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.
$h=$img->GetTextHeight($label);
$w=$img->GetTextWidth($label);
while( $a > 2*M_PI ) $a -= 2*M_PI;
if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0;
if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI;
if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1;
if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI);
if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI;
if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI);
if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1;
if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI);
if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0;
$img->StrokeText($xp-$dx*$w,$yp-$dy*$h,$label);
}
} // Class
/* EOF */
?>