source: contrib/ProjectManager/inc/jpgraph-1.5.2/src/jpgraph_pie.php @ 3594

Revision 3594, 12.5 KB checked in by afernandes, 13 years ago (diff)

Ticket #1416 - Disponibilizado o módulo ProjectManager? para a comunidade

  • Property svn:executable set to *
Line 
1<?php
2/*=======================================================================
3// File:        JPGRAPH_PIE.PHP
4// Description: Pie plot extension for JpGraph
5// Created:     2001-02-14
6// Author:      Johan Persson (johanp@aditus.nu)
7// Ver:         $Id: jpgraph_pie.php 18250 2005-05-07 14:13:43Z ralfbecker $
8//
9// License:     This code is released under GPL 2.0
10// Copyright (C) 2001 Johan Persson
11//========================================================================
12*/
13
14//===================================================
15// CLASS PiePlot
16// Description:
17//===================================================
18class PiePlot {
19    var $posx=0.5,$posy=0.5;
20    var $radius=0.3;
21    var $explode_radius=array(),$explode_all=false,$explode_r=20;
22    var $labels, $legends=null;
23    var $csimtargets=null;  // Array of targets for CSIM
24    var $csimareas='';          // Generated CSIM text 
25    var $csimalts=null;         // ALT tags for corresponding target
26    var $data=null;
27    var $title;
28    var $startangle=0;
29    var $weight=1, $color="black";
30    var $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=12,$font_color="black";
31    var $legend_margin=6,$show_labels=true;
32    var $precision=1,$show_psign=true;
33    var $themearr=array(
34        "earth"         => array(10,34,40,45,46,62,63,134,74,77,120,136,141,168,180,209,218,346,395,89,430),
35        "pastel" => array(27,38,42,58,66,79,105,110,128,147,152,230,236,240,331,337,405,415),
36        "water"  => array(8,370,10,40,335,56,213,237,268,14,326,387,24,388),
37        "sand"   => array(27,168,34,170,19,50,65,72,131,209,46,393));
38    var $theme="earth";
39    var $setslicecolors=array();
40    var $labelformat="%01.0f"; // Default format for labels
41    var $labeltype=0; // Default to percentage
42    var $pie_border=true,$pie_interior_border=true;
43       
44//---------------
45// CONSTRUCTOR
46    function PiePlot(&$data) {
47        $this->data = $data;
48        $this->title = new Text("");
49        $this->title->SetFont(FF_FONT1,FS_BOLD);
50    }
51
52//---------------
53// PUBLIC METHODS       
54    function SetCenter($x,$y=0.5) {
55        $this->posx = $x;
56        $this->posy = $y;
57    }
58
59    function SetCSIMTargets(&$targets,$alts=null) {
60        $this->csimtargets=$targets;
61        $this->csimalts=$alts;
62    }
63       
64    function GetCSIMareas() {
65        return $this->csimareas;
66    }
67
68    function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) {  //Slice number, ellipse centre (x,y), height, width, start angle, end angle
69               
70        //add coordinates of the centre to the map
71        $coords = "$xc, $yc";
72
73        //add coordinates of the first point on the arc to the map
74        $xp = floor(($radius*cos($sa))+$xc);
75        $yp = floor($yc-$radius*sin($sa));
76        $coords.= ", $xp, $yp";
77               
78        //add coordinates every 0.2 radians
79        $a=$sa+0.2;
80        while ($a<$ea) {
81            $xp = floor($radius*cos($a)+$xc);
82            $yp = floor($yc-$radius*sin($a));
83            $coords.= ", $xp, $yp";
84            $a += 0.2;
85        }
86               
87        //Add the last point on the arc
88        $xp = floor($radius*cos($ea)+$xc);
89        $yp = floor($yc-$radius*sin($ea));
90        $coords.= ", $xp, $yp";
91        if( !empty($this->csimtargets[$i]) )
92            $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\"";
93        if( !empty($this->csimalts[$i]) ) {                                                                             
94            $tmp=sprintf($this->csimalts[$i],$this->data[$i]);
95            $this->csimareas .= " alt=\"$tmp\"";
96        }
97        $this->csimareas .= ">\r\n";
98    }
99
100       
101    function SetTheme($t) {
102        if( in_array($t,array_keys($this->themearr)) )
103            $this->theme = $t;
104        else
105            JpGraphError::Raise("JpGraph Error: Unknown theme: $t");
106    }
107       
108    function ExplodeSlice($e) {
109        $this->explode_radius[$e]=20;
110    }
111
112    function ExplodeAll($radius=-1) {
113        $this->explode_all=true;
114        if( $radius==-1 )
115            $this->explode_r = 20;
116        else
117            $this->explode_r = $radius;
118    }
119
120    function Explode($radarr) {
121        $this->explode_radius = $radarr;
122    }
123       
124    function SetSliceColors($c) {
125        $this->setslicecolors = $c;
126    }
127       
128    function SetStartAngle($a) {
129        assert($a>=0 && $a<2*M_PI);
130        $this->startangle = $a;
131    }
132       
133    function SetFont($family,$style=FS_NORMAL,$size=10) {
134        $this->font_family=$family;
135        $this->font_style=$style;
136        $this->font_size=$size;
137    }
138       
139    // Size in percentage
140    function SetSize($size) {
141        if( ($size>0 && $size<=0.5) || ($size>10 && $size<1000) )
142            $this->radius = $size;
143        else
144            JpGraphError::Raise("JpGraph Error: Size (radius) for pie must either be specified as a fraction
145                                [0, 0.5] of the size of the image or as an absolute size in pixels
146                                in the range [10, 1000]");
147    }
148       
149    function SetFontColor($color) {
150        $this->font_color = $color;
151    }
152       
153    // Set label arrays
154    function SetLegends($l) {
155        $this->legends = $l;
156    }
157       
158    // Should the values be displayed?
159    function HideLabels($f=true) {
160        $this->show_labels = !$f;
161    }
162       
163    // Specify label format as a "C" printf string
164    function SetLabelFormat($f) {
165        $this->labelformat=$f;
166        // If format is specified don't add any %-sign
167        $this->show_psign=0;
168    }
169       
170    // Should we display actual value or percentage?
171    function SetLabelType($t) {
172        if( $t<0 || $t>1 )
173            JpGraphError::Raise("JpGraph Error: Label type for pie plots must be 0 or 1 (not $t).");
174        $this->labeltype=$t;
175        // Don't show percentage value when displaying absolute values
176        if( $t==1 )
177            $this->show_psign=0;
178    }
179
180    // Should the circle around a pie plot be displayed
181    function ShowBorder($exterior=true,$interior=true) {
182        $this->pie_border = $exterior;
183        $this->pie_interior_border = $interior;
184    }
185       
186    // Setup the legends
187    function Legend(&$graph) {
188        $colors = array_keys($graph->img->rgb->rgb_table);
189        sort($colors); 
190        $ta=$this->themearr[$this->theme];     
191       
192        if( $this->setslicecolors==null )
193            $numcolors=count($ta);
194        else
195            $numcolors=count($this->setslicecolors);
196               
197        $sum=0;
198        for($i=0; $i<count($this->data); ++$i)
199            $sum += $this->data[$i];
200                               
201        $i=0;
202        if( count($this->legends)>0 ) {
203            foreach( $this->legends as $l ) {
204                               
205                                // Replace possible format with actual values
206                if( $this->labeltype==0 )
207                    $l = sprintf($l,100*$this->data[$i]/$sum);
208                else
209                    $l = sprintf($l,$this->data[$i]);
210                               
211                if( $this->setslicecolors==null )
212                    $graph->legend->Add($l,$colors[$ta[$i%$numcolors]]);
213                else
214                    $graph->legend->Add($l,$this->setslicecolors[$i%$numcolors]);
215                ++$i;
216                               
217                                // Breakout if there are more legends then values
218                if( $i==count($this->data) ) return;
219            }
220        }
221    }
222       
223    // Specify precision for labels. This is almost a deprecated function
224    // nowadays since the introduction of SetLabelFormat()
225    function SetPrecision($p,$psign=true) {
226        if( $p<0 || $p>8 )
227            JpGraphError::Raise("JpGraph Error: Pie label Precision must be between 0 and 8");
228        $this->labelformat="%01.".$p."f";
229        $this->show_psign=$psign;
230    }
231       
232    function Stroke(&$img) {
233               
234        $colors = array_keys($img->rgb->rgb_table);
235        sort($colors); 
236        $ta=$this->themearr[$this->theme];     
237       
238        if( $this->setslicecolors==null )
239            $numcolors=count($ta);
240        else
241            $numcolors=count($this->setslicecolors);
242       
243        // Draw the slices
244        $sum=0;
245        for($i=0; $i<count($this->data); ++$i)
246            $sum += $this->data[$i];
247               
248        // Format the titles for each slice
249        for( $i=0; $i<count($this->data); ++$i) {
250            if( $this->labeltype==0 )
251                if( $sum != 0 )
252                    $l = round(100*$this->data[$i]/$sum,$this->precision);
253                else
254                    $l = 0;
255            else
256                $l = $this->data[$i];
257            $l = sprintf($this->labelformat,$l);
258            if( $this->show_psign ) $l .= "%";
259            $this->labels[$i]=$l;
260        }
261               
262        // Set up the pic-circle
263        if( $this->radius < 1 )
264            $radius = floor($this->radius*min($img->width,$img->height));
265        else
266            $radius = $this->radius;
267        $xc = $this->posx*$img->width;
268        $yc = $this->posy*$img->height;
269               
270        $accsum=0;
271        $angle2 = $this->startangle;
272        $img->SetColor($this->color);
273
274        if( $this->explode_all )
275            for($i=0;$i<count($this->data);++$i)
276                $this->explode_radius[$i]=$this->explode_r;
277
278        for($i=0; $sum>0 && $i<count($this->data); ++$i) {
279            $d = $this->data[$i];
280            $angle1 = $angle2;
281            $accsum += $d;
282            $angle2 = $this->startangle+2.0*M_PI*$accsum/$sum;
283           
284            if( $this->setslicecolors==null )
285                $slicecolor=$colors[$ta[$i%$numcolors]];
286            else
287                $slicecolor=$this->setslicecolors[$i%$numcolors];
288
289            if( $this->pie_interior_border )
290                $img->SetColor($this->color);
291            else
292                $img->SetColor($slicecolor);
293
294            $arccolor = $this->pie_border ? $this->color : $slicecolor;
295
296            $la = abs($angle2-$angle1)/2.0+$angle1;
297            if( empty($this->explode_radius[$i]) )
298                $this->explode_radius[$i]=0;
299            $xcm = $xc + $this->explode_radius[$i]*cos($la);
300            $ycm = $yc - $this->explode_radius[$i]*sin($la);
301           
302            $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1,$angle1,$angle2,
303                            $slicecolor,$arccolor);
304
305            if( $this->show_labels )
306                $this->StrokeLabels($this->labels[$i],$img,$xc,$yc,$la,
307                                    $radius+$this->explode_radius[$i]); 
308
309            if ($this->csimtargets) {
310                $this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2);
311            }                   
312
313        }
314        // Adjust title position
315        $this->title->Pos($xc,$yc-$img->GetFontHeight()-$radius,"center","bottom");
316        $this->title->Stroke($img);
317               
318    }
319
320//---------------
321// PRIVATE METHODS     
322       
323    // Position the labels of each slice
324    function StrokeLabels($label,$img,$xc,$yc,$a,$r) {
325        $img->SetFont($this->font_family,$this->font_style,$this->font_size);
326        $img->SetColor($this->font_color);
327        $img->SetTextAlign("left","top");
328        $marg=6;
329        $r += $img->GetFontHeight()/2;
330        $xt=round($r*cos($a)+$xc);
331        $yt=round($yc-$r*sin($a));
332
333        // Position the axis title.
334        // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text
335        // that intersects with the extension of the corresponding axis. The code looks a little
336        // bit messy but this is really the only way of having a reasonable position of the
337        // axis titles.
338        $h=$img->GetTextHeight($label);
339        $w=$img->GetTextWidth($label);
340        while( $a > 2*M_PI ) $a -= 2*M_PI;
341        if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0;
342        if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI;
343        if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1;
344        if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI);
345               
346        if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI;
347        if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI);
348        if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1;
349        if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI);
350        if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0;
351               
352        $img->StrokeText($xt-$dx*$w,$yt-$dy*$h,$label);         
353    }   
354} // Class
355
356
357
358//===================================================
359// CLASS PieGraph
360// Description:
361//===================================================
362class PieGraph extends Graph {
363    var $posx, $posy, $radius;         
364    var $legends=array();       
365    var $plots=array();
366//---------------
367// CONSTRUCTOR
368    function PieGraph($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) {
369        $this->Graph($width,$height,$cachedName,$timeout,$inline);
370        $this->posx=$width/2;
371        $this->posy=$height/2;
372        $this->SetColor(array(255,255,255));           
373    }
374
375//---------------
376// PUBLIC METHODS       
377    function Add(&$pie) {
378        $this->plots[] = $pie;
379    }
380       
381    function SetColor($c) {
382        $this->SetMarginColor($c);
383    }
384
385    // Method description
386    function Stroke($aStrokeFileName="") {
387               
388        $this->StrokeFrame();           
389               
390        for($i=0; $i<count($this->plots); ++$i)
391            $this->plots[$i]->Stroke($this->img);
392               
393        foreach( $this->plots as $p)
394            $p->Legend($this); 
395               
396        $this->legend->Stroke($this->img);
397        $this->title->Center($this->img->left_margin,$this->img->width-$this->img->right_margin,5);
398        $this->title->Stroke($this->img);               
399
400        // Stroke texts
401        if( $this->texts != null )
402            foreach( $this->texts as $t)
403                $t->Stroke($this->img);
404
405               
406        if ($this->showcsim) {
407            foreach($this->plots as $p ) {
408                $csim.= $p->GetCSIMareas();
409            }
410            //$csim.= $this->legend->GetCSIMareas();
411            if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) {
412                $this->img->SetColor($this->csimcolor);
413                for ($i=0; $i<count($coords[0]); $i++) {
414                    if ($coords[1][$i]=="poly") {
415                        preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts);
416                        $this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]);
417                        for ($j=0; $j<count($pts[0]); $j++) {
418                            $this->img->LineTo($pts[1][$j],$pts[2][$j]);
419                        }
420                    } else if ($coords[1][$i]=="rect") {
421                        $pts = preg_split('/,/', $coords[2][$i]);
422                        $this->img->SetStartPoint($pts[0],$pts[1]);
423                        $this->img->LineTo($pts[2],$pts[1]);
424                        $this->img->LineTo($pts[2],$pts[3]);
425                        $this->img->LineTo($pts[0],$pts[3]);
426                        $this->img->LineTo($pts[0],$pts[1]);
427                                               
428                    }
429                }
430            }
431        }
432               
433        // Finally output the image
434        $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName);                                       
435    }
436} // Class
437
438/* EOF */
439?>
Note: See TracBrowser for help on using the repository browser.