<?php
/*=======================================================================
// File:	JPGRAPH_PIE.PHP
// Description:	Pie plot extension for JpGraph
// Created: 	2001-02-14
// Author:	Johan Persson (johanp@aditus.nu)
// Ver:		$Id$
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/


// Defines for PiePlot::SetLabelType()
DEFINE("PIE_VALUE_ABS",1);
DEFINE("PIE_VALUE_PER",0);
DEFINE("PIE_VALUE_PERCENTAGE",0);
DEFINE("PIE_VALUE_ADJPERCENTAGE",2);
DEFINE("PIE_VALUE_ADJPER",2);

//===================================================
// CLASS PiePlot
// Description: Draws a pie plot
//===================================================
class PiePlot {
    var $posx=0.5,$posy=0.5;
    var $radius=0.3;
    var $explode_radius=array(),$explode_all=false,$explode_r=20;
    var $labels=null, $legends=null;
    var $csimtargets=null;  // Array of targets for CSIM
    var $csimareas='';		// Generated CSIM text	
    var $csimalts=null;		// ALT tags for corresponding target
    var $data=null;
    var $title;
    var $startangle=0;
    var $weight=1, $color="black";
    var $legend_margin=6,$show_labels=true;
    var $themearr = array(
	"earth" 	=> array(136,34,40,45,46,62,63,134,74,10,120,136,141,168,180,77,209,218,346,395,89,430),
	"pastel" => array(27,415,128,59,66,79,105,110,42,147,152,230,236,240,331,337,405,38),
	"water"  => array(8,370,24,40,335,56,213,237,268,14,326,387,10,388),
	"sand"   => array(27,168,34,170,19,50,65,72,131,209,46,393));
    var $theme="earth";
    var $setslicecolors=array();
    var $labeltype=0; // Default to percentage
    var $pie_border=true,$pie_interior_border=true;
    var $value;
    var $ishadowcolor='',$ishadowdrop=4;
    var $ilabelposadj=1;
    var $legendcsimtargets = array();
    var $legendcsimalts = array();
    var $adjusted_data = array();
    var $guideline = null,$guidelinemargin=10;
    var $iShowGuideLineForSingle = false;
    var $iGuideLineCurve = false,$iGuideVFactor=1.4,$iGuideLineRFactor=0.8;
//---------------
// CONSTRUCTOR
    function PiePlot($data) {
	$this->data = array_reverse($data);
	$this->title = new Text("");
	$this->title->SetFont(FF_FONT1,FS_BOLD);
	$this->value = new DisplayValue();
	$this->value->Show();
	$this->value->SetFormat('%.1f%%');
	$this->guideline = new LineProperty();
    }

//---------------
// PUBLIC METHODS	
    function SetCenter($x,$y=0.5) {
	$this->posx = $x;
	$this->posy = $y;
    }

    // Enable guideline and set drwaing policy
    function SetGuideLines($aFlg=true,$aCurved=true,$aAlways=false) {
	$this->guideline->Show($aFlg);
	$this->iShowGuideLineForSingle = $aAlways;
	$this->iGuideLineCurve = $aCurved;
    }

    // Adjuste the distance between labels and labels and pie
    function SetGuideLinesAdjust($aVFactor,$aRFactor=0.8) {
	$this->iGuideVFactor=$aVFactor;
	$this->iGuideLineRFactor=$aRFactor;
    }

    function SetColor($aColor) {
	$this->color = $aColor;
    }
	
    function SetSliceColors($aColors) {
	$this->setslicecolors = $aColors;
    }
	
    function SetShadow($aColor='darkgray',$aDropWidth=4) {
	$this->ishadowcolor = $aColor;
	$this->ishadowdrop = $aDropWidth;
    }

    function SetCSIMTargets($targets,$alts=null) {
	$this->csimtargets=array_reverse($targets);
	if( is_array($alts) )
	    $this->csimalts=array_reverse($alts);
    }
	
    function GetCSIMareas() {
	return $this->csimareas;
    }

    function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) {  

        //Slice number, ellipse centre (x,y), height, width, start angle, end angle
	while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI;
	while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI;

	$sa = 2*M_PI - $sa;
	$ea = 2*M_PI - $ea;

	// Special case when we have only one slice since then both start and end
	// angle will be == 0
	if( abs($sa - $ea) < 0.0001 ) {
	    $sa=2*M_PI; $ea=0;
	}

	//add coordinates of the centre to the map
	$xc = floor($xc);$yc=floor($yc);
	$coords = "$xc, $yc";

	//add coordinates of the first point on the arc to the map
	$xp = floor(($radius*cos($ea))+$xc);
	$yp = floor($yc-$radius*sin($ea));
	$coords.= ", $xp, $yp";
	//add coordinates every 0.2 radians
	$a=$ea+0.2;

	// If we cross the 260-limit with a slice we need to handle
	// the fact that end angle is smaller than start
	if( $sa < $ea ) {
	    while ($a <= 2*M_PI) {
		$xp = floor($radius*cos($a)+$xc);
		$yp = floor($yc-$radius*sin($a));
		$coords.= ", $xp, $yp";
		$a += 0.2;
	    }
	    $a -= 2*M_PI;
	}

	while ($a < $sa) {
	    $xp = floor($radius*cos($a)+$xc);
	    $yp = floor($yc-$radius*sin($a));
	    $coords.= ", $xp, $yp";
	    $a += 0.2;
	}
		
	//Add the last point on the arc
	$xp = floor($radius*cos($sa)+$xc);
	$yp = floor($yc-$radius*sin($sa));
	$coords.= ", $xp, $yp";
	if( !empty($this->csimtargets[$i]) ) {
	    $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\"";
	    $tmp="";
	    if( !empty($this->csimalts[$i]) ) {
		$tmp=sprintf($this->csimalts[$i],$this->data[$i]);
		$this->csimareas .= " title=\"$tmp\"";
	    }
	    $this->csimareas .= " alt=\"$tmp\" />\n";
	}
    }

	
    function SetTheme($aTheme) {
	if( in_array($aTheme,array_keys($this->themearr)) )
	    $this->theme = $aTheme;
	else
	    JpGraphError::RaiseL(15001,$aTheme);//("PiePLot::SetTheme() Unknown theme: $aTheme");
    }
	
    function ExplodeSlice($e,$radius=20) {
	if( ! is_integer($e) ) 
	    JpGraphError::RaiseL(15002);//('Argument to PiePlot::ExplodeSlice() must be an integer');
	$this->explode_radius[$e]=$radius;
    }

    function ExplodeAll($radius=20) {
	$this->explode_all=true;
	$this->explode_r = $radius;
    }

    function Explode($aExplodeArr) {
	if( !is_array($aExplodeArr) ) {
	    JpGraphError::RaiseL(15003);
//("Argument to PiePlot::Explode() must be an array with integer distances.");
	}
	$this->explode_radius = $aExplodeArr;
    }

    function SetStartAngle($aStart) {
	if( $aStart < 0 || $aStart > 360 ) {
	    JpGraphError::RaiseL(15004);//('Slice start angle must be between 0 and 360 degrees.');
	}
	$this->startangle = 360-$aStart;
	$this->startangle *= M_PI/180;
    }
	
    function SetFont($family,$style=FS_NORMAL,$size=10) {
	JpGraphError::RaiseL(15005);//('PiePlot::SetFont() is deprecated. Use PiePlot->value->SetFont() instead.');
    }
	
    // Size in percentage
    function SetSize($aSize) {
	if( ($aSize>0 && $aSize<=0.5) || ($aSize>10 && $aSize<1000) )
	    $this->radius = $aSize;
	else
	    JpGraphError::RaiseL(15006);
//("PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels  in the range [10, 1000]");
    }
	
    function SetFontColor($aColor) {
	JpGraphError::RaiseL(15007);
//('PiePlot::SetFontColor() is deprecated. Use PiePlot->value->SetColor() instead.');
    }
	
    // Set label arrays
    function SetLegends($aLegend) {
	$this->legends = $aLegend;
    }

    // Set text labels for slices 
    function SetLabels($aLabels,$aLblPosAdj="auto") {
	$this->labels = array_reverse($aLabels);
	$this->ilabelposadj=$aLblPosAdj;
    }

    function SetLabelPos($aLblPosAdj) {
	$this->ilabelposadj=$aLblPosAdj;
    }
	
    // Should we display actual value or percentage?
    function SetLabelType($t) {
	if( $t < 0 || $t > 2 ) 
	    JpGraphError::RaiseL(15008,$t);
//("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t).");
	$this->labeltype=$t;
    }

    // Deprecated. 
    function SetValueType($aType) {
	$this->SetLabelType($aType);
    }

    // Should the circle around a pie plot be displayed
    function ShowBorder($exterior=true,$interior=true) {
	$this->pie_border = $exterior;
	$this->pie_interior_border = $interior;
    }
	
    // Setup the legends (Framework method)
    function Legend(&$graph) {
	$colors = array_keys($graph->img->rgb->rgb_table);
   	sort($colors);	
   	$ta=$this->themearr[$this->theme];	
   	$n = count($this->data);

   	if( $this->setslicecolors==null ) {
	    $numcolors=count($ta);
	    if( is_a($this,'PiePlot3D') ) {
		$ta = array_reverse(array_slice($ta,0,$n));
	    }
	}
   	else {
	    $this->setslicecolors = array_slice($this->setslicecolors,0,$n);
	    $numcolors=count($this->setslicecolors); 
	    if( $graph->pieaa && is_a($this,'PiePlot') ) { 
		$this->setslicecolors = array_reverse($this->setslicecolors);
	    }
	}
		
	$sum=0;
	for($i=0; $i < $n; ++$i)
	    $sum += $this->data[$i];

	// Bail out with error if the sum is 0
	if( $sum==0 )
	    JpGraphError::RaiseL(15009);//("Illegal pie plot. Sum of all data is zero for Pie!");

	// Make sure we don't plot more values than data points
	// (in case the user added more legends than data points)
	$n = min(count($this->legends),count($this->data));
	if( $this->legends != "" ) {
	    $this->legends = array_reverse(array_slice($this->legends,0,$n));
	}
	for( $i=$n-1; $i >= 0; --$i ) {
	    $l = $this->legends[$i];
	    // Replace possible format with actual values
	    if( count($this->csimalts) > $i ) {
		$fmt = $this->csimalts[$i];
	    }
	    else {
		$fmt = "%d"; // Deafult Alt if no other has been specified
	    }
	    if( $this->labeltype==0 ) {
		$l = sprintf($l,100*$this->data[$i]/$sum);
		$alt = sprintf($fmt,$this->data[$i]);
		
	    }
	    elseif( $this->labeltype == 1)  {
		$l = sprintf($l,$this->data[$i]);
		$alt = sprintf($fmt,$this->data[$i]);
		
	    }
	    else {
		$l = sprintf($l,$this->adjusted_data[$i]);
		$alt = sprintf($fmt,$this->adjusted_data[$i]);
	    }

	    if( $this->setslicecolors==null ) {
		$graph->legend->Add($l,$colors[$ta[$i%$numcolors]],"",0,$this->csimtargets[$i],$alt);
	    }
	    else {
		$graph->legend->Add($l,$this->setslicecolors[$i%$numcolors],"",0,$this->csimtargets[$i],$alt);
	    }
	}
    }
	
    // Adjust the rounded percetage value so that the sum of
    // of the pie slices are always 100%
    // Using the Hare/Niemeyer method
    function AdjPercentage($aData,$aPrec=0) {
	$mul=100;
	if( $aPrec > 0 && $aPrec < 3 ) {
	    if( $aPrec == 1 ) 
		$mul=1000;
		else
		    $mul=10000;
	}
	
	$tmp = array();
	$result = array();
	$quote_sum=0;
	$n = count($aData) ;
	for( $i=0, $sum=0; $i < $n; ++$i )
	    $sum+=$aData[$i];
	foreach($aData as $index => $value) {
	    $tmp_percentage=$value/$sum*$mul;
	    $result[$index]=floor($tmp_percentage);
	    $tmp[$index]=$tmp_percentage-$result[$index];
	    $quote_sum+=$result[$index];
	}
	if( $quote_sum == $mul) {
	    if( $mul > 100 ) {
		$tmp = $mul / 100;
		for( $i=0; $i < $n; ++$i ) {
		    $result[$i] /= $tmp ;
		}
	    }
	    return $result;
	}
	arsort($tmp,SORT_NUMERIC);
	reset($tmp);
	for($i=0; $i < $mul-$quote_sum; $i++)
	{
	    $result[key($tmp)]++;
	    next($tmp);
	}
	if( $mul > 100 ) {
	    $tmp = $mul / 100;
	    for( $i=0; $i < $n; ++$i ) {
		$result[$i] /= $tmp ;
	    }
	}
	return $result;
    }


    function Stroke(&$img,$aaoption=0) {
	// aaoption is used to handle antialias
	// aaoption == 0 a normal pie
	// aaoption == 1 just the body
	// aaoption == 2 just the values

	// Explode scaling. If anti anti alias we scale the image
	// twice and we also need to scale the exploding distance
	$expscale = $aaoption === 1 ? 2 : 1;

	if( $this->labeltype == 2 ) {
	    // Adjust the data so that it will add up to 100%
	    $this->adjusted_data = $this->AdjPercentage($this->data);
	}

	$colors = array_keys($img->rgb->rgb_table);
   	sort($colors);	
   	$ta=$this->themearr[$this->theme];	
	$n = count($this->data);
   	
   	if( $this->setslicecolors==null ) {
	    $numcolors=count($ta);
	}
   	else {
	    $this->setslicecolors = array_reverse(array_slice($this->setslicecolors,0,$n));
	    $numcolors=count($this->setslicecolors); 
	    $tt = array_slice($this->setslicecolors,$n % $numcolors);
	    $tt2 = array_slice($this->setslicecolors,0,$n % $numcolors);
	    $tt2 = array_merge($tt, $tt2);
	    $this->setslicecolors = $tt + $tt2;
	}

	// Draw the slices
	$sum=0;
	for($i=0; $i < $n; ++$i)
	    $sum += $this->data[$i];
	
	// Bail out with error if the sum is 0
	if( $sum==0 )
	    JpGraphError::RaiseL(15009);//("Sum of all data is 0 for Pie.");
	
	// Set up the pie-circle
	if( $this->radius <= 1 )
	    $radius = floor($this->radius*min($img->width,$img->height));
	else {
	    $radius = $aaoption === 1 ? $this->radius*2 : $this->radius;
	}

	if( $this->posx <= 1 && $this->posx > 0 )
	    $xc = round($this->posx*$img->width);
	else
	    $xc = $this->posx ;
	
	if( $this->posy <= 1 && $this->posy > 0 )
	    $yc = round($this->posy*$img->height);
	else
	    $yc = $this->posy ;
		
	$n = count($this->data);

	if( $this->explode_all )
	    for($i=0; $i < $n; ++$i)
		$this->explode_radius[$i]=$this->explode_r;

	if( $this->ishadowcolor != "" && $aaoption !== 2) {
	    $accsum=0;
	    $angle2 = $this->startangle;
	    $img->SetColor($this->ishadowcolor);
	    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->Pos($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.
	$img->SetFont($this->value->ff,$this->value->fs,$this->value->fsize);
	$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,$radius) {

	// Default value
	if( $this->ilabelposadj === 'auto' )
	    $this->ilabelposadj = 0.65;
	$r = $radius;

	// 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.
	    $img->SetFont($this->value->ff,$this->value->fs,$this->value->fsize);
	    $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;
	    }
	    
	    $r += $img->GetFontHeight()/1.5;

	    $xt=round($r*cos($a)+$xc);
	    $yt=round($yc-$r*sin($a));

	    // Normalize angle
	    while( $a < 0 ) $a += 2*M_PI;
	    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;
	    
	    $this->value->Stroke($img,$label,$xt-$dx*$w,$yt-$dy*$h);
	}
    }	
} // Class


//===================================================
// CLASS PiePlotC
// Description: Same as a normal pie plot but with a 
// filled circle in the center
//===================================================
class PiePlotC extends PiePlot {
    var $imidsize=0.5;		// Fraction of total width
    var $imidcolor='white';
    var $midtitle='';
    var $middlecsimtarget="",$middlecsimalt="";

    function PiePlotC($data,$aCenterTitle='') {
	parent::PiePlot($data);
	$this->midtitle = new Text();
	$this->midtitle->ParagraphAlign('center');
    }

    function SetMid($aTitle,$aColor='white',$aSize=0.5) {
	$this->midtitle->Set($aTitle);

	$this->imidsize = $aSize ; 
	$this->imidcolor = $aColor ; 
    }

    function SetMidTitle($aTitle) {
	$this->midtitle->Set($aTitle);
    }

    function SetMidSize($aSize) {
	$this->imidsize = $aSize ; 
    }

    function SetMidColor($aColor) {
	$this->imidcolor = $aColor ; 
    }

    function SetMidCSIM($aTarget,$aAlt) {
	$this->middlecsimtarget = $aTarget;
	$this->middlecsimalt = $aAlt;
    }

    function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) {  

        //Slice number, ellipse centre (x,y), radius, start angle, end angle
	while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI;
	while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI;

	$sa = 2*M_PI - $sa;
	$ea = 2*M_PI - $ea;

	// Special case when we have only one slice since then both start and end
	// angle will be == 0
	if( abs($sa - $ea) < 0.0001 ) {
	    $sa=2*M_PI; $ea=0;
	}

	// Add inner circle first point
	$xp = floor(($this->imidsize*$radius*cos($ea))+$xc);
	$yp = floor($yc-($this->imidsize*$radius*sin($ea)));
	$coords = "$xp, $yp";
	
	//add coordinates every 0.25 radians
	$a=$ea+0.25;

	// If we cross the 260-limit with a slice we need to handle
	// the fact that end angle is smaller than start
	if( $sa < $ea ) {
	    while ($a <= 2*M_PI) {
		$xp = floor($radius*cos($a)+$xc);
		$yp = floor($yc-$radius*sin($a));
		$coords.= ", $xp, $yp";
		$a += 0.25;
	    }
	    $a -= 2*M_PI;
	}

	while ($a < $sa) {
	    $xp = floor(($this->imidsize*$radius*cos($a)+$xc));
	    $yp = floor($yc-($this->imidsize*$radius*sin($a)));
	    $coords.= ", $xp, $yp";
	    $a += 0.25;
	}

	// Make sure we end at the last point
	$xp = floor(($this->imidsize*$radius*cos($sa)+$xc));
	$yp = floor($yc-($this->imidsize*$radius*sin($sa)));
	$coords.= ", $xp, $yp";

	// Straight line to outer circle
	$xp = floor($radius*cos($sa)+$xc);
	$yp = floor($yc-$radius*sin($sa));
	$coords.= ", $xp, $yp";	

	//add coordinates every 0.25 radians
	$a=$sa - 0.25;
	while ($a > $ea) {
	    $xp = floor($radius*cos($a)+$xc);
	    $yp = floor($yc-$radius*sin($a));
	    $coords.= ", $xp, $yp";
	    $a -= 0.25;
	}
		
	//Add the last point on the arc
	$xp = floor($radius*cos($ea)+$xc);
	$yp = floor($yc-$radius*sin($ea));
	$coords.= ", $xp, $yp";

	// Close the arc
	$xp = floor(($this->imidsize*$radius*cos($ea))+$xc);
	$yp = floor($yc-($this->imidsize*$radius*sin($ea)));
	$coords .= ", $xp, $yp";

	if( !empty($this->csimtargets[$i]) ) {
	    $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".
		$this->csimtargets[$i]."\"";
	    if( !empty($this->csimalts[$i]) ) {
		$tmp=sprintf($this->csimalts[$i],$this->data[$i]);
		$this->csimareas .= " title=\"$tmp\"";
	    }
	    $this->csimareas .= " alt=\"$tmp\" />\n";
	}
    }


    function Stroke(&$img,$aaoption=0) {

	// Stroke the pie but don't stroke values
	$tmp =  $this->value->show;
	$this->value->show = false;
	parent::Stroke($img,$aaoption);
	$this->value->show = $tmp;

 	$xc = round($this->posx*$img->width);
	$yc = round($this->posy*$img->height);

	$radius = floor($this->radius * min($img->width,$img->height)) ;


	if( $this->imidsize > 0 && $aaoption !== 2 ) {

	    if( $this->ishadowcolor != "" ) {
		$img->SetColor($this->ishadowcolor);
		$img->FilledCircle($xc+$this->ishadowdrop,$yc+$this->ishadowdrop,
				   round($radius*$this->imidsize));
	    }

	    $img->SetColor($this->imidcolor);
	    $img->FilledCircle($xc,$yc,round($radius*$this->imidsize));

	    if(  $this->pie_border && $aaoption === 0 ) {
		$img->SetColor($this->color);
		$img->Circle($xc,$yc,round($radius*$this->imidsize));
	    }

	    if( !empty($this->middlecsimtarget) )
		$this->AddMiddleCSIM($xc,$yc,round($radius*$this->imidsize));

	}

	if( $this->value->show && $aaoption !== 1) {
	    $this->StrokeAllLabels($img,$xc,$yc,$radius);
	    $this->midtitle->Pos($xc,$yc,'center','center');
	    $this->midtitle->Stroke($img);
	}

    }

    function AddMiddleCSIM($xc,$yc,$r) {
	$xc=round($xc);$yc=round($yc);$r=round($r);
	$this->csimareas .= "<area shape=\"circle\" coords=\"$xc,$yc,$r\" href=\"".
	    $this->middlecsimtarget."\"";
	if( !empty($this->middlecsimalt) ) {
	    $tmp = $this->middlecsimalt;
	    $this->csimareas .= " title=\"$tmp\"";
	}
	$this->csimareas .= " alt=\"$tmp\" />\n";
    }

    function StrokeLabel($label,$img,$xc,$yc,$a,$r) {

	if( $this->ilabelposadj === 'auto' )
	    $this->ilabelposadj = (1-$this->imidsize)/2+$this->imidsize;

	parent::StrokeLabel($label,$img,$xc,$yc,$a,$r);

    }

}


//===================================================
// CLASS PieGraph
// Description: 
//===================================================
class PieGraph extends Graph {
    var $posx, $posy, $radius;		
    var $legends=array();	
    var $plots=array();
    var $pieaa = false ;
//---------------
// CONSTRUCTOR
    function PieGraph($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) {
	$this->Graph($width,$height,$cachedName,$timeout,$inline);
	$this->posx=$width/2;
	$this->posy=$height/2;
	$this->SetColor(array(255,255,255));		
    }

//---------------
// PUBLIC METHODS	
    function Add($aObj) {

	if( is_array($aObj) && count($aObj) > 0 )
	    $cl = $aObj[0];
	else
	    $cl = $aObj;

	if( is_a($cl,'Text') ) 
	    $this->AddText($aObj);
	elseif( is_a($cl,'IconPlot') ) 
	    $this->AddIcon($aObj);
	else {
	    if( is_array($aObj) ) {
		$n = count($aObj);
		for($i=0; $i < $n; ++$i ) {
		    $this->plots[] = $aObj[$i];
		}
	    }
	    else {
		$this->plots[] = $aObj;
	    }
	}
    }

    function SetAntiAliasing($aFlg=true) {
	$this->pieaa = $aFlg;
    }
	
    function SetColor($c) {
	$this->SetMarginColor($c);
    }

    function DisplayCSIMAreas() {
	    $csim="";
	    foreach($this->plots as $p ) {
		$csim .= $p->GetCSIMareas();
	    }
	    //$csim.= $this->legend->GetCSIMareas();
	    if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) {
		$this->img->SetColor($this->csimcolor);
		$n = count($coords[0]);
		for ($i=0; $i < $n; $i++) {
		    if ($coords[1][$i]=="poly") {
			preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts);
			$this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]);
			$m = count($pts[0]);
			for ($j=0; $j < $m; $j++) {
			    $this->img->LineTo($pts[1][$j],$pts[2][$j]);
			}
		    } else if ($coords[1][$i]=="rect") {
			$pts = preg_split('/,/', $coords[2][$i]);
			$this->img->SetStartPoint($pts[0],$pts[1]);
			$this->img->LineTo($pts[2],$pts[1]);
			$this->img->LineTo($pts[2],$pts[3]);
			$this->img->LineTo($pts[0],$pts[3]);
			$this->img->LineTo($pts[0],$pts[1]);
						
		    }
		}
	    }
    }

    // Method description
    function Stroke($aStrokeFileName="") {
	// If the filename is the predefined value = '_csim_special_'
	// we assume that the call to stroke only needs to do enough
	// to correctly generate the CSIM maps.
	// We use this variable to skip things we don't strictly need
	// to do to generate the image map to improve performance
	// a best we can. Therefor you will see a lot of tests !$_csim in the
	// code below.
	$_csim = ($aStrokeFileName===_CSIM_SPECIALFILE);

	// We need to know if we have stroked the plot in the
	// GetCSIMareas. Otherwise the CSIM hasn't been generated
	// and in the case of GetCSIM called before stroke to generate
	// CSIM without storing an image to disk GetCSIM must call Stroke.
	$this->iHasStroked = true;
		
	$n = count($this->plots);

	if( $this->pieaa ) {

	    if( !$_csim ) {
		if( $this->background_image != "" ) {
		    $this->StrokeFrameBackground();		
		}
		else {
		    $this->StrokeFrame();
		}
	    }


	    $w = $this->img->width;
	    $h = $this->img->height;
	    $oldimg = $this->img->img;

	    $this->img->CreateImgCanvas(2*$w,2*$h);
	    
	    $this->img->SetColor( $this->margin_color );
	    $this->img->FilledRectangle(0,0,2*$w-1,2*$h-1);

	    // Make all icons *2 i size since we will be scaling down the
	    // image to do the anti aliasing
	    $ni = count($this->iIcons);
	    for($i=0; $i < $ni; ++$i) {
		$this->iIcons[$i]->iScale *= 2 ;
		if( $this->iIcons[$i]->iX > 1 ) 
		    $this->iIcons[$i]->iX *= 2 ;
		if( $this->iIcons[$i]->iY > 1 ) 
		    $this->iIcons[$i]->iY *= 2 ;
	    }

	    $this->StrokeIcons();

	    for($i=0; $i < $n; ++$i) {
		if( $this->plots[$i]->posx > 1 ) 
		    $this->plots[$i]->posx *= 2 ;
		if( $this->plots[$i]->posy > 1 ) 
		    $this->plots[$i]->posy *= 2 ;

		$this->plots[$i]->Stroke($this->img,1);

		if( $this->plots[$i]->posx > 1 ) 
		    $this->plots[$i]->posx /= 2 ;
		if( $this->plots[$i]->posy > 1 ) 
		    $this->plots[$i]->posy /= 2 ;
	    }
	    $indent = $this->doframe ? ($this->frame_weight + ($this->doshadow ? $this->shadow_width : 0 )) : 0 ;
	    $indent += $this->framebevel ? $this->framebeveldepth + 1 : 0 ;
	    $this->img->CopyCanvasH($oldimg,$this->img->img,$indent,$indent,$indent,$indent,
				    $w-2*$indent,$h-2*$indent,2*($w-$indent),2*($h-$indent));

	    $this->img->img = $oldimg ;
	    $this->img->width = $w ;
	    $this->img->height = $h ;

	    for($i=0; $i < $n; ++$i) {
		$this->plots[$i]->Stroke($this->img,2); // Stroke labels
		$this->plots[$i]->Legend($this);
	    }

	}
	else {
	    // No antialias
	    if( !$_csim ) {
		if( $this->background_image != "" ) {
		    $this->StrokeFrameBackground();		
		}
		else {
		    $this->StrokeFrame();
		    $this->StrokeBackgroundGrad();
		}
	    }

	    $this->StrokeIcons();
	    for($i=0; $i < $n; ++$i) {
		$this->plots[$i]->Stroke($this->img);
		$this->plots[$i]->Legend($this);
	    }
	}

	$this->legend->Stroke($this->img);
	$this->footer->Stroke($this->img);
	$this->StrokeTitles();

	if( !$_csim ) {	

	    // Stroke texts
	    if( $this->texts != null ) {
		$n = count($this->texts);
		for($i=0; $i < $n; ++$i ) {
		    $this->texts[$i]->Stroke($this->img);
		}
	    }

	    if( _JPG_DEBUG ) {
		$this->DisplayCSIMAreas();
	    }

	    // Should we do any final image transformation
	    if( $this->iImgTrans ) {
		if( !class_exists('ImgTrans') ) {
		    require_once('jpgraph_imgtrans.php');
		    //JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.');
		}
	       
		$tform = new ImgTrans($this->img->img);
		$this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist,
						 $this->iImgTransDirection,$this->iImgTransHighQ,
						 $this->iImgTransMinSize,$this->iImgTransFillColor,
						 $this->iImgTransBorder);
	    }


	    // If the filename is given as the special "__handle"
	    // then the image handler is returned and the image is NOT
	    // streamed back
	    if( $aStrokeFileName == _IMG_HANDLER ) {
		return $this->img->img;
	    }
	    else {
		// Finally stream the generated picture					
		$this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,
					   $aStrokeFileName);		
	    }
	}
    }
} // Class

/* EOF */
?>
