Test Failed
Push — CI ( 0f01dd...c95a04 )
by Adam
55:13
created

pPie::draw2DRing()   F

Complexity

Conditions 75
Paths > 20000

Size

Total Lines 206
Code Lines 132

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 206
rs 2
cc 75
eloc 132
nc 429496.7295
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
 /*
3
     pPie - class to draw pie charts
4
5
     Version     : 2.1.4
6
     Made by     : Jean-Damien POGOLOTTI
7
     Last Update : 19/01/2014
8
9
     This file can be distributed under the license you can find at :
10
11
                       http://www.pchart.net/license
12
13
     You can find the whole class documentation on the pChart web site.
14
 */
15
16
 /* Class return codes */
17
 define("PIE_NO_ABSCISSA"	, 140001);
18
 define("PIE_NO_DATASERIE"	, 140002);
19
 define("PIE_SUMISNULL"		, 140003);
20
 define("PIE_RENDERED"		, 140000);
21
22
 define("PIE_LABEL_COLOR_AUTO"	, 140010);
23
 define("PIE_LABEL_COLOR_MANUAL", 140011);
24
25
 define("PIE_VALUE_NATURAL"	, 140020);
26
 define("PIE_VALUE_PERCENTAGE"	, 140021);
27
28
 define("PIE_VALUE_INSIDE"      , 140030);
29
 define("PIE_VALUE_OUTSIDE"     , 140031);
30
31
 /* pPie class definition */
32
 class pPie
33
  {
34
   var $pChartObject;
35
   var $pDataObject;
36
   var $LabelPos = "" ;
37
38
   /* Class creator */
39
   function pPie($Object,$pDataObject)
40
    {
41
     /* Cache the pChart object reference */
42
     $this->pChartObject = $Object;
43
44
     /* Cache the pData object reference */
45
     $this->pDataObject  = $pDataObject;
46
    }
47
48
   /* Draw a pie chart */
49
   function draw2DPie($X,$Y,$Format="")
50
    {
51
     $Radius		= isset($Format["Radius"]) ? $Format["Radius"] : 60;
52
     $Precision		= isset($Format["Precision"]) ? $Format["Precision"] : 0;
53
     $DataGapAngle	= isset($Format["DataGapAngle"]) ? $Format["DataGapAngle"] : 0;
54
     $DataGapRadius	= isset($Format["DataGapRadius"]) ? $Format["DataGapRadius"] : 0;
55
     $SecondPass	= isset($Format["SecondPass"]) ? $Format["SecondPass"] : TRUE;
56
     $Border		= isset($Format["Border"]) ? $Format["Border"] : FALSE;
57
     $BorderR		= isset($Format["BorderR"]) ? $Format["BorderR"] : 255;
58
     $BorderG		= isset($Format["BorderG"]) ? $Format["BorderG"] : 255;
59
     $BorderB		= isset($Format["BorderB"]) ? $Format["BorderB"] : 255;
60
     $Shadow		= isset($Format["Shadow"]) ? $Format["Shadow"] : FALSE;
61
     $DrawLabels	= isset($Format["DrawLabels"]) ? $Format["DrawLabels"] : FALSE;
62
     $LabelStacked	= isset($Format["LabelStacked"]) ? $Format["LabelStacked"] : FALSE;
63
     $LabelColor	= isset($Format["LabelColor"]) ? $Format["LabelColor"] : PIE_LABEL_COLOR_MANUAL;
64
     $LabelR		= isset($Format["LabelR"]) ? $Format["LabelR"] : 0;
65
     $LabelG		= isset($Format["LabelG"]) ? $Format["LabelG"] : 0;
66
     $LabelB		= isset($Format["LabelB"]) ? $Format["LabelB"] : 0;
67
     $LabelAlpha	= isset($Format["LabelAlpha"]) ? $Format["LabelAlpha"] : 100;
68
     $WriteValues	= isset($Format["WriteValues"]) ? $Format["WriteValues"] : NULL;
69
     $ValuePosition	= isset($Format["ValuePosition"]) ? $Format["ValuePosition"] : PIE_VALUE_OUTSIDE;
70
     $ValuePadding	= isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 15;
71
     $ValueSuffix	= isset($Format["ValueSuffix"]) ? $Format["ValueSuffix"] : "";
72
     $ValueR		= isset($Format["ValueR"]) ? $Format["ValueR"] : 255;
73
     $ValueG		= isset($Format["ValueG"]) ? $Format["ValueG"] : 255;
74
     $ValueB		= isset($Format["ValueB"]) ? $Format["ValueB"] : 255;
75
     $ValueAlpha	= isset($Format["ValueAlpha"]) ? $Format["ValueAlpha"] : 100;
76
     $RecordImageMap	= isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
77
78
     /* Data Processing */
79
     $Data    = $this->pDataObject->getData();
80
     $Palette = $this->pDataObject->getPalette();
81
82
     /* Do we have an abscissa serie defined? */
83
     if ( $Data["Abscissa"] == "" ) { return(PIE_NO_ABSCISSA); }
84
85
     /* Try to find the data serie */
86
     $DataSerie = "";
87
     foreach ($Data["Series"] as $SerieName => $SerieData)
88
      { if ( $SerieName != $Data["Abscissa"]) { $DataSerie = $SerieName; } }
89
90
     /* Do we have data to compute? */
91
     if ( $DataSerie == "" ) { return(PIE_NO_DATASERIE); }
92
93
     /* Remove unused data */
94
     list($Data,$Palette) = $this->clean0Values($Data,$Palette,$DataSerie,$Data["Abscissa"]);
95
96
     /* Compute the pie sum */
97
     $SerieSum = $this->pDataObject->getSum($DataSerie);
98
99
     /* Do we have data to draw? */
100
     if ( $SerieSum == 0 ) { return(PIE_SUMISNULL); }
101
102
     /* Dump the real number of data to draw */
103
     $Values = "";
104
     foreach ($Data["Series"][$DataSerie]["Data"] as $Key => $Value)
105
      { if ($Value != 0) { $Values[] = $Value; } }
106
107
     /* Compute the wasted angular space between series */
108
     if (count($Values)==1) { $WastedAngular = 0; } else { $WastedAngular = count($Values) * $DataGapAngle; }
109
110
     /* Compute the scale */
111
     $ScaleFactor = (360 - $WastedAngular) / $SerieSum;
112
113
     $RestoreShadow = $this->pChartObject->Shadow;
114
     if ( $this->pChartObject->Shadow )
115
      {
116
       $this->pChartObject->Shadow = FALSE;
117
118
       $ShadowFormat = $Format; $ShadowFormat["Shadow"] = TRUE;
119
       $this->draw2DPie($X+$this->pChartObject->ShadowX,$Y+$this->pChartObject->ShadowY,$ShadowFormat);
120
      }
121
122
     /* Draw the polygon pie elements */
123
     $Step = 360 / (2 * PI * $Radius);
124
     $Offset = 0; $ID = 0;
125
     foreach($Values as $Key => $Value)
0 ignored issues
show
Bug introduced by
The expression $Values of type string is not traversable.
Loading history...
126
      {
127
       if ( $Shadow )
128
        $Settings = array("R"=>$this->pChartObject->ShadowR,"G"=>$this->pChartObject->ShadowG,"B"=>$this->pChartObject->ShadowB,"Alpha"=>$this->pChartObject->Shadowa);
129
       else
130
        {
131
         if ( !isset($Palette[$ID]["R"]) ) { $Color = $this->pChartObject->getRandomColor(); $Palette[$ID] = $Color; $this->pDataObject->savePalette($ID,$Color); }
132
         $Settings = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);
133
        }
134
135
       if ( !$SecondPass && !$Shadow )
136
        {
137
         if ( !$Border )
138
          $Settings["Surrounding"] = 10;
139
         else
140
          { $Settings["BorderR"] = $BorderR; $Settings["BorderG"] = $BorderG; $Settings["BorderB"] = $BorderB; }
141
        }
142
143
       $Plots = "";
144
       $EndAngle = $Offset+($Value*$ScaleFactor); if ( $EndAngle > 360 ) { $EndAngle = 360; }
145
146
       $Angle = ($EndAngle - $Offset)/2 + $Offset;
147
       if ($DataGapAngle == 0)
148
        { $X0 = $X; $Y0 = $Y; }
149
       else
150
        {
151
         $X0 = cos(($Angle-90)*PI/180) * $DataGapRadius + $X;
152
         $Y0 = sin(($Angle-90)*PI/180) * $DataGapRadius + $Y;
153
        }
154
155
       $Plots[] = $X0; $Plots[] = $Y0;
156
157
158
       for($i=$Offset;$i<=$EndAngle;$i=$i+$Step)
159
        {
160
         $Xc = cos(($i-90)*PI/180) * $Radius + $X;
161
         $Yc = sin(($i-90)*PI/180) * $Radius + $Y;
162
163
         if ( $SecondPass && ( $i<90 )) { $Yc++; }
164
         if ( $SecondPass && ( $i>180 && $i<270 )) { $Xc++; }
165
         if ( $SecondPass && ( $i>=270 )) { $Xc++; $Yc++; }
166
167
         $Plots[] = $Xc; $Plots[] = $Yc;
168
        }
169
170
       $this->pChartObject->drawPolygon($Plots,$Settings);
171
       if ( $RecordImageMap && !$Shadow ) { $this->pChartObject->addToImageMap("POLY",$this->arraySerialize($Plots),$this->pChartObject->toHTMLColor($Palette[$ID]["R"],$Palette[$ID]["G"],$Palette[$ID]["B"]),$Data["Series"][$Data["Abscissa"]]["Data"][$Key],$Value); }
172
173
       if ( $DrawLabels && !$Shadow && !$SecondPass )
174
        {
175
         if ( $LabelColor == PIE_LABEL_COLOR_AUTO )
176
          { $Settings = array("FillR"=>$Palette[$ID]["R"],"FillG"=>$Palette[$ID]["G"],"FillB"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);}
177
         else
178
          { $Settings = array("FillR"=>$LabelR,"FillG"=>$LabelG,"FillB"=>$LabelB,"Alpha"=>$LabelAlpha); }
179
180
         $Angle = ($EndAngle - $Offset)/2 + $Offset;
181
         $Xc = cos(($Angle-90)*PI/180) * $Radius + $X;
182
         $Yc = sin(($Angle-90)*PI/180) * $Radius + $Y;
183
184
         $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];
185
186
         if ( $LabelStacked )
187
          $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,TRUE,$X,$Y,$Radius);
188
         else
189
          $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,FALSE);
190
        }
191
192
       $Offset = $i + $DataGapAngle; $ID++;
193
      }
194
195
     /* Second pass to smooth the angles */
196
     if ( $SecondPass )
197
      {
198
       $Step = 360 / (2 * PI * $Radius);
199
       $Offset = 0; $ID = 0;
200
       foreach($Values as $Key => $Value)
0 ignored issues
show
Bug introduced by
The expression $Values of type string is not traversable.
Loading history...
201
        {
202
         $FirstPoint = TRUE;
203
         if ( $Shadow )
204
          $Settings = array("R"=>$this->pChartObject->ShadowR,"G"=>$this->pChartObject->ShadowG,"B"=>$this->pChartObject->ShadowB,"Alpha"=>$this->pChartObject->Shadowa);
205
         else
206
          {
207
           if ( $Border )
208
            $Settings = array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB);
209
           else
210
            $Settings = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);
211
          }
212
213
         $EndAngle = $Offset+($Value*$ScaleFactor); if ( $EndAngle > 360 ) { $EndAngle = 360; }
214
215
         if ($DataGapAngle == 0)
216
          { $X0 = $X; $Y0 = $Y; }
217
         else
218
          {
219
           $Angle = ($EndAngle - $Offset)/2 + $Offset;
220
           $X0 = cos(($Angle-90)*PI/180) * $DataGapRadius + $X;
221
           $Y0 = sin(($Angle-90)*PI/180) * $DataGapRadius + $Y;
222
          }
223
         $Plots[] = $X0; $Plots[] = $Y0;
224
225
         for($i=$Offset;$i<=$EndAngle;$i=$i+$Step)
226
          {
227
           $Xc = cos(($i-90)*PI/180) * $Radius + $X;
228
           $Yc = sin(($i-90)*PI/180) * $Radius + $Y;
229
230
           if ( $FirstPoint ) { $this->pChartObject->drawLine($Xc,$Yc,$X0,$Y0,$Settings); } { $FirstPoint = FALSE; }
231
  
232
           $this->pChartObject->drawAntialiasPixel($Xc,$Yc,$Settings);
233
          }
234
         $this->pChartObject->drawLine($Xc,$Yc,$X0,$Y0,$Settings);
235
236
         if ( $DrawLabels && !$Shadow )
237
          {
238
           if ( $LabelColor == PIE_LABEL_COLOR_AUTO )
239
            { $Settings = array("FillR"=>$Palette[$ID]["R"],"FillG"=>$Palette[$ID]["G"],"FillB"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);}
240
           else
241
            { $Settings = array("FillR"=>$LabelR,"FillG"=>$LabelG,"FillB"=>$LabelB,"Alpha"=>$LabelAlpha); }
242
243
           $Angle = ($EndAngle - $Offset)/2 + $Offset;
244
           $Xc = cos(($Angle-90)*PI/180) * $Radius + $X;
245
           $Yc = sin(($Angle-90)*PI/180) * $Radius + $Y;
246
247
           $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];
248
249
           if ( $LabelStacked )
250
            $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,TRUE,$X,$Y,$Radius);
251
           else
252
            $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,FALSE);
253
          }
254
  
255
         $Offset = $i + $DataGapAngle; $ID++;
256
        }
257
      }
258
259
     if ( $WriteValues != NULL && !$Shadow )
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $WriteValues of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
260
      {
261
       $Step = 360 / (2 * PI * $Radius);
262
       $Offset = 0; $ID = count($Values)-1;
263
       $Settings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"R"=>$ValueR,"G"=>$ValueG,"B"=>$ValueB,"Alpha"=>$ValueAlpha);
264
       foreach($Values as $Key => $Value)
0 ignored issues
show
Bug introduced by
The expression $Values of type string is not traversable.
Loading history...
265
        {
266
         $EndAngle = ($Value*$ScaleFactor) + $Offset; if ( (int)$EndAngle > 360 ) { $EndAngle = 0; }
267
         $Angle    = ($EndAngle - $Offset)/2 + $Offset;
268
269
         if ( $ValuePosition == PIE_VALUE_OUTSIDE )
270
          {
271
           $Xc = cos(($Angle-90)*PI/180) * ($Radius+$ValuePadding) + $X;
272
           $Yc = sin(($Angle-90)*PI/180) * ($Radius+$ValuePadding) + $Y;
273
          }
274
         else
275
          {
276
           $Xc = cos(($Angle-90)*PI/180) * ($Radius)/2 + $X;
277
           $Yc = sin(($Angle-90)*PI/180) * ($Radius)/2 + $Y;
278
          }
279
280
         if ( $WriteValues == PIE_VALUE_PERCENTAGE )
281
          $Display = round(( 100 / $SerieSum ) * $Value,$Precision)."%";
282
         elseif ( $WriteValues == PIE_VALUE_NATURAL )
283
          $Display = $Value.$ValueSuffix;
284
285
         $this->pChartObject->drawText($Xc,$Yc,$Display,$Settings);
286
287
         $Offset = $EndAngle + $DataGapAngle; $ID--;
288
        }
289
      }
290
291
     if ( $DrawLabels && $LabelStacked ) { $this->writeShiftedLabels(); }
292
293
     $this->pChartObject->Shadow = $RestoreShadow;
294
295
     return(PIE_RENDERED);
296
    }
297
298
   /* Draw a 3D pie chart */
299
   function draw3DPie($X,$Y,$Format="")
300
    {
301
     /* Rendering layout */
302
     $Radius		= isset($Format["Radius"]) ? $Format["Radius"] : 80;
303
     $Precision		= isset($Format["Precision"]) ? $Format["Precision"] : 0;
304
     $SkewFactor	= isset($Format["SkewFactor"]) ? $Format["SkewFactor"] : .5;
305
     $SliceHeight	= isset($Format["SliceHeight"]) ? $Format["SliceHeight"] : 20;
306
     $DataGapAngle	= isset($Format["DataGapAngle"]) ? $Format["DataGapAngle"] : 0;
307
     $DataGapRadius	= isset($Format["DataGapRadius"]) ? $Format["DataGapRadius"] : 0;
308
     $SecondPass	= isset($Format["SecondPass"]) ? $Format["SecondPass"] : TRUE;
309
     $Border		= isset($Format["Border"]) ? $Format["Border"] : FALSE;
310
     $Shadow		= isset($Format["Shadow"]) ? $Format["Shadow"] : FALSE;
311
     $DrawLabels	= isset($Format["DrawLabels"]) ? $Format["DrawLabels"] : FALSE;
312
     $LabelStacked	= isset($Format["LabelStacked"]) ? $Format["LabelStacked"] : FALSE;
313
     $LabelColor	= isset($Format["LabelColor"]) ? $Format["LabelColor"] : PIE_LABEL_COLOR_MANUAL;
314
     $LabelR		= isset($Format["LabelR"]) ? $Format["LabelR"] : 0;
315
     $LabelG		= isset($Format["LabelG"]) ? $Format["LabelG"] : 0;
316
     $LabelB		= isset($Format["LabelB"]) ? $Format["LabelB"] : 0;
317
     $LabelAlpha	= isset($Format["LabelAlpha"]) ? $Format["LabelAlpha"] : 100;
318
     $WriteValues	= isset($Format["WriteValues"]) ? $Format["WriteValues"] : NULL; //PIE_VALUE_PERCENTAGE
319
     $ValuePosition	= isset($Format["ValuePosition"]) ? $Format["ValuePosition"] : PIE_VALUE_INSIDE;
320
     $ValuePadding	= isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 15;
321
     $ValueSuffix	= isset($Format["ValueSuffix"]) ? $Format["ValueSuffix"] : "";
322
     $ValueR		= isset($Format["ValueR"]) ? $Format["ValueR"] : 255;
323
     $ValueG		= isset($Format["ValueG"]) ? $Format["ValueG"] : 255;
324
     $ValueB		= isset($Format["ValueB"]) ? $Format["ValueB"] : 255;
325
     $ValueAlpha	= isset($Format["ValueAlpha"]) ? $Format["ValueAlpha"] : 100;
326
     $RecordImageMap	= isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
327
328
     /* Error correction for overlaying rounded corners */
329
     if ( $SkewFactor < .5 ) { $SkewFactor = .5; }
330
331
     /* Data Processing */
332
     $Data    = $this->pDataObject->getData();
333
     $Palette = $this->pDataObject->getPalette();
334
335
     /* Do we have an abscissa serie defined? */
336
     if ( $Data["Abscissa"] == "" ) { return(PIE_NO_ABSCISSA); }
337
338
     /* Try to find the data serie */
339
     $DataSerie = "";
340
     foreach ($Data["Series"] as $SerieName => $SerieData)
341
      { if ( $SerieName != $Data["Abscissa"]) { $DataSerie = $SerieName; } }
342
343
     /* Do we have data to compute? */
344
     if ( $DataSerie == "" ) { return(PIE_NO_DATASERIE); }
345
346
     /* Remove unused data */
347
     list($Data,$Palette) = $this->clean0Values($Data,$Palette,$DataSerie,$Data["Abscissa"]);
348
349
     /* Compute the pie sum */
350
     $SerieSum = $this->pDataObject->getSum($DataSerie);
351
352
     /* Do we have data to draw? */
353
     if ( $SerieSum == 0 ) { return(PIE_SUMISNULL); }
354
355
     /* Dump the real number of data to draw */
356
     $Values = "";
357
     foreach ($Data["Series"][$DataSerie]["Data"] as $Key => $Value)
358
      { if ($Value != 0) { $Values[] = $Value; } }
359
360
     /* Compute the wasted angular space between series */
361
     if (count($Values)==1) { $WastedAngular = 0; } else { $WastedAngular = count($Values) * $DataGapAngle; }
362
363
     /* Compute the scale */
364
     $ScaleFactor = (360 - $WastedAngular) / $SerieSum;
365
366
     $RestoreShadow = $this->pChartObject->Shadow;
367
     if ( $this->pChartObject->Shadow ) { $this->pChartObject->Shadow = FALSE; }
368
369
     /* Draw the polygon pie elements */
370
     $Step   = 360 / (2 * PI * $Radius);
371
     $Offset = 360; $ID = count($Values)-1;
372
     $Values = array_reverse($Values);
373
     $Slice  = 0; $Slices = ""; $SliceColors = ""; $Visible = ""; $SliceAngle = "";
374
     foreach($Values as $Key => $Value)
375
      {
376
       if ( !isset($Palette[$ID]["R"]) ) { $Color = $this->pChartObject->getRandomColor(); $Palette[$ID] = $Color; $this->pDataObject->savePalette($ID,$Color); }
377
       $Settings = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);
378
379
       $SliceColors[$Slice] = $Settings;
380
381
       $StartAngle = $Offset;
382
       $EndAngle   = $Offset-($Value*$ScaleFactor); if ( $EndAngle < 0 ) { $EndAngle = 0; }
383
384
       if ( $StartAngle > 180 ) { $Visible[$Slice]["Start"] = TRUE; } else { $Visible[$Slice]["Start"] = TRUE; }
385
       if ( $EndAngle < 180 )   { $Visible[$Slice]["End"] = FALSE; } else { $Visible[$Slice]["End"] = TRUE; }
386
387
       if ($DataGapAngle == 0)
388
        { $X0 = $X; $Y0 = $Y; }
389
       else
390
        {
391
         $Angle = ($EndAngle - $Offset)/2 + $Offset;
392
         $X0 = cos(($Angle-90)*PI/180) * $DataGapRadius + $X;
393
         $Y0 = sin(($Angle-90)*PI/180) * $DataGapRadius*$SkewFactor + $Y;
394
        }
395
       $Slices[$Slice][] = $X0; $Slices[$Slice][] = $Y0; $SliceAngle[$Slice][] = 0;
396
397
       for($i=$Offset;$i>=$EndAngle;$i=$i-$Step)
398
        {
399
         $Xc = cos(($i-90)*PI/180) * $Radius + $X;
400
         $Yc = sin(($i-90)*PI/180) * $Radius*$SkewFactor + $Y;
401
402
         if ( ($SecondPass || $RestoreShadow ) && ( $i<90 )) { $Yc++; }
403
         if ( ($SecondPass || $RestoreShadow ) && ( $i>90 && $i<180 )) { $Xc++; }
404
         if ( ($SecondPass || $RestoreShadow ) && ( $i>180 && $i<270 )) { $Xc++; }
405
         if ( ($SecondPass || $RestoreShadow ) && ( $i>=270 )) { $Xc++; $Yc++; }
406
407
         $Slices[$Slice][] = $Xc; $Slices[$Slice][] = $Yc; $SliceAngle[$Slice][] = $i;
408
        }
409
410
       $Offset = $i - $DataGapAngle; $ID--; $Slice++;
411
      }
412
413
     /* Draw the bottom shadow if needed */
414
     if ( $RestoreShadow && ($this->pChartObject->ShadowX != 0 || $this->pChartObject->ShadowY !=0 ))
415
      {
416
       foreach($Slices as $SliceID => $Plots)
0 ignored issues
show
Bug introduced by
The expression $Slices of type string is not traversable.
Loading history...
417
        {
418
         $ShadowPie = "";
419
         for($i=0;$i<count($Plots);$i=$i+2)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
420
          { $ShadowPie[] = $Plots[$i]+$this->pChartObject->ShadowX; $ShadowPie[] = $Plots[$i+1]+$this->pChartObject->ShadowY; }
421
422
         $Settings = array("R"=>$this->pChartObject->ShadowR,"G"=>$this->pChartObject->ShadowG,"B"=>$this->pChartObject->ShadowB,"Alpha"=>$this->pChartObject->Shadowa,"NoBorder"=>TRUE);
423
         $this->pChartObject->drawPolygon($ShadowPie,$Settings);
424
        }
425
426
       $Step = 360 / (2 * PI * $Radius);
427
       $Offset = 360;
428
       foreach($Values as $Key => $Value)
429
        {
430
         $EndAngle = $Offset-($Value*$ScaleFactor); if ( $EndAngle < 0 ) { $EndAngle = 0; }
431
432
         for($i=$Offset;$i>=$EndAngle;$i=$i-$Step)
433
          {
434
           $Xc = cos(($i-90)*PI/180) * $Radius + $X + $this->pChartObject->ShadowX;
435
           $Yc = sin(($i-90)*PI/180) * $Radius*$SkewFactor + $Y + $this->pChartObject->ShadowY;
436
437
           $this->pChartObject->drawAntialiasPixel($Xc,$Yc,$Settings);
438
          }
439
440
         $Offset = $i - $DataGapAngle; $ID--;
441
        }
442
      }
443
444
     /* Draw the bottom pie splice */
445
     foreach($Slices as $SliceID => $Plots)
0 ignored issues
show
Bug introduced by
The expression $Slices of type string is not traversable.
Loading history...
446
      {
447
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
448
       $this->pChartObject->drawPolygon($Plots,$Settings);
449
450
       if ( $SecondPass )
451
        {
452
         $Settings = $SliceColors[$SliceID];
453
         if ( $Border )
454
          { $Settings["R"]+= 30; $Settings["G"]+= 30; $Settings["B"]+= 30;; }
455
  
456
         if ( isset($SliceAngle[$SliceID][1]) ) /* Empty error handling */
457
          {
458
           $Angle = $SliceAngle[$SliceID][1];
459
           $Xc = cos(($Angle-90)*PI/180) * $Radius + $X;
460
           $Yc = sin(($Angle-90)*PI/180) * $Radius*$SkewFactor + $Y;
461
           $this->pChartObject->drawLine($Plots[0],$Plots[1],$Xc,$Yc,$Settings);
462
463
           $Angle = $SliceAngle[$SliceID][count($SliceAngle[$SliceID])-1];
464
           $Xc = cos(($Angle-90)*PI/180) * $Radius + $X;
465
           $Yc = sin(($Angle-90)*PI/180) * $Radius*$SkewFactor + $Y;
466
           $this->pChartObject->drawLine($Plots[0],$Plots[1],$Xc,$Yc,$Settings);
467
          }
468
        }
469
      }
470
471
     /* Draw the two vertical edges */
472
     $Slices      = array_reverse($Slices);
473
     $SliceColors = array_reverse($SliceColors);
474
     foreach($Slices as $SliceID => $Plots)
475
      {
476
       $Settings = $SliceColors[$SliceID];
477
       $Settings["R"]+= 10; $Settings["G"]+= 10; $Settings["B"]+= 10; $Settings["NoBorder"] = TRUE;
478
479
       if ( $Visible[$SliceID]["Start"] && isset($Plots[2])) /* Empty error handling */
480
        {
481
         $this->pChartObject->drawLine($Plots[2],$Plots[3],$Plots[2],$Plots[3]- $SliceHeight,array("R"=>$Settings["R"],"G"=>$Settings["G"],"B"=>$Settings["B"]));
482
         $Border = "";
483
         $Border[] = $Plots[0]; $Border[] = $Plots[1]; $Border[] = $Plots[0]; $Border[] = $Plots[1] - $SliceHeight;
484
         $Border[] = $Plots[2]; $Border[] = $Plots[3] - $SliceHeight; $Border[] = $Plots[2]; $Border[] = $Plots[3]; 
485
         $this->pChartObject->drawPolygon($Border,$Settings);
486
        }
487
      }
488
489
     $Slices      = array_reverse($Slices);
490
     $SliceColors = array_reverse($SliceColors);
491
     foreach($Slices as $SliceID => $Plots)
492
      {
493
       $Settings = $SliceColors[$SliceID];
494
       $Settings["R"]+= 10; $Settings["G"]+= 10; $Settings["B"]+= 10; $Settings["NoBorder"] = TRUE;
495
       if ( $Visible[$SliceID]["End"] )
496
        {
497
         $this->pChartObject->drawLine($Plots[count($Plots)-2],$Plots[count($Plots)-1],$Plots[count($Plots)-2],$Plots[count($Plots)-1]- $SliceHeight,array("R"=>$Settings["R"],"G"=>$Settings["G"],"B"=>$Settings["B"]));
498
499
         $Border = "";
500
         $Border[] = $Plots[0]; $Border[] = $Plots[1]; $Border[] = $Plots[0]; $Border[] = $Plots[1] - $SliceHeight;
501
         $Border[] = $Plots[count($Plots)-2]; $Border[] = $Plots[count($Plots)-1] - $SliceHeight; $Border[] = $Plots[count($Plots)-2]; $Border[] = $Plots[count($Plots)-1]; 
502
         $this->pChartObject->drawPolygon($Border,$Settings);
503
        }
504
      }
505
506
     /* Draw the rounded edges */
507
     foreach($Slices as $SliceID => $Plots)
508
      {
509
       $Settings = $SliceColors[$SliceID];
510
       $Settings["R"]+= 10; $Settings["G"]+= 10; $Settings["B"]+= 10; $Settings["NoBorder"] = TRUE;
511
512
       for ($j=2;$j<count($Plots)-2;$j=$j+2)
513
        {
514
         $Angle = $SliceAngle[$SliceID][$j/2];
515
         if ( $Angle < 270 && $Angle > 90 )
516
          {
517
           $Border = "";
518
           $Border[] = $Plots[$j];   $Border[] = $Plots[$j+1];
519
           $Border[] = $Plots[$j+2]; $Border[] = $Plots[$j+3];
520
           $Border[] = $Plots[$j+2]; $Border[] = $Plots[$j+3] - $SliceHeight;
521
           $Border[] = $Plots[$j];   $Border[] = $Plots[$j+1] - $SliceHeight;
522
           $this->pChartObject->drawPolygon($Border,$Settings);
523
          }
524
        }
525
526
       if ( $SecondPass )
527
        {
528
         $Settings = $SliceColors[$SliceID];
529
         if ( $Border )
530
          { $Settings["R"]+= 30; $Settings["G"]+= 30; $Settings["B"]+= 30; }
531
  
532
         if ( isset($SliceAngle[$SliceID][1]) ) /* Empty error handling */
533
          {
534
           $Angle = $SliceAngle[$SliceID][1];
535
           if ( $Angle < 270 && $Angle > 90 )
536
            {
537
             $Xc = cos(($Angle-90)*PI/180) * $Radius + $X;
538
             $Yc = sin(($Angle-90)*PI/180) * $Radius*$SkewFactor + $Y;
539
             $this->pChartObject->drawLine($Xc,$Yc,$Xc,$Yc-$SliceHeight,$Settings);
540
            }
541
          }
542
543
         $Angle = $SliceAngle[$SliceID][count($SliceAngle[$SliceID])-1];
544
         if ( $Angle < 270 && $Angle > 90 )
545
          {
546
           $Xc = cos(($Angle-90)*PI/180) * $Radius + $X;
547
           $Yc = sin(($Angle-90)*PI/180) * $Radius*$SkewFactor + $Y;
548
           $this->pChartObject->drawLine($Xc,$Yc,$Xc,$Yc-$SliceHeight,$Settings);
549
          }
550
551
         if ( isset($SliceAngle[$SliceID][1]) && $SliceAngle[$SliceID][1] > 270 && $SliceAngle[$SliceID][count($SliceAngle[$SliceID])-1] < 270 )
552
          {
553
           $Xc = cos((270-90)*PI/180) * $Radius + $X;
554
           $Yc = sin((270-90)*PI/180) * $Radius*$SkewFactor + $Y;
555
           $this->pChartObject->drawLine($Xc,$Yc,$Xc,$Yc-$SliceHeight,$Settings);
556
          }
557
558
         if ( isset($SliceAngle[$SliceID][1]) && $SliceAngle[$SliceID][1] > 90 && $SliceAngle[$SliceID][count($SliceAngle[$SliceID])-1] < 90 )
559
          {
560
           $Xc = cos((0)*PI/180) * $Radius + $X;
561
           $Yc = sin((0)*PI/180) * $Radius*$SkewFactor + $Y;
562
           $this->pChartObject->drawLine($Xc,$Yc,$Xc,$Yc-$SliceHeight,$Settings);
563
          }
564
565
        }
566
      }
567
568
     /* Draw the top splice */
569
     foreach($Slices as $SliceID => $Plots)
570
      {
571
       $Settings = $SliceColors[$SliceID];
572
       $Settings["R"]+= 20; $Settings["G"]+= 20; $Settings["B"]+= 20;
573
574
       $Top = "";
575
       for($j=0;$j<count($Plots);$j=$j+2) { $Top[] = $Plots[$j]; $Top[] = $Plots[$j+1]- $SliceHeight; }
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
576
       $this->pChartObject->drawPolygon($Top,$Settings);
577
578
       if ( $RecordImageMap && !$Shadow ) { $this->pChartObject->addToImageMap("POLY",$this->arraySerialize($Top),$this->pChartObject->toHTMLColor($Settings["R"],$Settings["G"],$Settings["B"]),$Data["Series"][$Data["Abscissa"]]["Data"][count($Slices)-$SliceID-1],$Values[$SliceID]); }
579
      }
580
581
582
     /* Second pass to smooth the angles */
583
     if ( $SecondPass )
584
      {
585
       $Step = 360 / (2 * PI * $Radius);
586
       $Offset = 360; $ID = count($Values)-1;
587
       foreach($Values as $Key => $Value)
588
        {
589
         $FirstPoint = TRUE;
590
         if ( $Shadow )
591
          $Settings = array("R"=>$this->pChartObject->ShadowR,"G"=>$this->pChartObject->ShadowG,"B"=>$this->pChartObject->ShadowB,"Alpha"=>$this->pChartObject->Shadowa);
592
         else
593
          {
594
           if ( $Border )
595
            { $Settings = array("R"=>$Palette[$ID]["R"]+30,"G"=>$Palette[$ID]["G"]+30,"B"=>$Palette[$ID]["B"]+30,"Alpha"=>$Palette[$ID]["Alpha"]); }
596
           else
597
            $Settings = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);
598
          }
599
600
         $EndAngle = $Offset-($Value*$ScaleFactor); if ( $EndAngle < 0 ) { $EndAngle = 0; }
601
602
         if ($DataGapAngle == 0)
603
          { $X0 = $X; $Y0 = $Y- $SliceHeight; }
604
         else
605
          {
606
           $Angle = ($EndAngle - $Offset)/2 + $Offset;
607
           $X0 = cos(($Angle-90)*PI/180) * $DataGapRadius + $X;
608
           $Y0 = sin(($Angle-90)*PI/180) * $DataGapRadius*$SkewFactor + $Y - $SliceHeight;
609
          }
610
         $Plots[] = $X0; $Plots[] = $Y0;
611
612
         for($i=$Offset;$i>=$EndAngle;$i=$i-$Step)
613
          {
614
           $Xc = cos(($i-90)*PI/180) * $Radius + $X;
615
           $Yc = sin(($i-90)*PI/180) * $Radius*$SkewFactor + $Y - $SliceHeight;
616
617
           if ( $FirstPoint ) { $this->pChartObject->drawLine($Xc,$Yc,$X0,$Y0,$Settings); } { $FirstPoint = FALSE; }
618
  
619
           $this->pChartObject->drawAntialiasPixel($Xc,$Yc,$Settings);
620
           if ($i < 270 && $i > 90 ) { $this->pChartObject->drawAntialiasPixel($Xc,$Yc+$SliceHeight,$Settings); }
621
          }
622
         $this->pChartObject->drawLine($Xc,$Yc,$X0,$Y0,$Settings);
623
624
         $Offset = $i - $DataGapAngle; $ID--;
625
        }
626
      }
627
628
     if ( $WriteValues != NULL )
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $WriteValues of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
629
      {
630
       $Step = 360 / (2 * PI * $Radius);
631
       $Offset = 360; $ID = count($Values)-1;
632
       $Settings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE,"R"=>$ValueR,"G"=>$ValueG,"B"=>$ValueB,"Alpha"=>$ValueAlpha);
633
       foreach($Values as $Key => $Value)
634
        {
635
         $EndAngle = $Offset-($Value*$ScaleFactor); if ( $EndAngle < 0 ) { $EndAngle = 0; }
636
637
         $Angle = ($EndAngle - $Offset)/2 + $Offset;
638
639
         if ( $ValuePosition == PIE_VALUE_OUTSIDE )
640
          {
641
           $Xc = cos(($Angle-90)*PI/180) * ($Radius+$ValuePadding) + $X;
642
           $Yc = sin(($Angle-90)*PI/180) * (($Radius*$SkewFactor)+$ValuePadding) + $Y - $SliceHeight;
643
          }
644
         else
645
          {
646
           $Xc = cos(($Angle-90)*PI/180) * ($Radius)/2 + $X;
647
           $Yc = sin(($Angle-90)*PI/180) * ($Radius*$SkewFactor)/2 + $Y - $SliceHeight;
648
          }
649
650
         if ( $WriteValues == PIE_VALUE_PERCENTAGE )
651
          $Display = round(( 100 / $SerieSum ) * $Value,$Precision)."%";
652
         elseif ( $WriteValues == PIE_VALUE_NATURAL )
653
          $Display = $Value.$ValueSuffix;
654
655
         $this->pChartObject->drawText($Xc,$Yc,$Display,$Settings);
656
657
         $Offset = $EndAngle - $DataGapAngle; $ID--;
658
        }
659
      }
660
661
     if ( $DrawLabels )
662
      {
663
       $Step = 360 / (2 * PI * $Radius);
664
       $Offset = 360; $ID = count($Values)-1;
665
       foreach($Values as $Key => $Value)
666
        {
667
         if ( $LabelColor == PIE_LABEL_COLOR_AUTO )
668
          { $Settings = array("FillR"=>$Palette[$ID]["R"],"FillG"=>$Palette[$ID]["G"],"FillB"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);}
669
         else
670
          { $Settings = array("FillR"=>$LabelR,"FillG"=>$LabelG,"FillB"=>$LabelB,"Alpha"=>$LabelAlpha); }
671
672
         $EndAngle = $Offset-($Value*$ScaleFactor); if ( $EndAngle < 0 ) { $EndAngle = 0; }
673
674
         $Angle = ($EndAngle - $Offset)/2 + $Offset;
675
         $Xc = cos(($Angle-90)*PI/180) * $Radius + $X;
676
         $Yc = sin(($Angle-90)*PI/180) * $Radius*$SkewFactor + $Y - $SliceHeight;
677
678
         if ( isset($Data["Series"][$Data["Abscissa"]]["Data"][$ID]) )
679
          {
680
           $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$ID];
681
682
           if ( $LabelStacked )
683
            $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,TRUE,$X,$Y,$Radius,TRUE);
684
           else
685
            $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,FALSE);
686
          }
687
688
         $Offset = $EndAngle - $DataGapAngle; $ID--;
689
        }
690
      }
691
692
     if ( $DrawLabels && $LabelStacked ) { $this->writeShiftedLabels(); }
693
694
     $this->pChartObject->Shadow = $RestoreShadow;
695
696
     return(PIE_RENDERED);
697
    }
698
699
   /* Draw the legend of pie chart */
700
   function drawPieLegend($X,$Y,$Format="")
701
    {
702
     $FontName		= isset($Format["FontName"]) ? $Format["FontName"] : $this->pChartObject->FontName;
703
     $FontSize		= isset($Format["FontSize"]) ? $Format["FontSize"] : $this->pChartObject->FontSize;
704
     $FontR		= isset($Format["FontR"]) ? $Format["FontR"] : $this->pChartObject->FontColorR;
705
     $FontG		= isset($Format["FontG"]) ? $Format["FontG"] : $this->pChartObject->FontColorG;
706
     $FontB		= isset($Format["FontB"]) ? $Format["FontB"] : $this->pChartObject->FontColorB;
707
     $BoxSize		= isset($Format["BoxSize"]) ? $Format["BoxSize"] : 5;
708
     $Margin		= isset($Format["Margin"]) ? $Format["Margin"] : 5;
709
     $R			= isset($Format["R"]) ? $Format["R"] : 200;
710
     $G			= isset($Format["G"]) ? $Format["G"] : 200;
711
     $B			= isset($Format["B"]) ? $Format["B"] : 200;
712
     $Alpha		= isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
713
     $BorderR		= isset($Format["BorderR"]) ? $Format["BorderR"] : 255;
714
     $BorderG		= isset($Format["BorderG"]) ? $Format["BorderG"] : 255;
715
     $BorderB		= isset($Format["BorderB"]) ? $Format["BorderB"] : 255;
716
     $Surrounding	= isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
717
     $Style		= isset($Format["Style"]) ? $Format["Style"] : LEGEND_ROUND;
718
     $Mode		= isset($Format["Mode"]) ? $Format["Mode"] : LEGEND_VERTICAL;
719
720
     if ( $Surrounding != NULL ) { $BorderR = $R + $Surrounding; $BorderG = $G + $Surrounding; $BorderB = $B + $Surrounding; }
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $Surrounding of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
721
722
     $YStep = max($this->pChartObject->FontSize,$BoxSize) + 5;
723
     $XStep = $BoxSize + 5;
724
725
     /* Data Processing */
726
     $Data    = $this->pDataObject->getData();
727
     $Palette = $this->pDataObject->getPalette();
728
729
     /* Do we have an abscissa serie defined? */
730
     if ( $Data["Abscissa"] == "" ) { return(PIE_NO_ABSCISSA); }
731
732
     $Boundaries = ""; $Boundaries["L"] = $X; $Boundaries["T"] = $Y; $Boundaries["R"] = 0; $Boundaries["B"] = 0; $vY = $Y; $vX = $X;
733
     foreach($Data["Series"][$Data["Abscissa"]]["Data"] as $Key => $Value)
734
      {
735
       $BoxArray = $this->pChartObject->getTextBox($vX+$BoxSize+4,$vY+$BoxSize/2,$FontName,$FontSize,0,$Value);
736
737
       if ( $Mode == LEGEND_VERTICAL )
738
        {
739
         if ( $Boundaries["T"] > $BoxArray[2]["Y"]+$BoxSize/2 ) { $Boundaries["T"] = $BoxArray[2]["Y"]+$BoxSize/2; }
740
         if ( $Boundaries["R"] < $BoxArray[1]["X"]+2 ) { $Boundaries["R"] = $BoxArray[1]["X"]+2; }
741
         if ( $Boundaries["B"] < $BoxArray[1]["Y"]+2+$BoxSize/2 ) { $Boundaries["B"] = $BoxArray[1]["Y"]+2+$BoxSize/2; }
742
         $vY=$vY+$YStep;
743
        }
744
       elseif ( $Mode == LEGEND_HORIZONTAL )
745
        {
746
         if ( $Boundaries["T"] > $BoxArray[2]["Y"]+$BoxSize/2 ) { $Boundaries["T"] = $BoxArray[2]["Y"]+$BoxSize/2; }
747
         if ( $Boundaries["R"] < $BoxArray[1]["X"]+2 ) { $Boundaries["R"] = $BoxArray[1]["X"]+2; }
748
         if ( $Boundaries["B"] < $BoxArray[1]["Y"]+2+$BoxSize/2 ) { $Boundaries["B"] = $BoxArray[1]["Y"]+2+$BoxSize/2; }
749
         $vX=$Boundaries["R"]+$XStep;
750
        }
751
      }
752
     $vY=$vY-$YStep; $vX=$vX-$XStep;
753
754
     $TopOffset  = $Y - $Boundaries["T"];
755
     if ( $Boundaries["B"]-($vY+$BoxSize) < $TopOffset ) { $Boundaries["B"] = $vY+$BoxSize+$TopOffset; }
756
757
     if ( $Style == LEGEND_ROUND )
758
      $this->pChartObject->drawRoundedFilledRectangle($Boundaries["L"]-$Margin,$Boundaries["T"]-$Margin,$Boundaries["R"]+$Margin,$Boundaries["B"]+$Margin,$Margin,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"BorderR"=>$BorderR,"BorderG"=>$BorderG,"BorderB"=>$BorderB));
759
     elseif ( $Style == LEGEND_BOX )
760
      $this->pChartObject->drawFilledRectangle($Boundaries["L"]-$Margin,$Boundaries["T"]-$Margin,$Boundaries["R"]+$Margin,$Boundaries["B"]+$Margin,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"BorderR"=>$BorderR,"BorderG"=>$BorderG,"BorderB"=>$BorderB));
761
762
     $RestoreShadow = $this->pChartObject->Shadow; $this->pChartObject->Shadow = FALSE;
763
     foreach($Data["Series"][$Data["Abscissa"]]["Data"] as $Key => $Value)
764
      {
765
       $R = $Palette[$Key]["R"]; $G = $Palette[$Key]["G"]; $B = $Palette[$Key]["B"];
766
767
       $this->pChartObject->drawFilledRectangle($X+1,$Y+1,$X+$BoxSize+1,$Y+$BoxSize+1,array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>20));
768
       $this->pChartObject->drawFilledRectangle($X,$Y,$X+$BoxSize,$Y+$BoxSize,array("R"=>$R,"G"=>$G,"B"=>$B,"Surrounding"=>20));
769
       if ( $Mode == LEGEND_VERTICAL )
770
        {
771
         $this->pChartObject->drawText($X+$BoxSize+4,$Y+$BoxSize/2,$Value,array("R"=>$FontR,"G"=>$FontG,"B"=>$FontB,"Align"=>TEXT_ALIGN_MIDDLELEFT,"FontName"=>$FontName,"FontSize"=>$FontSize));
772
         $Y=$Y+$YStep;
773
        }
774
       elseif ( $Mode == LEGEND_HORIZONTAL )
775
        {
776
         $BoxArray = $this->pChartObject->drawText($X+$BoxSize+4,$Y+$BoxSize/2,$Value,array("R"=>$FontR,"G"=>$FontG,"B"=>$FontB,"Align"=>TEXT_ALIGN_MIDDLELEFT,"FontName"=>$FontName,"FontSize"=>$FontSize));
777
         $X=$BoxArray[1]["X"]+2+$XStep;
778
        }
779
      }
780
781
     $this->Shadow = $RestoreShadow;
782
    }
783
784
   /* Set the color of the specified slice */
785
   function setSliceColor($SliceID,$Format="")
786
    {
787
     $R		= isset($Format["R"]) ? $Format["R"] : 0;
788
     $G		= isset($Format["G"]) ? $Format["G"] : 0;
789
     $B		= isset($Format["B"]) ? $Format["B"] : 0;
790
     $Alpha	= isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
791
792
     $this->pDataObject->Palette[$SliceID]["R"]     = $R;
793
     $this->pDataObject->Palette[$SliceID]["G"]     = $G;
794
     $this->pDataObject->Palette[$SliceID]["B"]     = $B;
795
     $this->pDataObject->Palette[$SliceID]["Alpha"] = $Alpha;
796
    }
797
798
   /* Internally used compute the label positions */
799
   function writePieLabel($X,$Y,$Label,$Angle,$Settings,$Stacked,$Xc=0,$Yc=0,$Radius=0,$Reversed=FALSE)
800
    {
801
     $LabelOffset	= 30;
802
     $FontName		= $this->pChartObject->FontName;
803
     $FontSize		= $this->pChartObject->FontSize;
804
805
     if ( !$Stacked )
806
      {
807
       $Settings["Angle"]  = 360-$Angle;
808
       $Settings["Length"] = 25;
809
       $Settings["Size"]   = 8;
810
811
       $this->pChartObject->drawArrowLabel($X,$Y," ".$Label." ",$Settings);
812
      }
813
     else
814
      {
815
       $X2 = cos(deg2rad($Angle-90))*20+$X;
816
       $Y2 = sin(deg2rad($Angle-90))*20+$Y;
817
818
       $TxtPos = $this->pChartObject->getTextBox($X,$Y,$FontName,$FontSize,0,$Label);
819
       $Height = $TxtPos[0]["Y"] - $TxtPos[2]["Y"];
820
       $YTop    = $Y2 - $Height/2 - 2;
821
       $YBottom = $Y2 + $Height/2 + 2;
822
823
       if ( $this->LabelPos != "" )
824
        {
825
         $Done = FALSE;
826
         foreach($this->LabelPos as $Key => $Settings)
0 ignored issues
show
Bug introduced by
The expression $this->LabelPos of type string is not traversable.
Loading history...
827
          {
828
           if ( !$Done )
829
            {
830
             if ( $Angle <= 90 && (($YTop >= $Settings["YTop"] && $YTop <= $Settings["YBottom"]) || ($YBottom >= $Settings["YTop"] && $YBottom <= $Settings["YBottom"])))
831
              { $this->shift(0,180,-($Height+2),$Reversed); $Done = TRUE; }
832
             if ( $Angle > 90 && $Angle <= 180 && (($YTop >= $Settings["YTop"] && $YTop <= $Settings["YBottom"]) || ($YBottom >= $Settings["YTop"] && $YBottom <= $Settings["YBottom"])))
833
              { $this->shift(0,180,-($Height+2),$Reversed); $Done = TRUE; }
834
             if ( $Angle > 180 && $Angle <= 270 && (($YTop >= $Settings["YTop"] && $YTop <= $Settings["YBottom"]) || ($YBottom >= $Settings["YTop"] && $YBottom <= $Settings["YBottom"])))
835
              { $this->shift(180,360,($Height+2),$Reversed); $Done = TRUE; }
836
             if ( $Angle > 270 && $Angle <= 360 && (($YTop >= $Settings["YTop"] && $YTop <= $Settings["YBottom"]) || ($YBottom >= $Settings["YTop"] && $YBottom <= $Settings["YBottom"])))
837
              { $this->shift(180,360,($Height+2),$Reversed); $Done = TRUE; }
838
            }
839
          }
840
        }
841
842
       $LabelSettings = array("YTop"=>$YTop,"YBottom"=>$YBottom,"Label"=>$Label,"Angle"=>$Angle,"X1"=>$X,"Y1"=>$Y,"X2"=>$X2,"Y2"=>$Y2);
843
       if ( $Angle <= 180 ) { $LabelSettings["X3"] = $Xc+$Radius+$LabelOffset; }
844
       if ( $Angle > 180 )  { $LabelSettings["X3"] = $Xc-$Radius-$LabelOffset; }
845
       $this->LabelPos[] = $LabelSettings;
846
      }
847
    }
848
849
   /* Internally used to shift label positions */
850
   function shift($StartAngle,$EndAngle,$Offset,$Reversed)
851
    {
852
     if ( $Reversed ) { $Offset = -$Offset; }
853
     foreach($this->LabelPos as $Key => $Settings)
0 ignored issues
show
Bug introduced by
The expression $this->LabelPos of type string is not traversable.
Loading history...
854
      {
855
       if ( $Settings["Angle"] > $StartAngle && $Settings["Angle"] <= $EndAngle ) { $this->LabelPos[$Key]["YTop"] = $Settings["YTop"] + $Offset; $this->LabelPos[$Key]["YBottom"] = $Settings["YBottom"] + $Offset; $this->LabelPos[$Key]["Y2"] = $Settings["Y2"] + $Offset; }
856
      }
857
    }
858
859
   /* Internally used to write the re-computed labels */
860
   function writeShiftedLabels()
861
    {
862
     if ( $this->LabelPos == "" ) { return(0); }
863
     foreach($this->LabelPos as $Key => $Settings)
0 ignored issues
show
Bug introduced by
The expression $this->LabelPos of type string is not traversable.
Loading history...
864
      {
865
       $X1 = $Settings["X1"]; $Y1 = $Settings["Y1"];
866
       $X2 = $Settings["X2"]; $Y2 = $Settings["Y2"];
867
       $X3 = $Settings["X3"];
868
       $Angle = $Settings["Angle"];
869
       $Label = $Settings["Label"];
870
871
       $this->pChartObject->drawArrow($X2,$Y2,$X1,$Y1,array("Size"=>8));
872
       if ( $Angle <= 180 )
873
        {
874
         $this->pChartObject->drawLine($X2,$Y2,$X3,$Y2);
875
         $this->pChartObject->drawText($X3+2,$Y2,$Label,array("Align"=>TEXT_ALIGN_MIDDLELEFT));
876
        }
877
       else
878
        {
879
         $this->pChartObject->drawLine($X2,$Y2,$X3,$Y2);
880
         $this->pChartObject->drawText($X3-2,$Y2,$Label,array("Align"=>TEXT_ALIGN_MIDDLERIGHT));
881
        }
882
      }
883
    }
884
885
   /* Draw a ring chart */
886
   function draw2DRing($X,$Y,$Format="")
887
    {
888
     $OuterRadius	= isset($Format["Radius"]) ? $Format["Radius"] : 60;
889
     $Precision		= isset($Format["Precision"]) ? $Format["Precision"] : 0;
890
     $InnerRadius	= isset($Format["Radius"]) ? $Format["Radius"] : 30;
891
     $Border		= isset($Format["Border"]) ? $Format["Border"] : FALSE;
892
     $BorderR		= isset($Format["BorderR"]) ? $Format["BorderR"] : 255;
893
     $BorderG		= isset($Format["BorderG"]) ? $Format["BorderG"] : 255;
894
     $BorderB		= isset($Format["BorderB"]) ? $Format["BorderB"] : 255;
895
     $BorderAlpha	= isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : 100;
896
     $Shadow		= isset($Format["Shadow"]) ? $Format["Shadow"] : FALSE;
897
     $DrawLabels	= isset($Format["DrawLabels"]) ? $Format["DrawLabels"] : FALSE;
898
     $LabelStacked	= isset($Format["LabelStacked"]) ? $Format["LabelStacked"] : FALSE;
899
     $LabelColor	= isset($Format["LabelColor"]) ? $Format["LabelColor"] : PIE_LABEL_COLOR_MANUAL;
900
     $LabelR		= isset($Format["LabelR"]) ? $Format["LabelR"] : 0;
901
     $LabelG		= isset($Format["LabelG"]) ? $Format["LabelG"] : 0;
902
     $LabelB		= isset($Format["LabelB"]) ? $Format["LabelB"] : 0;
903
     $LabelAlpha	= isset($Format["LabelAlpha"]) ? $Format["LabelAlpha"] : 100;
904
     $WriteValues	= isset($Format["WriteValues"]) ? $Format["WriteValues"] : NULL; //PIE_VALUE_PERCENTAGE
905
     $ValuePadding	= isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : 5;
906
     $ValuePosition	= isset($Format["ValuePosition"]) ? $Format["ValuePosition"] : PIE_VALUE_OUTSIDE;
907
     $ValueSuffix	= isset($Format["ValueSuffix"]) ? $Format["ValueSuffix"] : "";
908
     $ValueR		= isset($Format["ValueR"]) ? $Format["ValueR"] : 255;
909
     $ValueG		= isset($Format["ValueG"]) ? $Format["ValueG"] : 255;
910
     $ValueB		= isset($Format["ValueB"]) ? $Format["ValueB"] : 255;
911
     $ValueAlpha	= isset($Format["ValueAlpha"]) ? $Format["ValueAlpha"] : 100;
912
     $RecordImageMap	= isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
913
914
     /* Data Processing */
915
     $Data    = $this->pDataObject->getData();
916
     $Palette = $this->pDataObject->getPalette();
917
918
     /* Do we have an abscissa serie defined? */
919
     if ( $Data["Abscissa"] == "" ) { return(PIE_NO_ABSCISSA); }
920
921
     /* Try to find the data serie */
922
     $DataSerie = "";
923
     foreach ($Data["Series"] as $SerieName => $SerieData)
924
      { if ( $SerieName != $Data["Abscissa"]) { $DataSerie = $SerieName; } }
925
926
     /* Do we have data to compute? */
927
     if ( $DataSerie == "" ) { return(PIE_NO_DATASERIE); }
928
929
     /* Remove unused data */
930
     list($Data,$Palette) = $this->clean0Values($Data,$Palette,$DataSerie,$Data["Abscissa"]);
931
932
     /* Compute the pie sum */
933
     $SerieSum = $this->pDataObject->getSum($DataSerie);
934
935
     /* Do we have data to draw? */
936
     if ( $SerieSum == 0 ) { return(PIE_SUMISNULL); }
937
938
     /* Dump the real number of data to draw */
939
     $Values = "";
940
     foreach ($Data["Series"][$DataSerie]["Data"] as $Key => $Value)
941
      { if ($Value != 0) { $Values[] = $Value; } }
942
943
     /* Compute the wasted angular space between series */
944
     if (count($Values)==1) { $WastedAngular = 0; } else { $WastedAngular = 0; } // count($Values)
945
946
     /* Compute the scale */
947
     $ScaleFactor = (360 - $WastedAngular) / $SerieSum;
948
949
     $RestoreShadow = $this->pChartObject->Shadow;
950
     if ( $this->pChartObject->Shadow )
951
      {
952
       $this->pChartObject->Shadow = FALSE;
953
954
       $ShadowFormat = $Format; $ShadowFormat["Shadow"] = TRUE;
955
       $this->draw2DRing($X+$this->pChartObject->ShadowX,$Y+$this->pChartObject->ShadowY,$ShadowFormat);
956
      }
957
958
     /* Draw the polygon pie elements */
959
     $Step = 360 / (2 * PI * $OuterRadius);
960
     $Offset = 0; $ID = 0;
961
     foreach($Values as $Key => $Value)
0 ignored issues
show
Bug introduced by
The expression $Values of type string is not traversable.
Loading history...
962
      {
963
       if ( $Shadow )
964
        {
965
         $Settings    = array("R"=>$this->pChartObject->ShadowR,"G"=>$this->pChartObject->ShadowG,"B"=>$this->pChartObject->ShadowB,"Alpha"=>$this->pChartObject->Shadowa);
966
         $BorderColor = $Settings;
967
        }
968
       else
969
        {
970
         if ( !isset($Palette[$ID]["R"]) ) { $Color = $this->pChartObject->getRandomColor(); $Palette[$ID] = $Color; $this->pDataObject->savePalette($ID,$Color); }
971
         $Settings = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);
972
973
         if ( $Border )
974
          $BorderColor = array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha);
975
         else
976
          $BorderColor = $Settings;
977
        }
978
979
       $Plots = ""; $Boundaries = ""; $AAPixels = "";
980
       $EndAngle = $Offset+($Value*$ScaleFactor); if ( $EndAngle > 360 ) { $EndAngle = 360; }
981
       for($i=$Offset;$i<=$EndAngle;$i=$i+$Step)
982
        {
983
         $Xc = cos(($i-90)*PI/180) * $OuterRadius + $X;
984
         $Yc = sin(($i-90)*PI/180) * $OuterRadius + $Y;
985
986
         if ( !isset($Boundaries[0]["X1"]) ) { $Boundaries[0]["X1"] = $Xc; $Boundaries[0]["Y1"] = $Yc; }
987
         $AAPixels[] = array($Xc,$Yc);
988
989
         if ( $i<90 ) { $Yc++; }
990
         if ( $i>180 && $i<270 ) { $Xc++; }
991
         if ( $i>=270 ) { $Xc++; $Yc++; }
992
993
         $Plots[] = $Xc; $Plots[] = $Yc;
994
        }
995
       $Boundaries[1]["X1"] = $Xc; $Boundaries[1]["Y1"] = $Yc;
996
       $Lasti = $EndAngle;
997
998
       for($i=$EndAngle;$i>=$Offset;$i=$i-$Step)
999
        {
1000
         $Xc = cos(($i-90)*PI/180) * ($InnerRadius-1) + $X;
1001
         $Yc = sin(($i-90)*PI/180) * ($InnerRadius-1) + $Y;
1002
1003
         if ( !isset($Boundaries[1]["X2"]) ) { $Boundaries[1]["X2"] = $Xc; $Boundaries[1]["Y2"] = $Yc; }
1004
         $AAPixels[] = array($Xc,$Yc);
1005
1006
         $Xc = cos(($i-90)*PI/180) * $InnerRadius + $X;
1007
         $Yc = sin(($i-90)*PI/180) * $InnerRadius + $Y;
1008
1009
         if ( $i<90 ) { $Yc++; }
1010
         if ( $i>180 && $i<270 ) { $Xc++; }
1011
         if ( $i>=270 ) { $Xc++; $Yc++; }
1012
1013
         $Plots[] = $Xc; $Plots[] = $Yc;
1014
        }
1015
       $Boundaries[0]["X2"] = $Xc; $Boundaries[0]["Y2"] = $Yc;
1016
1017
       /* Draw the polygon */
1018
       $this->pChartObject->drawPolygon($Plots,$Settings);
1019
       if ( $RecordImageMap && !$Shadow ) { $this->pChartObject->addToImageMap("POLY",$this->arraySerialize($Plots),$this->pChartObject->toHTMLColor($Palette[$ID]["R"],$Palette[$ID]["G"],$Palette[$ID]["B"]),$Data["Series"][$Data["Abscissa"]]["Data"][$Key],$Value); }
1020
1021
       /* Smooth the edges using AA */
1022
       foreach($AAPixels as $iKey => $Pos ) { $this->pChartObject->drawAntialiasPixel($Pos[0],$Pos[1],$BorderColor); }
0 ignored issues
show
Bug introduced by
The expression $AAPixels of type string is not traversable.
Loading history...
1023
       $this->pChartObject->drawLine($Boundaries[0]["X1"],$Boundaries[0]["Y1"],$Boundaries[0]["X2"],$Boundaries[0]["Y2"],$BorderColor);
1024
       $this->pChartObject->drawLine($Boundaries[1]["X1"],$Boundaries[1]["Y1"],$Boundaries[1]["X2"],$Boundaries[1]["Y2"],$BorderColor);
1025
1026
       if ( $DrawLabels && !$Shadow )
1027
        {
1028
         if ( $LabelColor == PIE_LABEL_COLOR_AUTO )
1029
          { $Settings = array("FillR"=>$Palette[$ID]["R"],"FillG"=>$Palette[$ID]["G"],"FillB"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);}
1030
         else
1031
          { $Settings = array("FillR"=>$LabelR,"FillG"=>$LabelG,"FillB"=>$LabelB,"Alpha"=>$LabelAlpha); }
1032
1033
         $Angle = ($EndAngle - $Offset)/2 + $Offset;
1034
         $Xc = cos(($Angle-90)*PI/180) * $OuterRadius + $X;
1035
         $Yc = sin(($Angle-90)*PI/180) * $OuterRadius + $Y;
1036
1037
         $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];
1038
1039
         if ( $LabelStacked )
1040
          $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,TRUE,$X,$Y,$OuterRadius);
1041
         else
1042
          $this->writePieLabel($Xc,$Yc,$Label,$Angle,$Settings,FALSE);
1043
        }
1044
1045
       $Offset = $Lasti; $ID++;
1046
      }
1047
1048
     if ( $DrawLabels && $LabelStacked ) { $this->writeShiftedLabels(); }
1049
1050
     if ( $WriteValues && !$Shadow )
1051
      {
1052
       $Step = 360 / (2 * PI * $OuterRadius);
1053
       $Offset = 0;
1054
       foreach($Values as $Key => $Value)
0 ignored issues
show
Bug introduced by
The expression $Values of type string is not traversable.
Loading history...
1055
        {
1056
         $EndAngle = $Offset+($Value*$ScaleFactor);
1057
         if ( $EndAngle > 360 ) { $EndAngle = 360; }
1058
1059
         $Angle = $Offset+($Value*$ScaleFactor)/2;
1060
         if ( $ValuePosition == PIE_VALUE_OUTSIDE )
1061
          {
1062
           $Xc = cos(($Angle-90)*PI/180) * ($OuterRadius+$ValuePadding) + $X;
1063
           $Yc = sin(($Angle-90)*PI/180) * ($OuterRadius+$ValuePadding) + $Y;
1064
           if ( $Angle >=0 && $Angle <= 90 ) { $Align = TEXT_ALIGN_BOTTOMLEFT; }
1065
           if ( $Angle > 90 && $Angle <= 180 ) { $Align = TEXT_ALIGN_TOPLEFT; }
1066
           if ( $Angle > 180 && $Angle <= 270 ) { $Align = TEXT_ALIGN_TOPRIGHT; }
1067
           if ( $Angle > 270 ) { $Align = TEXT_ALIGN_BOTTOMRIGHT; }
1068
          }
1069
         else
1070
          {
1071
           $Xc = cos(($Angle-90)*PI/180) * (($OuterRadius-$InnerRadius)/2+$InnerRadius) + $X;
1072
           $Yc = sin(($Angle-90)*PI/180) * (($OuterRadius-$InnerRadius)/2+$InnerRadius) + $Y;
1073
           $Align = TEXT_ALIGN_MIDDLEMIDDLE;
1074
          }
1075
1076
         if ( $WriteValues == PIE_VALUE_PERCENTAGE )
1077
          $Display = round(( 100 / $SerieSum ) * $Value,$Precision)."%";
1078
         elseif ( $WriteValues == PIE_VALUE_NATURAL )
1079
          $Display = $Value.$ValueSuffix;
1080
         else
1081
          $Label = "";
1082
1083
         $this->pChartObject->drawText($Xc,$Yc,$Display,array("Align"=>$Align,"R"=>$ValueR,"G"=>$ValueG,"B"=>$ValueB));
1084
         $Offset = $EndAngle;
1085
        }
1086
      }
1087
1088
     $this->pChartObject->Shadow = $RestoreShadow;
1089
1090
     return(PIE_RENDERED);
1091
    }
1092
1093
   /* Draw a 3D ring chart */
1094
   function draw3DRing($X,$Y,$Format="")
1095
    {
1096
     $OuterRadius	= isset($Format["OuterRadius"]) ? $Format["OuterRadius"] : 100;
1097
     $Precision		= isset($Format["Precision"]) ? $Format["Precision"] : 0;
1098
     $InnerRadius	= isset($Format["InnerRadius"]) ? $Format["InnerRadius"] : 30;
1099
     $SkewFactor	= isset($Format["SkewFactor"]) ? $Format["SkewFactor"] : .6;
1100
     $SliceHeight	= isset($Format["SliceHeight"]) ? $Format["SliceHeight"] : 10;
1101
     $DataGapAngle	= isset($Format["DataGapAngle"]) ? $Format["DataGapAngle"] : 10;
1102
     $DataGapRadius	= isset($Format["DataGapRadius"]) ? $Format["DataGapRadius"] : 10;
1103
     $Border		= isset($Format["Border"]) ? $Format["Border"] : FALSE;
1104
     $Shadow		= isset($Format["Shadow"]) ? $Format["Shadow"] : FALSE;
1105
     $DrawLabels	= isset($Format["DrawLabels"]) ? $Format["DrawLabels"] : FALSE;
1106
     $LabelStacked	= isset($Format["LabelStacked"]) ? $Format["LabelStacked"] : FALSE;
1107
     $LabelColor	= isset($Format["LabelColor"]) ? $Format["LabelColor"] : PIE_LABEL_COLOR_MANUAL;
1108
     $LabelR		= isset($Format["LabelR"]) ? $Format["LabelR"] : 0;
1109
     $LabelG		= isset($Format["LabelG"]) ? $Format["LabelG"] : 0;
1110
     $LabelB		= isset($Format["LabelB"]) ? $Format["LabelB"] : 0;
1111
     $LabelAlpha	= isset($Format["LabelAlpha"]) ? $Format["LabelAlpha"] : 100;
1112
     $Cf		= isset($Format["Cf"]) ? $Format["Cf"] : 20;
1113
     $WriteValues	= isset($Format["WriteValues"]) ? $Format["WriteValues"] : PIE_VALUE_NATURAL;
1114
     $ValuePadding	= isset($Format["ValuePadding"]) ? $Format["ValuePadding"] : $SliceHeight + 15;
1115
     $ValuePosition	= isset($Format["ValuePosition"]) ? $Format["ValuePosition"] : PIE_VALUE_OUTSIDE;
1116
     $ValueSuffix	= isset($Format["ValueSuffix"]) ? $Format["ValueSuffix"] : "";
1117
     $ValueR		= isset($Format["ValueR"]) ? $Format["ValueR"] : 255;
1118
     $ValueG		= isset($Format["ValueG"]) ? $Format["ValueG"] : 255;
1119
     $ValueB		= isset($Format["ValueB"]) ? $Format["ValueB"] : 255;
1120
     $ValueAlpha	= isset($Format["ValueAlpha"]) ? $Format["ValueAlpha"] : 100;
1121
     $RecordImageMap	= isset($Format["RecordImageMap"]) ? $Format["RecordImageMap"] : FALSE;
1122
1123
     /* Error correction for overlaying rounded corners */
1124
     if ( $SkewFactor < .5 ) { $SkewFactor = .5; }
1125
1126
     /* Data Processing */
1127
     $Data    = $this->pDataObject->getData();
1128
     $Palette = $this->pDataObject->getPalette();
1129
1130
     /* Do we have an abscissa serie defined? */
1131
     if ( $Data["Abscissa"] == "" ) { return(PIE_NO_ABSCISSA); }
1132
1133
     /* Try to find the data serie */
1134
     $DataSerie = "";
1135
     foreach ($Data["Series"] as $SerieName => $SerieData)
1136
      { if ( $SerieName != $Data["Abscissa"]) { $DataSerie = $SerieName; } }
1137
1138
     /* Do we have data to compute? */
1139
     if ( $DataSerie == "" ) { return(PIE_NO_DATASERIE); }
1140
1141
     /* Remove unused data */
1142
     list($Data,$Palette) = $this->clean0Values($Data,$Palette,$DataSerie,$Data["Abscissa"]);
1143
1144
     /* Compute the pie sum */
1145
     $SerieSum = $this->pDataObject->getSum($DataSerie);
1146
1147
     /* Do we have data to draw? */
1148
     if ( $SerieSum == 0 ) { return(PIE_SUMISNULL); }
1149
1150
     /* Dump the real number of data to draw */
1151
     $Values = "";
1152
     foreach ($Data["Series"][$DataSerie]["Data"] as $Key => $Value)
1153
      { if ($Value != 0) { $Values[] = $Value; } }
1154
1155
     /* Compute the wasted angular space between series */
1156
     if (count($Values)==1) { $WastedAngular = 0; } else { $WastedAngular = count($Values) * $DataGapAngle; }
1157
1158
     /* Compute the scale */
1159
     $ScaleFactor = (360 - $WastedAngular) / $SerieSum;
1160
1161
     $RestoreShadow = $this->pChartObject->Shadow;
1162
     if ( $this->pChartObject->Shadow ) { $this->pChartObject->Shadow = FALSE; }
1163
1164
     /* Draw the polygon ring elements */
1165
     $Offset = 360; $ID = count($Values)-1;
1166
     $Values = array_reverse($Values);
1167
     $Slice  = 0; $Slices = ""; $SliceColors = ""; $Visible = ""; $SliceAngle = "";
1168
     foreach($Values as $Key => $Value)
1169
      {
1170
       if ( !isset($Palette[$ID]["R"]) ) { $Color = $this->pChartObject->getRandomColor(); $Palette[$ID] = $Color; $this->pDataObject->savePalette($ID,$Color); }
1171
       $Settings = array("R"=>$Palette[$ID]["R"],"G"=>$Palette[$ID]["G"],"B"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);
1172
1173
       $SliceColors[$Slice] = $Settings;
1174
1175
       $StartAngle = $Offset;
1176
       $EndAngle   = $Offset-($Value*$ScaleFactor); if ( $EndAngle < 0 ) { $EndAngle = 0; }
1177
1178
       if ( $StartAngle > 180 ) { $Visible[$Slice]["Start"] = TRUE; } else { $Visible[$Slice]["Start"] = TRUE; }
1179
       if ( $EndAngle < 180 )   { $Visible[$Slice]["End"] = FALSE; } else { $Visible[$Slice]["End"] = TRUE; }
1180
1181
       $Step   = (360 / (2 * PI * $OuterRadius))/2;
1182
       $OutX1 = VOID; $OutY1 = VOID;
1183
       for($i=$Offset;$i>=$EndAngle;$i=$i-$Step)
1184
        {
1185
         $Xc = cos(($i-90)*PI/180) * ($OuterRadius+$DataGapRadius-2) + $X;
1186
         $Yc = sin(($i-90)*PI/180) * ($OuterRadius+$DataGapRadius-2)*$SkewFactor + $Y;
1187
         $Slices[$Slice]["AA"][] = array($Xc,$Yc);
1188
1189
         $Xc = cos(($i-90)*PI/180) * ($OuterRadius+$DataGapRadius-1) + $X;
1190
         $Yc = sin(($i-90)*PI/180) * ($OuterRadius+$DataGapRadius-1)*$SkewFactor + $Y;
1191
         $Slices[$Slice]["AA"][] = array($Xc,$Yc);
1192
1193
         $Xc = cos(($i-90)*PI/180) * ($OuterRadius+$DataGapRadius) + $X;
1194
         $Yc = sin(($i-90)*PI/180) * ($OuterRadius+$DataGapRadius)*$SkewFactor + $Y;
1195
         $this->pChartObject->drawAntialiasPixel($Xc,$Yc,$Settings);
1196
1197
         if ( $OutX1 == VOID ) { $OutX1 = $Xc; $OutY1 = $Yc; }
1198
1199
         if ( $i<90 ) { $Yc++; }
1200
         if ( $i>90 && $i<180 ) { $Xc++; }
1201
         if ( $i>180 && $i<270 ) { $Xc++; }
1202
         if ( $i>=270 ) { $Xc++; $Yc++; }
1203
1204
         $Slices[$Slice]["BottomPoly"][] = floor($Xc); $Slices[$Slice]["BottomPoly"][] = floor($Yc);
1205
         $Slices[$Slice]["TopPoly"][] = floor($Xc); $Slices[$Slice]["TopPoly"][] = floor($Yc)-$SliceHeight;
1206
         $Slices[$Slice]["Angle"][] = $i;
1207
        }
1208
       $OutX2 = $Xc; $OutY2 = $Yc;
1209
1210
       $Slices[$Slice]["Angle"][] = VOID;
1211
       $Lasti = $i;
1212
1213
       $Step   = (360 / (2 * PI * $InnerRadius))/2;
1214
       $InX1 = VOID; $InY1 = VOID;
1215
       for($i=$EndAngle;$i<=$Offset;$i=$i+$Step)
1216
        {
1217
         $Xc = cos(($i-90)*PI/180) * ($InnerRadius+$DataGapRadius-1) + $X;
1218
         $Yc = sin(($i-90)*PI/180) * ($InnerRadius+$DataGapRadius-1)*$SkewFactor + $Y;
1219
         $Slices[$Slice]["AA"][] = array($Xc,$Yc);
1220
1221
         $Xc = cos(($i-90)*PI/180) * ($InnerRadius+$DataGapRadius) + $X;
1222
         $Yc = sin(($i-90)*PI/180) * ($InnerRadius+$DataGapRadius)*$SkewFactor + $Y;
1223
         $Slices[$Slice]["AA"][] = array($Xc,$Yc);
1224
1225
         if ( $InX1 == VOID ) { $InX1 = $Xc; $InY1 = $Yc; }
1226
1227
         if ( $i<90 ) { $Yc++; }
1228
         if ( $i>90 && $i<180 ) { $Xc++; }
1229
         if ( $i>180 && $i<270 ) { $Xc++; }
1230
         if ( $i>=270 ) { $Xc++; $Yc++; }
1231
1232
         $Slices[$Slice]["BottomPoly"][] = floor($Xc); $Slices[$Slice]["BottomPoly"][] = floor($Yc);
1233
         $Slices[$Slice]["TopPoly"][] = floor($Xc); $Slices[$Slice]["TopPoly"][] = floor($Yc)-$SliceHeight;
1234
         $Slices[$Slice]["Angle"][] = $i;
1235
        }
1236
       $InX2 = $Xc; $InY2 = $Yc;
1237
1238
       $Slices[$Slice]["InX1"] = $InX1;   $Slices[$Slice]["InY1"] = $InY1;
1239
       $Slices[$Slice]["InX2"] = $InX2;   $Slices[$Slice]["InY2"] = $InY2;
1240
       $Slices[$Slice]["OutX1"] = $OutX1; $Slices[$Slice]["OutY1"] = $OutY1;
1241
       $Slices[$Slice]["OutX2"] = $OutX2; $Slices[$Slice]["OutY2"] = $OutY2;
1242
1243
       $Offset = $Lasti - $DataGapAngle; $ID--; $Slice++;
1244
      }
1245
1246
     /* Draw the bottom pie splice */
1247
     foreach($Slices as $SliceID => $Plots)
0 ignored issues
show
Bug introduced by
The expression $Slices of type string is not traversable.
Loading history...
1248
      {
1249
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
1250
       $this->pChartObject->drawPolygon($Plots["BottomPoly"],$Settings);
1251
1252
       foreach($Plots["AA"] as $Key => $Pos)
1253
        $this->pChartObject->drawAntialiasPixel($Pos[0],$Pos[1],$Settings);
1254
1255
       $this->pChartObject->drawLine($Plots["InX1"],$Plots["InY1"],$Plots["OutX2"],$Plots["OutY2"],$Settings);
1256
       $this->pChartObject->drawLine($Plots["InX2"],$Plots["InY2"],$Plots["OutX1"],$Plots["OutY1"],$Settings);
1257
      }
1258
1259
     $Slices      = array_reverse($Slices);
1260
     $SliceColors = array_reverse($SliceColors);
1261
1262
     /* Draw the vertical edges (semi-visible) */
1263
     foreach($Slices as $SliceID => $Plots)
1264
      {
1265
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
1266
       $Settings["R"] = $Settings["R"]+$Cf; $Settings["G"] = $Settings["G"]+$Cf; $Settings["B"] = $Settings["B"]+$Cf;
1267
1268
       $StartAngle = $Plots["Angle"][0];
1269
       foreach($Plots["Angle"] as $Key =>$Angle) { if ($Angle == VOID) { $EndAngle = $Plots["Angle"][$Key-1]; } }
1270
1271
       if ( $StartAngle >= 270 || $StartAngle <= 90 )
1272
        $this->pChartObject->drawLine($Plots["OutX1"],$Plots["OutY1"],$Plots["OutX1"],$Plots["OutY1"]-$SliceHeight,$Settings);
1273
       if ( $StartAngle >= 270 || $StartAngle <= 90 )
1274
        $this->pChartObject->drawLine($Plots["OutX2"],$Plots["OutY2"],$Plots["OutX2"],$Plots["OutY2"]-$SliceHeight,$Settings);
1275
1276
        $this->pChartObject->drawLine($Plots["InX1"],$Plots["InY1"],$Plots["InX1"],$Plots["InY1"]-$SliceHeight,$Settings);
1277
        $this->pChartObject->drawLine($Plots["InX2"],$Plots["InY2"],$Plots["InX2"],$Plots["InY2"]-$SliceHeight,$Settings);
1278
      }
1279
1280
     /* Draw the inner vertical slices */
1281
     foreach($Slices as $SliceID => $Plots)
1282
      {
1283
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
1284
       $Settings["R"] = $Settings["R"]+$Cf; $Settings["G"] = $Settings["G"]+$Cf; $Settings["B"] = $Settings["B"]+$Cf;
1285
1286
       $Outer = TRUE; $Inner = FALSE;
1287
       $InnerPlotsA = ""; $InnerPlotsB = "";
1288
       foreach($Plots["Angle"] as $ID => $Angle)
1289
        {
1290
         if ( $Angle == VOID )
1291
          { $Outer = FALSE; $Inner = TRUE; }
1292
         elseif( $Inner )
1293
          {
1294
           if (( $Angle < 90 || $Angle > 270 ) && isset($Plots["BottomPoly"][$ID*2]) )
1295
            {
1296
             $Xo = $Plots["BottomPoly"][$ID*2];
1297
             $Yo = $Plots["BottomPoly"][$ID*2+1];
1298
1299
             $InnerPlotsA[] = $Xo; $InnerPlotsA[] = $Yo;
1300
             $InnerPlotsB[] = $Xo; $InnerPlotsB[] = $Yo-$SliceHeight;
1301
            }
1302
          }
1303
        }
1304
1305
       if ( $InnerPlotsA != "" )
1306
        { $InnerPlots = array_merge($InnerPlotsA,$this->arrayReverse($InnerPlotsB)); $this->pChartObject->drawPolygon($InnerPlots,$Settings); }
1307
      }
1308
1309
     /* Draw the splice top and left poly */
1310
     foreach($Slices as $SliceID => $Plots)
1311
      {
1312
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
1313
       $Settings["R"] = $Settings["R"]+$Cf*1.5; $Settings["G"] = $Settings["G"]+$Cf*1.5; $Settings["B"] = $Settings["B"]+$Cf*1.5;
1314
1315
       $StartAngle = $Plots["Angle"][0];
1316
       foreach($Plots["Angle"] as $Key =>$Angle) { if ($Angle == VOID) { $EndAngle = $Plots["Angle"][$Key-1]; } }
1317
1318
       if ( $StartAngle < 180 )
1319
        {
1320
         $Points = "";
1321
         $Points[] = $Plots["InX2"];
1322
         $Points[] = $Plots["InY2"];
1323
         $Points[] = $Plots["InX2"];
1324
         $Points[] = $Plots["InY2"]-$SliceHeight;
1325
         $Points[] = $Plots["OutX1"];
1326
         $Points[] = $Plots["OutY1"]-$SliceHeight;
1327
         $Points[] = $Plots["OutX1"];
1328
         $Points[] = $Plots["OutY1"];
1329
1330
         $this->pChartObject->drawPolygon($Points,$Settings);
1331
        }
1332
1333
       if ( $EndAngle > 180 )
1334
        {
1335
         $Points = "";
1336
         $Points[] = $Plots["InX1"];
1337
         $Points[] = $Plots["InY1"];
1338
         $Points[] = $Plots["InX1"];
1339
         $Points[] = $Plots["InY1"]-$SliceHeight;
1340
         $Points[] = $Plots["OutX2"];
1341
         $Points[] = $Plots["OutY2"]-$SliceHeight;
1342
         $Points[] = $Plots["OutX2"];
1343
         $Points[] = $Plots["OutY2"];
1344
1345
         $this->pChartObject->drawPolygon($Points,$Settings);
1346
        }
1347
      }
1348
1349
1350
     /* Draw the vertical edges (visible) */
1351
     foreach($Slices as $SliceID => $Plots)
1352
      {
1353
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
1354
       $Settings["R"] = $Settings["R"]+$Cf; $Settings["G"] = $Settings["G"]+$Cf; $Settings["B"] = $Settings["B"]+$Cf;
1355
1356
       $StartAngle = $Plots["Angle"][0];
1357
       foreach($Plots["Angle"] as $Key =>$Angle) { if ($Angle == VOID) { $EndAngle = $Plots["Angle"][$Key-1]; } }
1358
1359
       if ( $StartAngle <= 270 && $StartAngle >= 90 )
1360
        $this->pChartObject->drawLine($Plots["OutX1"],$Plots["OutY1"],$Plots["OutX1"],$Plots["OutY1"]-$SliceHeight,$Settings);
1361
       if ( $EndAngle <= 270 && $EndAngle >= 90 )
1362
        $this->pChartObject->drawLine($Plots["OutX2"],$Plots["OutY2"],$Plots["OutX2"],$Plots["OutY2"]-$SliceHeight,$Settings);
1363
      }
1364
1365
1366
     /* Draw the outer vertical slices */
1367
     foreach($Slices as $SliceID => $Plots)
1368
      {
1369
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
1370
       $Settings["R"] = $Settings["R"]+$Cf; $Settings["G"] = $Settings["G"]+$Cf; $Settings["B"] = $Settings["B"]+$Cf;
1371
1372
       $Outer = TRUE; $Inner = FALSE;
1373
       $OuterPlotsA = ""; $OuterPlotsB = ""; $InnerPlotsA = ""; $InnerPlotsB = "";
1374
       foreach($Plots["Angle"] as $ID => $Angle)
1375
        {
1376
         if ( $Angle == VOID )
1377
          { $Outer = FALSE; $Inner = TRUE; }
1378
         elseif( $Outer )
1379
          {
1380
           if ( ( $Angle > 90 && $Angle < 270 ) && isset($Plots["BottomPoly"][$ID*2]) )
1381
            {
1382
             $Xo = $Plots["BottomPoly"][$ID*2];
1383
             $Yo = $Plots["BottomPoly"][$ID*2+1];
1384
1385
             $OuterPlotsA[] = $Xo; $OuterPlotsA[] = $Yo;
1386
             $OuterPlotsB[] = $Xo; $OuterPlotsB[] = $Yo-$SliceHeight;
1387
            }
1388
          }
1389
        }
1390
       if ( $OuterPlotsA != "" )
1391
        { $OuterPlots = array_merge($OuterPlotsA,$this->arrayReverse($OuterPlotsB)); $this->pChartObject->drawPolygon($OuterPlots,$Settings); }
1392
      }
1393
1394
     $Slices      = array_reverse($Slices);
1395
     $SliceColors = array_reverse($SliceColors);
1396
1397
1398
     /* Draw the top pie splice */
1399
     foreach($Slices as $SliceID => $Plots)
1400
      {
1401
       $Settings = $SliceColors[$SliceID];  $Settings["NoBorder"] = TRUE;
1402
       $Settings["R"] = $Settings["R"]+$Cf*2; $Settings["G"] = $Settings["G"]+$Cf*2; $Settings["B"] = $Settings["B"]+$Cf*2;
1403
 
1404
       $this->pChartObject->drawPolygon($Plots["TopPoly"],$Settings);
1405
1406
       if ( $RecordImageMap ) { $this->pChartObject->addToImageMap("POLY",$this->arraySerialize($Plots["TopPoly"]),$this->pChartObject->toHTMLColor($Settings["R"],$Settings["G"],$Settings["B"]),$Data["Series"][$Data["Abscissa"]]["Data"][$SliceID],$Data["Series"][$DataSerie]["Data"][count($Slices)-$SliceID-1]); }
1407
1408
       foreach($Plots["AA"] as $Key => $Pos)
1409
        $this->pChartObject->drawAntialiasPixel($Pos[0],$Pos[1]-$SliceHeight,$Settings);
1410
1411
       $this->pChartObject->drawLine($Plots["InX1"],$Plots["InY1"]-$SliceHeight,$Plots["OutX2"],$Plots["OutY2"]-$SliceHeight,$Settings);
1412
       $this->pChartObject->drawLine($Plots["InX2"],$Plots["InY2"]-$SliceHeight,$Plots["OutX1"],$Plots["OutY1"]-$SliceHeight,$Settings);
1413
      }
1414
1415
     if ( $DrawLabels )
1416
      {
1417
       $Offset = 360;
1418
       foreach($Values as $Key => $Value)
1419
        {
1420
         $StartAngle = $Offset;
1421
         $EndAngle   = $Offset-($Value*$ScaleFactor); if ( $EndAngle < 0 ) { $EndAngle = 0; }
1422
1423
         if ( $LabelColor == PIE_LABEL_COLOR_AUTO )
1424
          { $Settings = array("FillR"=>$Palette[$ID]["R"],"FillG"=>$Palette[$ID]["G"],"FillB"=>$Palette[$ID]["B"],"Alpha"=>$Palette[$ID]["Alpha"]);}
1425
         else
1426
          { $Settings = array("FillR"=>$LabelR,"FillG"=>$LabelG,"FillB"=>$LabelB,"Alpha"=>$LabelAlpha); }
1427
1428
         $Angle = ($EndAngle - $Offset)/2 + $Offset;
1429
         $Xc = cos(($Angle-90)*PI/180) * ($OuterRadius+$DataGapRadius) + $X;
1430
         $Yc = sin(($Angle-90)*PI/180) * ($OuterRadius+$DataGapRadius)*$SkewFactor + $Y;
1431
1432
         if ( $WriteValues == PIE_VALUE_PERCENTAGE )
1433
          $Label = $Display = round(( 100 / $SerieSum ) * $Value,$Precision)."%";
1434
         elseif ( $WriteValues == PIE_VALUE_NATURAL )
1435
          $Label = $Data["Series"][$Data["Abscissa"]]["Data"][$Key];
1436
         else
1437
          $Label = "";
1438
1439
         if ( $LabelStacked )
1440
          $this->writePieLabel($Xc,$Yc-$SliceHeight,$Label,$Angle,$Settings,TRUE,$X,$Y,$OuterRadius);
1441
         else
1442
          $this->writePieLabel($Xc,$Yc-$SliceHeight,$Label,$Angle,$Settings,FALSE);
1443
1444
         $Offset = $EndAngle - $DataGapAngle; $ID--; $Slice++;
1445
        }
1446
      }
1447
     if ( $DrawLabels && $LabelStacked ) { $this->writeShiftedLabels(); }
1448
1449
     $this->pChartObject->Shadow = $RestoreShadow;
1450
1451
     return(PIE_RENDERED);
1452
    }
1453
1454
  /* Serialize an array */
1455
  function arraySerialize($Data)
1456
   {
1457
    $Result = "";
1458
    foreach($Data as $Key => $Value)
1459
     { if ($Result == "") { $Result = floor($Value); } else { $Result = $Result.",".floor($Value); } }
1460
1461
    return($Result);
1462
   }
1463
1464
  /* Reverse an array */
1465
  function arrayReverse($Plots)
1466
   {
1467
    $Result = "";
1468
1469
    for($i=count($Plots)-1;$i>=0;$i=$i-2)
1470
     { $Result[] = $Plots[$i-1]; $Result[] = $Plots[$i]; }
1471
1472
    return($Result);
1473
   }
1474
1475
  /* Remove unused series & values */
1476
  function clean0Values($Data,$Palette,$DataSerie,$AbscissaSerie)
1477
   {
1478
    $NewPalette = ""; $NewData = ""; $NewAbscissa = "";
1479
1480
    /* Remove unused series */
1481
    foreach($Data["Series"] as $SerieName => $SerieSettings)
1482
     { if ( $SerieName != $DataSerie && $SerieName != $AbscissaSerie ) { unset($Data["Series"][$SerieName]); } }
1483
1484
    /* Remove NULL values */
1485
    foreach($Data["Series"][$DataSerie]["Data"] as $Key => $Value)
1486
     {
1487
      if ($Value != 0 )
1488
       {
1489
        $NewData[]     = $Value;
1490
        $NewAbscissa[] = $Data["Series"][$AbscissaSerie]["Data"][$Key];
1491
        if ( isset($Palette[$Key]) ) { $NewPalette[]  = $Palette[$Key]; }
1492
       }
1493
     }
1494
    $Data["Series"][$DataSerie]["Data"]     = $NewData;
1495
    $Data["Series"][$AbscissaSerie]["Data"] = $NewAbscissa;
1496
1497
    return(array($Data,$NewPalette));
1498
   }
1499
  }
1500
?>