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

Revision 3594, 9.0 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_PIE3D.PHP
4// Description: 3D Pie plot extension for JpGraph
5// Created:     2001-03-24
6// Author:      Johan Persson (johanp@aditus.nu)
7// Ver:         $Id: jpgraph_pie3d.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 PiePlot3D
16// Description: Plots a 3D pie with a specified projection
17// angle between 20 and 70 degrees.
18//===================================================
19class PiePlot3D extends PiePlot {
20    var $labelhintcolor="red",$showlabelhint=true,$labelmargin=0.30;
21    var $angle=30;     
22       
23//---------------
24// CONSTRUCTOR
25    function PiePlot3d(&$data) {
26        $this->data = $data;
27        $this->title = new Text("");
28        $this->title->SetFont(FF_FONT1,FS_BOLD);
29    }
30
31//---------------
32// PUBLIC METHODS       
33       
34    // Specify projection angle for 3D in degrees
35    // Must be between 20 and 70 degrees
36    function SetAngle($a) {
37        if( $a<30 || $a>70 )
38            JpGraphError::Raise("JpGraph: 3D Pie projection angle must be between 30 and 70 degrees.");
39        else
40            $this->angle = $a;
41    }
42
43    function AddSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) {  //Slice number, ellipse centre (x,y), height, width, start angle, end angle
44               
45        //add coordinates of the centre to the map
46        $coords = "$xc, $yc";
47
48        //add coordinates of the first point on the arc to the map
49        $xp = floor($width*cos($sa)/2+$xc);
50        $yp = floor($yc-$height*sin($sa)/2);
51        $coords.= ", $xp, $yp";
52
53        //If on the front half, add the thickness offset
54        if ($sa >= M_PI && $sa <= 2*M_PI*1.01) {
55            $yp = floor($yp+($thick*$width));
56            $coords.= ", $xp, $yp";
57        }
58               
59        //add coordinates every 0.2 radians
60        $a=$sa+0.2;
61        while ($a<$ea) {
62            $xp = floor($width*cos($a)/2+$xc);
63            if ($a >= M_PI && $a <= 2*M_PI*1.01) {
64                $yp = floor($yc-($height*sin($a)/2)+$thick*$width);
65            } else {
66                $yp = floor($yc-$height*sin($a)/2);
67            }
68            $coords.= ", $xp, $yp";
69            $a += 0.2;
70        }
71               
72        //Add the last point on the arc
73        $xp = floor($width*cos($ea)/2+$xc);
74        $yp = floor($yc-$height*sin($ea)/2);
75
76        //If on the front half, add the thickness offset
77        if ($ea >= M_PI && $ea <= 2*M_PI*1.01) {
78            $coords.= ", $xp, ".floor($yp+($thick*$width));
79        }
80        $coords.= ", $xp, $yp";
81        if( !empty($this->csimalts[$i]) ) {                                                                             
82            $tmp=sprintf($this->csimalts[$i],$this->data[$i]);
83            $alt="alt=\"$tmp\"";
84        }
85        if( !empty($this->csimtargets[$i]) )
86            $this->csimareas .= "<area shape=\"poly\" coords=\"$coords\" href=\"".$this->csimtargets[$i]."\" $alt>\r\n";
87    }
88
89       
90    function ExplodeSlice($e) {
91        JpGraphError::Raise("JpGraph Error: Exploding slices are not (yet) implemented for 3d pies graphs.");
92        //$this->explode_slice=$e;
93    }
94       
95    // Distance from the pie to the labels
96    function SetLabelMargin($m) {
97        assert($m>0 && $m<1);
98        $this->labelmargin=$m;
99    }
100       
101    // Show a thin line from the pie to the label for a specific slice
102    function ShowLabelHint($f=true) {
103        $this->showlabelhint=$f;
104    }
105       
106    // Set color of hint line to label for each slice
107    function SetLabelHintColor($c) {
108        $this->labelhintcolor=$c;
109    }
110               
111    function Stroke(&$img) {
112               
113        $colors = array_keys($img->rgb->rgb_table);
114        sort($colors); 
115        $ta=$this->themearr[$this->theme];     
116       
117        if( $this->setslicecolors==null )
118            $numcolors=count($ta);
119        else
120            $numcolors=count($this->setslicecolors);
121       
122        // Draw the slices
123        $sum=0;
124        foreach($this->data as $d)
125            $sum += $d;
126               
127        // Format the titles for each slice
128        for( $i=0; $i<count($this->data); ++$i) {
129            if( $this->labeltype==0 )
130                if( $sum != 0 )
131                    $l = round(100*$this->data[$i]/$sum,$this->precision);
132                else
133                    $l=0;
134            else
135                $l = $this->data[$i];
136            $l = sprintf($this->labelformat,$l);
137            if( $this->show_psign ) $l .= "%";
138            $this->labels[$i]=$l;                       
139        }
140               
141        // Set up the pie-circle with some heuristic constants
142        $thick=0.16-($this->angle-20)/60*0.07;
143       
144        $width = floor(2.0*$this->radius*min($img->width,$img->height));
145        $height = ($this->angle/90.0)*$width;
146        $xc = $this->posx*$img->width;
147        $yc = $this->posy*$img->height;
148
149        $img->SetColor($this->color);                   
150        $img->Ellipse($xc,$yc,$width,$height);
151        $img->Arc($xc,$yc+$width*$thick,$width,$height,0,180);
152        $img->Line($xc+$width/2,$yc,$xc+$width/2,$yc+$width*$thick);
153        $img->Line($xc-$width/2,$yc,$xc-$width/2,$yc+$width*$thick);
154        $fillPerimeter[0] = array('x' => round((($xc - ($width / 2)) + 1)),
155                                  'y' => round(($yc + ($width * $thick) / 2)));
156               
157        // Draw the first slice first line
158        $img->SetColor($this->color);                   
159        $img->SetLineWeight($this->weight);
160        $a = $this->startangle;
161
162        $xp = $width*cos($a)/2+$xc;
163        $yp = $yc-$height*sin($a)/2;
164        $img->Line($xc,$yc,$xp,$yp);
165
166        for($i=0; $sum>0 && $i<count($this->data); $i++) {
167            $img->SetColor($this->color);       
168            $d = $this->data[$i];
169            $la = $a + M_PI*$d/$sum;
170            $old_a = $a;
171            $a += 2*M_PI*$d/$sum;
172
173            if ($this->csimtargets[$i]) {
174                $this->AddSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$old_a,$a);
175            }
176
177            $xp = $width*cos($a)/2+$xc;
178            $yp = $yc-$height*sin($a)/2;
179
180            if( $i<count($this->data)-1)
181                $img->Line($xc,$yc,$xp,$yp);
182
183            if( $a > M_PI && $a < 0.999*2*M_PI )
184                $img->Line($xp,$yp,$xp,$yp+$width*$thick-1);
185
186            if($a < M_PI) {
187                $fillPerimeter[$i + 1] = $fillPerimeter[$i];
188            } else {
189                $fillPerimeter[$i + 1] = array('x' => round(($xp + 1)),
190                                               'y' => round(($yp + ($width * $thick) / 2)));
191            }
192                       
193            if( $this->setslicecolors==null )
194                $slicecolor=$colors[$ta[$i%$numcolors]];
195            else
196                $slicecolor=$this->setslicecolors[$i%$numcolors];
197                               
198            if( $this->show_labels ) {
199                $margin = 1 + $this->labelmargin;
200                $xp = $width*cos($la)/2*$margin;
201                $yp = $height*sin($la)/2*$margin;
202                                                                       
203                if( ($la >= 0 && $la <= M_PI) || $la>2*M_PI*0.98 ) {
204                    $this->StrokeLabels($this->labels[$i],$img,$la,$xc+$xp,$yc-$yp);   
205                    if( $this->showlabelhint ) {
206                        $img->SetColor($this->labelhintcolor);
207                        $img->Line($xc+$xp/$margin,$yc-$yp/$margin,$xc+$xp,$yc-$yp);
208                    }
209                }
210                else {
211                    $this->StrokeLabels($this->labels[$i],$img,$la,$xc+$xp,$yc-$yp+$width*$thick);     
212                    if( $this->showlabelhint ) {
213                        $img->SetColor($this->labelhintcolor);
214                        $img->Line($xc+$xp/$margin,$yc-$yp/$margin+$width*$thick,$xc+$xp,$yc-$yp+$width*$thick);
215                    }
216                }                                       
217
218
219                $img->SetColor($slicecolor);
220                $xp = $width*cos($la)/3+$xc;
221                $yp = $yc-$height*sin($la)/3;
222                $img->Fill(round($xp), round($yp));
223
224                // Make the edge color 35% darker
225                $img->SetColor($slicecolor.":0.65");
226                               
227                if($fillPerimeter[$i]['x'] <= $xc + ($width / 2)) {
228                    $img->Fill($fillPerimeter[$i]['x'],$fillPerimeter[$i]['y']);
229                }
230            }
231        }       
232               
233        // Adjust title position
234        $this->title->Pos($xc,$yc-$img->GetFontHeight()-$this->radius,"center","bottom");
235        $this->title->Stroke($img);
236
237        // Draw the pie ellipse one more time since the filling might have
238        // written partly on the lines due to the filling in the edges.
239        $img->SetColor($this->color);                   
240        $img->Ellipse($xc,$yc,$width,$height);
241        $img->Arc($xc,$yc+$width*$thick,$width,$height,0,180);
242
243        // Draw the first slice first line
244        $a = $this->startangle;
245        $xp = $width*cos($a)/2+$xc;
246        $yp = $yc-$height*sin($a)/2;
247        $img->Line($xc,$yc,$xp,$yp);
248
249        // Draw the rest of the slice lines
250        for($i=0, $a=0; $sum>0 && $i<count($this->data); $i++) {
251            $d = $this->data[$i];
252            $la = $a + M_PI*$d/$sum;
253            $old_a = $a;
254            $a += 2*M_PI*$d/$sum;
255                 
256            $xp = $width*cos($a)/2+$xc;
257            $yp = $yc-$height*sin($a)/2;
258
259            if( $a > M_PI && $a < 0.999*2*M_PI )
260                $img->Line($xp,$yp,$xp,$yp+$width*$thick-1);
261                 
262            if( $i<count($this->data)-1)
263                $img->Line($xc,$yc,$xp,$yp);
264        }
265
266        $img->Line($xc+$width/2,$yc,$xc+$width/2,$yc+$width*$thick);
267        $img->Line($xc-$width/2,$yc,$xc-$width/2,$yc+$width*$thick);
268               
269    }
270
271//---------------
272// PRIVATE METHODS     
273
274    // Position the labels of each slice
275    function StrokeLabels($label,$img,$a,$xp,$yp) {
276               
277        $img->SetFont($this->font_family,$this->font_style,$this->font_size);
278        $img->SetColor($this->font_color);
279        $img->SetTextAlign("left","top");
280        $marg=6;
281
282        // Position the axis title.
283        // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text
284        // that intersects with the extension of the corresponding axis. The code looks a little
285        // bit messy but this is really the only way of having a reasonable position of the
286        // axis titles.
287        $h=$img->GetTextHeight($label);
288        $w=$img->GetTextWidth($label);
289        while( $a > 2*M_PI ) $a -= 2*M_PI;
290        if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0;
291        if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI;
292        if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1;
293        if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI);
294               
295        if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI;
296        if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI);
297        if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1;
298        if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI);
299        if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0;
300               
301        $img->StrokeText($xp-$dx*$w,$yp-$dy*$h,$label);         
302    }   
303} // Class
304
305/* EOF */
306?>
Note: See TracBrowser for help on using the repository browser.