PiePlot::Legend()   F
last analyzed

Complexity

Conditions 14
Paths 800

Size

Total Lines 67
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 16.8436

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 45
nc 800
nop 1
dl 0
loc 67
ccs 31
cts 41
cp 0.7561
crap 16.8436
rs 2.3777
c 1
b 0
f 0

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
/**
4
 * JPGraph v4.0.3
5
 */
6
7
namespace Amenadiel\JpGraph\Plot;
8
9
use Amenadiel\JpGraph\Graph;
10
use Amenadiel\JpGraph\Text;
11
use Amenadiel\JpGraph\Util;
12
13
/*
14
 * File:        JPGRAPH_PIE.PHP
15
 * // Description: Pie plot extension for JpGraph
16
 * // Created:     2001-02-14
17
 * // Ver:         $Id: jpgraph_pie.php 1926 2010-01-11 16:33:07Z ljp $
18
 * //
19
 * // Copyright (c) Asial Corporation. All rights reserved.
20
 */
21
// Defines for PiePlot::SetLabelType()
22 1
define('PIE_VALUE_ABS', 1);
23 1
define('PIE_VALUE_PER', 0);
24 1
define('PIE_VALUE_PERCENTAGE', 0);
25 1
define('PIE_VALUE_ADJPERCENTAGE', 2);
26 1
define('PIE_VALUE_ADJPER', 2);
27
28
/**
29
 * @class PiePlot
30
 * // Description: Draws a pie plot
31
 */
32
class PiePlot
33
{
34
    public $posx                     = 0.5;
35
    public $posy                     = 0.5;
36
    public $is_using_plot_theme      = false;
37
    public $theme                    = 'earth';
38
    protected $use_plot_theme_colors = false;
39
    protected $radius                = 0.3;
40
    protected $explode_radius        = [];
41
    protected $explode_all           = false;
42
    protected $explode_r             = 20;
43
    protected $labels;
44
    protected $legends;
45
    protected $csimtargets;
46
    protected $csimwintargets; // Array of targets for CSIM
47
    protected $csimareas = ''; // Generated CSIM text
48
    protected $csimalts; // ALT tags for corresponding target
49
    protected $data;
50
    public $title;
51
    protected $startangle    = 0;
52
    protected $weight        = 1;
53
    protected $color         = 'black';
54
    protected $legend_margin = 6;
55
    protected $show_labels   = true;
56
    protected $themearr      = [
57
        'earth'  => [136, 34, 40, 45, 46, 62, 63, 134, 74, 10, 120, 136, 141, 168, 180, 77, 209, 218, 346, 395, 89, 430],
58
        'pastel' => [27, 415, 128, 59, 66, 79, 105, 110, 42, 147, 152, 230, 236, 240, 331, 337, 405, 38],
59
        'water'  => [8, 370, 24, 40, 335, 56, 213, 237, 268, 14, 326, 387, 10, 388],
60
        'sand'   => [27, 168, 34, 170, 19, 50, 65, 72, 131, 209, 46, 393], ];
61
    protected $setslicecolors      = [];
62
    protected $labeltype           = 0; // Default to percentage
63
    protected $pie_border          = true;
64
    protected $pie_interior_border = true;
65
    public $value;
66
    protected $ishadowcolor         = '';
67
    protected $ishadowdrop          = 4;
68
    protected $ilabelposadj         = 1;
69
    protected $legendcsimtargets    = [];
70
    protected $legendcsimwintargets = [];
71
    protected $legendcsimalts       = [];
72
    protected $adjusted_data        = [];
73
    public $guideline;
74
    protected $guidelinemargin         = 10;
75
    protected $iShowGuideLineForSingle = false;
76
    protected $iGuideLineCurve         = false;
77
    protected $iGuideVFactor           = 1.4;
78
    protected $iGuideLineRFactor       = 0.8;
79
    protected $la                      = []; // Holds the exact angle for each label
80
81
    /**
82
     * CONSTRUCTOR.
83
     *
84
     * @param mixed $data
85
     */
86 3
    public function __construct($data)
87
    {
88 3
        $this->data  = array_reverse($data);
89 3
        $this->title = new Text\Text('');
90 3
        $this->title->SetFont(FF_DEFAULT, FS_BOLD);
91 3
        $this->value = new DisplayValue();
92 3
        $this->value->Show();
93 3
        $this->value->SetFormat('%.1f%%');
94 3
        $this->guideline = new Graph\LineProperty();
95 3
    }
96
97
    /**
98
     * PUBLIC METHODS.
99
     *
100
     * @param mixed $x
101
     * @param mixed $y
102
     */
103 3
    public function SetCenter($x, $y = 0.5)
104
    {
105 3
        $this->posx = $x;
106 3
        $this->posy = $y;
107 3
    }
108
109
    // Enable guideline and set drwaing policy
110 1
    public function SetGuideLines($aFlg = true, $aCurved = true, $aAlways = false)
111
    {
112 1
        $this->guideline->Show($aFlg);
113 1
        $this->iShowGuideLineForSingle = $aAlways;
114 1
        $this->iGuideLineCurve         = $aCurved;
115 1
    }
116
117
    // Adjuste the distance between labels and labels and pie
118 1
    public function SetGuideLinesAdjust($aVFactor, $aRFactor = 0.8)
119
    {
120 1
        $this->iGuideVFactor     = $aVFactor;
121 1
        $this->iGuideLineRFactor = $aRFactor;
122 1
    }
123
124
    public function SetColor($aColor)
125
    {
126
        $this->color = $aColor;
127
    }
128
129
    public function SetSliceColors($aColors)
130
    {
131
        $this->setslicecolors = $aColors;
132
    }
133
134 1
    public function SetShadow($aColor = 'darkgray', $aDropWidth = 4)
135
    {
136 1
        $this->ishadowcolor = $aColor;
137 1
        $this->ishadowdrop  = $aDropWidth;
138 1
    }
139
140
    public function SetCSIMTargets($aTargets, $aAlts = '', $aWinTargets = '')
141
    {
142
        $this->csimtargets = array_reverse($aTargets);
143
        if (is_array($aWinTargets)) {
144
            $this->csimwintargets = array_reverse($aWinTargets);
145
        }
146
147
        if (is_array($aAlts)) {
148
            $this->csimalts = array_reverse($aAlts);
149
        }
150
    }
151
152
    public function GetCSIMareas()
153
    {
154
        return $this->csimareas;
155
    }
156
157
    public function AddSliceToCSIM($i, $xc, $yc, $radius, $sa, $ea)
158
    {
159
        //Slice number, ellipse centre (x,y), height, width, start angle, end angle
160
        while ($sa > 2 * M_PI) {
161
            $sa = $sa - 2 * M_PI;
162
        }
163
164
        while ($ea > 2 * M_PI) {
165
            $ea = $ea - 2 * M_PI;
166
        }
167
168
        $sa = 2 * M_PI - $sa;
169
        $ea = 2 * M_PI - $ea;
170
171
        // Special case when we have only one slice since then both start and end
172
        // angle will be == 0
173
        if (abs($sa - $ea) < 0.0001) {
174
            $sa = 2 * M_PI;
175
            $ea = 0;
176
        }
177
178
        //add coordinates of the centre to the map
179
        $xc     = floor($xc);
180
        $yc     = floor($yc);
181
        $coords = "${xc}, ${yc}";
182
183
        //add coordinates of the first point on the arc to the map
184
        $xp = floor(($radius * cos($ea)) + $xc);
185
        $yp = floor($yc - $radius * sin($ea));
186
        $coords .= ", ${xp}, ${yp}";
187
188
        //add coordinates every 0.2 radians
189
        $a = $ea + 0.2;
190
191
        // If we cross the 360-limit with a slice we need to handle
192
        // the fact that end angle is smaller than start
193
        if ($sa < $ea) {
194
            while ($a <= 2 * M_PI) {
195
                $xp = floor($radius * cos($a) + $xc);
196
                $yp = floor($yc - $radius * sin($a));
197
                $coords .= ", ${xp}, ${yp}";
198
                $a += 0.2;
199
            }
200
            $a -= 2 * M_PI;
201
        }
202
203
        while ($a < $sa) {
204
            $xp = floor($radius * cos($a) + $xc);
205
            $yp = floor($yc - $radius * sin($a));
206
            $coords .= ", ${xp}, ${yp}";
207
            $a += 0.2;
208
        }
209
210
        //Add the last point on the arc
211
        $xp = floor($radius * cos($sa) + $xc);
212
        $yp = floor($yc - $radius * sin($sa));
213
        $coords .= ", ${xp}, ${yp}";
214
        if (!empty($this->csimtargets[$i])) {
215
            $this->csimareas .= "<area shape=\"poly\" coords=\"${coords}\" href=\"" . $this->csimtargets[$i] . '"';
216
            $tmp = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $tmp is dead and can be removed.
Loading history...
217
            if (!empty($this->csimwintargets[$i])) {
218
                $this->csimareas .= ' target="' . $this->csimwintargets[$i] . '" ';
219
            }
220
            if (!empty($this->csimalts[$i])) {
221
                $tmp = sprintf($this->csimalts[$i], $this->data[$i]);
222
                $this->csimareas .= " title=\"${tmp}\" alt=\"${tmp}\" ";
223
            }
224
            $this->csimareas .= " />\n";
225
        }
226
    }
227
228 3
    public function SetTheme($aTheme)
229
    {
230
        //        Util\JpGraphError::RaiseL(15012,$aTheme);
231
        //        return;
232
233 3
        if (in_array($aTheme, array_keys($this->themearr), true)) {
234 3
            $this->theme               = $aTheme;
235 3
            $this->is_using_plot_theme = true;
236
        } else {
237
            Util\JpGraphError::RaiseL(15001, $aTheme); //("PiePLot::SetTheme() Unknown theme: $aTheme");
238
        }
239 3
    }
240
241 3
    public function ExplodeSlice($e, $radius = 20)
242
    {
243 3
        if (!is_integer($e)) {
244
            Util\JpGraphError::RaiseL(15002);
245
        }
246
        //('Argument to PiePlot::ExplodeSlice() must be an integer');
247 3
        $this->explode_radius[$e] = $radius;
248 3
    }
249
250 1
    public function ExplodeAll($radius = 20)
251
    {
252 1
        $this->explode_all = true;
253 1
        $this->explode_r   = $radius;
254 1
    }
255
256 2
    public function Explode($aExplodeArr)
257
    {
258 2
        if (!is_array($aExplodeArr)) {
259
            Util\JpGraphError::RaiseL(15003);
260
            //("Argument to PiePlot::Explode() must be an array with integer distances.");
261
        }
262 2
        $this->explode_radius = $aExplodeArr;
263 2
    }
264
265
    public function SetStartAngle($aStart)
266
    {
267
        if ($aStart < 0 || $aStart > 360) {
268
            Util\JpGraphError::RaiseL(15004); //('Slice start angle must be between 0 and 360 degrees.');
269
        }
270
        if ($aStart == 0) {
271
            $this->startangle = 0;
272
        } else {
273
            $this->startangle = 360 - $aStart;
274
            $this->startangle *= M_PI / 180;
275
        }
276
    }
277
278
    // Size in percentage
279 3
    public function SetSize($aSize)
280
    {
281 3
        if (($aSize > 0 && $aSize <= 0.5) || ($aSize > 10 && $aSize < 1000)) {
282 3
            $this->radius = $aSize;
283
        } else {
284
            Util\JpGraphError::RaiseL(15006);
285
        }
286
287
        //("PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels  in the range [10, 1000]");
288 3
    }
289
290
    // Set label arrays
291 2
    public function SetLegends($aLegend)
292
    {
293 2
        $this->legends = $aLegend;
294 2
    }
295
296
    // Set text labels for slices
297 1
    public function SetLabels($aLabels, $aLblPosAdj = 'auto')
298
    {
299 1
        $this->labels       = array_reverse($aLabels);
300 1
        $this->ilabelposadj = $aLblPosAdj;
301 1
    }
302
303 2
    public function SetLabelPos($aLblPosAdj)
304
    {
305 2
        $this->ilabelposadj = $aLblPosAdj;
306 2
    }
307
308
    // Should we display actual value or percentage?
309 2
    public function SetLabelType($aType)
310
    {
311 2
        if ($aType < 0 || $aType > 2) {
312
            Util\JpGraphError::RaiseL(15008, $aType);
313
        }
314
315
        //("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t).");
316 2
        $this->labeltype = $aType;
317 2
    }
318
319
    // Deprecated.
320
    public function SetValueType($aType)
321
    {
322
        $this->SetLabelType($aType);
323
    }
324
325
    // Should the circle around a pie plot be displayed
326 1
    public function ShowBorder($exterior = true, $interior = true)
327
    {
328 1
        $this->pie_border          = $exterior;
329 1
        $this->pie_interior_border = $interior;
330 1
    }
331
332
    // Setup the legends
333 3
    public function Legend($graph)
334
    {
335 3
        $colors = array_keys($graph->img->rgb->rgb_table);
336 3
        sort($colors);
337 3
        $ta = $this->themearr[$this->theme];
338 3
        $n  = safe_count($this->data);
339
340 3
        if ($this->setslicecolors == null) {
341 3
            $numcolors = safe_count($ta);
342 3
            if (($this instanceof PiePlot3D)) {
343 3
                $ta = array_reverse(array_slice($ta, 0, $n));
344
            }
345
        } else {
346
            $this->setslicecolors = array_slice($this->setslicecolors, 0, $n);
347
            $numcolors            = safe_count($this->setslicecolors);
348
            if ($graph->pieaa && !($this instanceof PiePlot3D)) {
349
                $this->setslicecolors = array_reverse($this->setslicecolors);
350
            }
351
        }
352
353 3
        $sum = 0;
354 3
        for ($i = 0; $i < $n; ++$i) {
355 3
            $sum += $this->data[$i];
356
        }
357
358
        // Bail out with error if the sum is 0
359 3
        if ($sum == 0) {
0 ignored issues
show
introduced by
The condition $sum == 0 is always true.
Loading history...
360
            Util\JpGraphError::RaiseL(15009);
361
        }
362
        //("Illegal pie plot. Sum of all data is zero for Pie!");
363
364
        // Make sure we don't plot more values than data points
365
        // (in case the user added more legends than data points)
366 3
        $n = min(safe_count($this->legends), safe_count($this->data));
367 3
        if ($this->legends != '') {
368 3
            $this->legends = array_reverse(array_slice($this->legends, 0, $n));
369
        }
370 3
        for ($i = $n - 1; $i >= 0; --$i) {
371 3
            $l = $this->legends[$i];
372
            // Replace possible format with actual values
373 3
            if (safe_count($this->csimalts) > $i) {
374
                $fmt = $this->csimalts[$i];
375
            } else {
376 3
                $fmt = '%d'; // Deafult Alt if no other has been specified
377
            }
378 3
            if ($this->labeltype == 0) {
379 3
                $l   = sprintf($l, 100 * $this->data[$i] / $sum);
380 3
                $alt = sprintf($fmt, $this->data[$i]);
381 1
            } elseif ($this->labeltype == 1) {
382 1
                $l   = sprintf($l, $this->data[$i]);
383 1
                $alt = sprintf($fmt, $this->data[$i]);
384
            } else {
385
                $l   = sprintf($l, $this->adjusted_data[$i]);
386
                $alt = sprintf($fmt, $this->adjusted_data[$i]);
387
            }
388
389 3
            if (empty($this->csimwintargets[$i])) {
390 3
                $wintarg = '';
391
            } else {
392
                $wintarg = $this->csimwintargets[$i];
393
            }
394
395 3
            $imageMapTarget = $this->csimtargets[$i] ?? '';
396 3
            if ($this->setslicecolors == null) {
397 3
                $graph->legend->Add($l, $colors[$ta[$i % $numcolors]], '', 0, $imageMapTarget, $alt, $wintarg);
398
            } else {
399
                $graph->legend->Add($l, $this->setslicecolors[$i % $numcolors], '', 0, $imageMapTarget, $alt, $wintarg);
400
            }
401
        }
402 3
    }
403
404
    // Adjust the rounded percetage value so that the sum of
405
    // of the pie slices are always 100%
406
    // Using the Hare/Niemeyer method
407
    public function AdjPercentage($aData, $aPrec = 0)
408
    {
409
        $mul = 100;
410
        if ($aPrec > 0 && $aPrec < 3) {
411
            if ($aPrec == 1) {
412
                $mul = 1000;
413
            } else {
414
                $mul = 10000;
415
            }
416
        }
417
418
        $tmp       = [];
419
        $result    = [];
420
        $quote_sum = 0;
421
        $n         = safe_count($aData);
422
        for ($i = 0, $sum = 0; $i < $n; ++$i) {
423
            $sum += $aData[$i];
424
        }
425
426
        foreach ($aData as $index => $value) {
427
            $tmp_percentage = $value / $sum * $mul;
428
            $result[$index] = floor($tmp_percentage);
429
            $tmp[$index]    = $tmp_percentage - $result[$index];
430
            $quote_sum += $result[$index];
431
        }
432
        if ($quote_sum == $mul) {
433
            if ($mul > 100) {
434
                $tmp = $mul / 100;
435
                for ($i = 0; $i < $n; ++$i) {
436
                    $result[$i] /= $tmp;
437
                }
438
            }
439
440
            return $result;
441
        }
442
        arsort($tmp, SORT_NUMERIC);
443
        reset($tmp);
444
        for ($i = 0; $i < $mul - $quote_sum; ++$i) {
445
            ++$result[key($tmp)];
446
            next($tmp);
447
        }
448
        if ($mul > 100) {
449
            $tmp = $mul / 100;
450
            for ($i = 0; $i < $n; ++$i) {
451
                $result[$i] /= $tmp;
452
            }
453
        }
454
455
        return $result;
456
    }
457
458 3
    public function Stroke($img, $aaoption = 0)
459
    {
460
        // aaoption is used to handle antialias
461
        // aaoption == 0 a normal pie
462
        // aaoption == 1 just the body
463
        // aaoption == 2 just the values
464
465
        // Explode scaling. If anti alias we scale the image
466
        // twice and we also need to scale the exploding distance
467 3
        $expscale = $aaoption === 1 ? 2 : 1;
468
469 3
        if ($this->labeltype == 2) {
470
            // Adjust the data so that it will add up to 100%
471
            $this->adjusted_data = $this->AdjPercentage($this->data);
472
        }
473
474 3
        if ($this->use_plot_theme_colors) {
475 2
            $this->setslicecolors = null;
476
        }
477
478 3
        $colors = array_keys($img->rgb->rgb_table);
479 3
        sort($colors);
480 3
        $ta = $this->themearr[$this->theme];
481 3
        $n  = safe_count($this->data);
482
483 3
        if ($this->setslicecolors == null) {
484 3
            $numcolors = safe_count($ta);
485
        } else {
486
            // We need to create an array of colors as long as the data
487
            // since we need to reverse it to get the colors in the right order
488
            $numcolors = safe_count($this->setslicecolors);
489
            $i         = 2 * $numcolors;
490
            while ($n > $i) {
491
                $this->setslicecolors = array_merge($this->setslicecolors, $this->setslicecolors);
492
                $i += $n;
493
            }
494
            $tt                   = array_slice($this->setslicecolors, 0, $n % $numcolors);
495
            $this->setslicecolors = array_merge($this->setslicecolors, $tt);
496
            $this->setslicecolors = array_reverse($this->setslicecolors);
497
        }
498
499
        // Draw the slices
500 3
        $sum = 0;
501 3
        for ($i = 0; $i < $n; ++$i) {
502 3
            $sum += $this->data[$i];
503
        }
504
505
        // Bail out with error if the sum is 0
506 3
        if ($sum == 0) {
0 ignored issues
show
introduced by
The condition $sum == 0 is always true.
Loading history...
507
            Util\JpGraphError::RaiseL(15009); //("Sum of all data is 0 for Pie.");
508
        }
509
510
        // Set up the pie-circle
511 3
        if ($this->radius <= 1) {
512 3
            $radius = floor($this->radius * min($img->width, $img->height));
513
        } else {
514
            $radius = $aaoption === 1 ? $this->radius * 2 : $this->radius;
515
        }
516
517 3
        if ($this->posx <= 1 && $this->posx > 0) {
518 3
            $xc = round($this->posx * $img->width);
519
        } else {
520
            $xc = $this->posx;
521
        }
522
523 3
        if ($this->posy <= 1 && $this->posy > 0) {
524 3
            $yc = round($this->posy * $img->height);
525
        } else {
526
            $yc = $this->posy;
527
        }
528
529 3
        $n = safe_count($this->data);
530
531 3
        if ($this->explode_all) {
532 1
            for ($i = 0; $i < $n; ++$i) {
533 1
                $this->explode_radius[$i] = $this->explode_r;
534
            }
535
        }
536
537
        // If we have a shadow and not just drawing the labels
538 3
        if ($this->ishadowcolor != '' && $aaoption !== 2) {
539 1
            $accsum = 0;
540 1
            $angle2 = $this->startangle;
541 1
            $img->SetColor($this->ishadowcolor);
542 1
            for ($i = 0; $sum > 0 && $i < $n; ++$i) {
543 1
                $j      = $n - $i - 1;
544 1
                $d      = $this->data[$i];
545 1
                $angle1 = $angle2;
546 1
                $accsum += $d;
547 1
                $angle2 = $this->startangle + 2 * M_PI * $accsum / $sum;
548 1
                if (empty($this->explode_radius[$j])) {
549
                    $this->explode_radius[$j] = 0;
550
                }
551
552 1
                if ($d < 0.00001) {
553
                    continue;
554
                }
555
556 1
                $la = 2 * M_PI - (abs($angle2 - $angle1) / 2.0 + $angle1);
557
558 1
                $xcm = $xc + $this->explode_radius[$j] * cos($la) * $expscale;
559 1
                $ycm = $yc - $this->explode_radius[$j] * sin($la) * $expscale;
560
561 1
                $xcm += $this->ishadowdrop * $expscale;
562 1
                $ycm += $this->ishadowdrop * $expscale;
563
564 1
                $_sa = round($angle1 * 180 / M_PI);
565 1
                $_ea = round($angle2 * 180 / M_PI);
566
567
                // The CakeSlice method draws a full circle in case of start angle = end angle
568
                // for pie slices we don't want this behaviour unless we only have one
569
                // slice in the pie in case it is the wanted behaviour
570 1
                if ($_ea - $_sa > 0.1 || $n == 1) {
571 1
                    $img->CakeSlice(
572 1
                        $xcm,
573 1
                        $ycm,
574 1
                        $radius - 1,
575 1
                        $radius - 1,
576 1
                        $angle1 * 180 / M_PI,
577 1
                        $angle2 * 180 / M_PI,
578 1
                        $this->ishadowcolor
579
                    );
580
                }
581
            }
582
        }
583
584
        /**
585
         * This is the main loop to draw each cake slice.
586
         */
587
        // Set up the accumulated sum, start angle for first slice and border color
588 3
        $accsum = 0;
589 3
        $angle2 = $this->startangle;
590 3
        $img->SetColor($this->color);
591
592
        // Loop though all the slices if there is a pie to draw (sum>0)
593
        // There are n slices in total
594 3
        for ($i = 0; $sum > 0 && $i < $n; ++$i) {
595
            // $j is the actual index used for the slice
596 3
            $j = $n - $i - 1;
597
598
            // Make sure we havea  valid distance to explode the slice
599 3
            if (empty($this->explode_radius[$j])) {
600 3
                $this->explode_radius[$j] = 0;
601
            }
602
603
            // The actual numeric value for the slice
604 3
            $d = $this->data[$i];
605
606 3
            $angle1 = $angle2;
607
608
            // Accumlate the sum
609 3
            $accsum += $d;
610
611
            // The new angle when we add the "size" of this slice
612
            // angle1 is then the start and angle2 the end of this slice
613 3
            $angle2 = $this->NormAngle($this->startangle + 2 * M_PI * $accsum / $sum);
614
615
            // We avoid some trouble by not allowing end angle to be 0, in that case
616
            // we translate to 360
617
618
            // la is used to hold the label angle, which is centered on the slice
619 3
            if ($angle2 < 0.0001 && $angle1 > 0.0001) {
620 1
                $this->la[$i] = 2 * M_PI - (abs(2 * M_PI - $angle1) / 2.0 + $angle1);
621 3
            } elseif ($angle1 > $angle2) {
622
                // The case where the slice crosses the 3 a'clock line
623
                // Remember that the slices are counted clockwise and
624
                // labels are counted counter clockwise so we need to revert with 2 PI
625
                $this->la[$i] = 2 * M_PI - $this->NormAngle($angle1 + ((2 * M_PI - $angle1) + $angle2) / 2);
626
            } else {
627 3
                $this->la[$i] = 2 * M_PI - (abs($angle2 - $angle1) / 2.0 + $angle1);
628
            }
629
630
            // Too avoid rounding problems we skip the slice if it is too small
631 3
            if ($d < 0.00001) {
632 1
                continue;
633
            }
634
635
            // If the user has specified an array of colors for each slice then use
636
            // that a color otherwise use the theme array (ta) of colors
637 3
            if ($this->setslicecolors == null) {
638 3
                $slicecolor = $colors[$ta[$i % $numcolors]];
639
            } else {
640
                $slicecolor = $this->setslicecolors[$i % $numcolors];
641
            }
642
643
            //            $_sa = round($angle1*180/M_PI);
644
            //            $_ea = round($angle2*180/M_PI);
645
            //            $_la = round($this->la[$i]*180/M_PI);
646
            //            echo "Slice#$i: ang1=$_sa , ang2=$_ea, la=$_la, color=$slicecolor<br>";
647
648
            // If we have enabled antialias then we don't draw any border so
649
            // make the bordedr color the same as the slice color
650 3
            if ($this->pie_interior_border && $aaoption === 0) {
651
                $img->SetColor($this->color);
652
            } else {
653 3
                $img->SetColor($slicecolor);
654
            }
655 3
            $arccolor = $this->pie_border && $aaoption === 0 ? $this->color : '';
656
657
            // Calculate the x,y coordinates for the base of this slice taking
658
            // the exploded distance into account. Here we use the mid angle as the
659
            // ray of extension and we have the mid angle handy as it is also the
660
            // label angle
661 3
            $xcm = $xc + $this->explode_radius[$j] * cos($this->la[$i]) * $expscale;
662 3
            $ycm = $yc - $this->explode_radius[$j] * sin($this->la[$i]) * $expscale;
663
664
            // If we are not just drawing the labels then draw this cake slice
665 3
            if ($aaoption !== 2) {
666 3
                $_sa = round($angle1 * 180 / M_PI);
667 3
                $_ea = round($angle2 * 180 / M_PI);
668 3
                $_la = round($this->la[$i] * 180 / M_PI);
0 ignored issues
show
Unused Code introduced by
The assignment to $_la is dead and can be removed.
Loading history...
669
                //echo "[$i] sa=$_sa, ea=$_ea, la[$i]=$_la, (color=$slicecolor)<br>";
670
671
                // The CakeSlice method draws a full circle in case of start angle = end angle
672
                // for pie slices we want this in case the slice have a value larger than 99% of the
673
                // total sum
674 3
                if (abs($_ea - $_sa) >= 1 || $d == $sum) {
675 3
                    $img->CakeSlice($xcm, $ycm, $radius - 1, $radius - 1, $_sa, $_ea, $slicecolor, $arccolor);
676
                }
677
            }
678
679
            // If the CSIM is used then make sure we register a CSIM area for this slice as well
680 3
            if ($this->csimtargets && $aaoption !== 1) {
681
                $this->AddSliceToCSIM($i, $xcm, $ycm, $radius, $angle1, $angle2);
682
            }
683
        }
684
685
        // Format the titles for each slice
686 3
        if ($aaoption !== 2) {
687 3
            for ($i = 0; $i < $n; ++$i) {
688 3
                if ($this->labeltype == 0) {
689 3
                    if ($sum != 0) {
690 3
                        $l = 100.0 * $this->data[$i] / $sum;
691
                    } else {
692 3
                        $l = 0.0;
693
                    }
694 1
                } elseif ($this->labeltype == 1) {
695 1
                    $l = $this->data[$i] * 1.0;
696
                } else {
697
                    $l = $this->adjusted_data[$i];
698
                }
699 3
                if (isset($this->labels[$i]) && is_string($this->labels[$i])) {
700 1
                    $this->labels[$i] = sprintf($this->labels[$i], $l);
701
                } else {
702 3
                    $this->labels[$i] = $l;
703
                }
704
            }
705
        }
706
707 3
        if ($this->value->show && $aaoption !== 1) {
708 3
            $this->StrokeAllLabels($img, $xc, $yc, $radius);
709
        }
710
711
        // Adjust title position
712 3
        if ($aaoption !== 1) {
713 3
            $this->title->SetPos(
714 3
                $xc,
715 3
                $yc - $this->title->GetFontHeight($img) - $radius - $this->title->margin,
716 3
                'center',
717 3
                'bottom'
718
            );
719 3
            $this->title->Stroke($img);
720
        }
721 3
    }
722
723
    /**
724
     * PRIVATE METHODS.
725
     *
726
     * @param mixed $a
727
     */
728 3
    public function NormAngle($a)
729
    {
730 3
        while ($a < 0) {
731
            $a += 2 * M_PI;
732
        }
733
734 3
        while ($a > 2 * M_PI) {
735 1
            $a -= 2 * M_PI;
736
        }
737
738 3
        return $a;
739
    }
740
741 1
    public function Quadrant($a)
742
    {
743 1
        $a = $this->NormAngle($a);
744 1
        if ($a > 0 && $a <= M_PI / 2) {
745 1
            return 0;
746
        }
747
748 1
        if ($a > M_PI / 2 && $a <= M_PI) {
749 1
            return 1;
750
        }
751
752 1
        if ($a > M_PI && $a <= 1.5 * M_PI) {
753 1
            return 2;
754
        }
755
756 1
        if ($a > 1.5 * M_PI) {
757 1
            return 3;
758
        }
759
    }
760
761 1
    public function StrokeGuideLabels($img, $xc, $yc, $radius)
762
    {
763 1
        $n = safe_count($this->labels);
764
765
        /**
766
         * Step 1 of the algorithm is to construct a number of clusters
767
         * // a cluster is defined as all slices within the same quadrant (almost)
768
         * // that has an angular distance less than the treshold.
769
         */
770 1
        $tresh_hold = 25 * M_PI / 180; // 25 degrees difference to be in a cluster
771 1
        $incluster  = false; // flag if we are currently in a cluster or not
772 1
        $clusters   = []; // array of clusters
773 1
        $cidx       = -1; // running cluster index
774
775
        // Go through all the labels and construct a number of clusters
776 1
        for ($i = 0; $i < $n - 1; ++$i) {
777
            // Calc the angle distance between two consecutive slices
778 1
            $a1   = $this->la[$i];
779 1
            $a2   = $this->la[$i + 1];
780 1
            $q1   = $this->Quadrant($a1);
781 1
            $q2   = $this->Quadrant($a2);
782 1
            $diff = abs($a1 - $a2);
783 1
            if ($diff < $tresh_hold) {
784 1
                if ($incluster) {
785 1
                    ++$clusters[$cidx][1];
786
                    // Each cluster can only cover one quadrant
787
                    // Do we cross a quadrant ( and must break the cluster)
788 1
                    if ($q1 != $q2) {
789
                        // If we cross a quadrant boundary we normally start a
790
                        // new cluster. However we need to take the 12'a clock
791
                        // and 6'a clock positions into a special consideration.
792
                        // Case 1: WE go from q=1 to q=2 if the last slice on
793
                        // the cluster for q=1 is close to 12'a clock and the
794
                        // first slice in q=0 is small we extend the previous
795
                        // cluster
796 1
                        if ($q1 == 1 && $q2 == 0 && $a2 > (90 - 15) * M_PI / 180) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $q2 of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
797 1
                            if ($i < $n - 2) {
798 1
                                $a3 = $this->la[$i + 2];
799
                                // If there isn't a cluster coming up with the next-next slice
800
                                // we extend the previous cluster to cover this slice as well
801 1
                                if (abs($a3 - $a2) >= $tresh_hold) {
802
                                    ++$clusters[$cidx][1];
803 1
                                    ++$i;
804
                                }
805
                            }
806 1
                        } elseif ($q1 == 3 && $q2 == 2 && $a2 > (270 - 15) * M_PI / 180) {
807
                            if ($i < $n - 2) {
808
                                $a3 = $this->la[$i + 2];
809
                                // If there isn't a cluster coming up with the next-next slice
810
                                // we extend the previous cluster to cover this slice as well
811
                                if (abs($a3 - $a2) >= $tresh_hold) {
812
                                    ++$clusters[$cidx][1];
813
                                    ++$i;
814
                                }
815
                            }
816
                        }
817
818 1
                        if ($q1 == 2 && $q2 == 1 && $a2 > (180 - 15) * M_PI / 180) {
819 1
                            ++$clusters[$cidx][1];
820 1
                            ++$i;
821
                        }
822
823 1
                        $incluster = false;
824
                    }
825 1
                } elseif ($q1 == $q2) {
826 1
                    $incluster = true;
827
                    // Now we have a special case for quadrant 0. If we previously
828
                    // have a cluster of one in quadrant 0 we just extend that
829
                    // cluster. If we don't do this then we risk that the label
830
                    // for the cluster of one will cross the guide-line
831 1
                    if ($q1 == 0 && $cidx > -1 &&
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $q1 of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
832 1
                        $clusters[$cidx][1] == 1 &&
833 1
                        $this->Quadrant($this->la[$clusters[$cidx][0]]) == 0) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->Quadrant($this->la[$clusters[$cidx][0]]) of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
834
                        ++$clusters[$cidx][1];
835
                    } else {
836 1
                        ++$cidx;
837 1
                        $clusters[$cidx][0] = $i;
838 1
                        $clusters[$cidx][1] = 1;
839
                    }
840
                } else {
841
                    // Create a "cluster" of one since we are just crossing
842
                    // a quadrant
843
                    ++$cidx;
844
                    $clusters[$cidx][0] = $i;
845 1
                    $clusters[$cidx][1] = 1;
846
                }
847
            } else {
848 1
                if ($incluster) {
849
                    // Add the last slice
850 1
                    ++$clusters[$cidx][1];
851 1
                    $incluster = false;
852
                } else {
853
                    // Create a "cluster" of one
854 1
                    ++$cidx;
855 1
                    $clusters[$cidx][0] = $i;
856 1
                    $clusters[$cidx][1] = 1;
857
                }
858
            }
859
        }
860
        // Handle the very last slice
861 1
        if ($incluster) {
862
            ++$clusters[$cidx][1];
863
        } else {
864
            // Create a "cluster" of one
865 1
            ++$cidx;
866 1
            $clusters[$cidx][0] = $i;
867 1
            $clusters[$cidx][1] = 1;
868
        }
869
870
        /*
871
        if( true ) {
872
        // Debug printout in labels
873
        for( $i=0; $i <= $cidx; ++$i ) {
874
        for( $j=0; $j < $clusters[$i][1]; ++$j ) {
875
        $a = $this->la[$clusters[$i][0]+$j];
876
        $aa = round($a*180/M_PI);
877
        $q = $this->Quadrant($a);
878
        $this->labels[$clusters[$i][0]+$j]="[$q:$aa] $i:$j";
879
        }
880
        }
881
        }
882
         */
883
884
        /*
885
         * Step 2 of the algorithm is use the clusters and draw the labels
886
         * // and guidelines
887
         */
888
        // We use the font height as the base factor for how far we need to
889
        // spread the labels in the Y-direction.
890 1
        $this->value->ApplyFont($img);
891 1
        $fh        = $img->GetFontHeight();
892 1
        $origvstep = $fh * $this->iGuideVFactor;
893 1
        $this->value->SetMargin(0);
894
895
        // Number of clusters found
896 1
        $nc = safe_count($clusters);
897
898
        // Walk through all the clusters
899 1
        for ($i = 0; $i < $nc; ++$i) {
900
            // Start angle and number of slices in this cluster
901 1
            $csize = $clusters[$i][1];
902 1
            $a     = $this->la[$clusters[$i][0]];
903 1
            $q     = $this->Quadrant($a);
904
905
            // Now set up the start and end conditions to make sure that
906
            // in each cluster we walk through the all the slices starting with the slice
907
            // closest to the equator. Since all slices are numbered clockwise from "3'a clock"
908
            // we have different conditions depending on in which quadrant the slice lies within.
909 1
            if ($q == 0) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $q of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
910 1
                $start = $csize - 1;
911 1
                $idx   = $start;
912 1
                $step  = -1;
913 1
                $vstep = -$origvstep;
914 1
            } elseif ($q == 1) {
915 1
                $start = 0;
916 1
                $idx   = $start;
917 1
                $step  = 1;
918 1
                $vstep = -$origvstep;
919 1
            } elseif ($q == 2) {
920 1
                $start = $csize - 1;
921 1
                $idx   = $start;
922 1
                $step  = -1;
923 1
                $vstep = $origvstep;
924 1
            } elseif ($q == 3) {
925 1
                $start = 0;
926 1
                $idx   = $start;
927 1
                $step  = 1;
928 1
                $vstep = $origvstep;
929
            }
930
931
            // Walk through all slices within this cluster
932 1
            for ($j = 0; $j < $csize; ++$j) {
933
                // Now adjust the position of the labels in each cluster starting
934
                // with the slice that is closest to the equator of the pie
935 1
                $a = $this->la[$clusters[$i][0] + $idx];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $idx does not seem to be defined for all execution paths leading up to this point.
Loading history...
936
937
                // Guide line start in the center of the arc of the slice
938 1
                $r = $radius + $this->explode_radius[$n - 1 - ($clusters[$i][0] + $idx)];
939 1
                $x = round($r * cos($a) + $xc);
940 1
                $y = round($yc - $r * sin($a));
941
942
                // The distance from the arc depends on chosen font and the "R-Factor"
943 1
                $r += $fh * $this->iGuideLineRFactor;
944
945
                // Should the labels be placed curved along the pie or in straight columns
946
                // outside the pie?
947 1
                if ($this->iGuideLineCurve) {
948 1
                    $xt = round($r * cos($a) + $xc);
949
                }
950
951
                // If this is the first slice in the cluster we need some first time
952
                // proessing
953 1
                if ($idx == $start) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $start does not seem to be defined for all execution paths leading up to this point.
Loading history...
954 1
                    if (!$this->iGuideLineCurve) {
955 1
                        $xt = round($r * cos($a) + $xc);
956
                    }
957
958 1
                    $yt = round($yc - $r * sin($a));
959
960
                    // Some special consideration in case this cluster starts
961
                    // in quadrant 1 or 3 very close to the "equator" (< 20 degrees)
962
                    // and the previous clusters last slice is within the tolerance.
963
                    // In that case we add a font height to this labels Y-position
964
                    // so it doesn't collide with
965
                    // the slice in the previous cluster
966 1
                    $prevcluster = ($i + ($nc - 1)) % $nc;
967 1
                    $previdx     = $clusters[$prevcluster][0] + $clusters[$prevcluster][1] - 1;
968 1
                    if ($q == 1 && $a > 160 * M_PI / 180) {
969
                        // Get the angle for the previous clusters last slice
970
                        $diff = abs($a - $this->la[$previdx]);
971
                        if ($diff < $tresh_hold) {
972
                            $yt -= $fh;
973
                        }
974 1
                    } elseif ($q == 3 && $a > 340 * M_PI / 180) {
975
                        // We need to subtract 360 to compare angle distance between
976
                        // q=0 and q=3
977 1
                        $diff = abs($a - $this->la[$previdx] - 360 * M_PI / 180);
978 1
                        if ($diff < $tresh_hold) {
979 1
                            $yt += $fh;
980
                        }
981
                    }
982
                } else {
983
                    // The step is at minimum $vstep but if the slices are relatively large
984
                    // we make sure that we add at least a step that corresponds to the vertical
985
                    // distance between the centers at the arc on the slice
986 1
                    $prev_a = $this->la[$clusters[$i][0] + ($idx - $step)];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $step does not seem to be defined for all execution paths leading up to this point.
Loading history...
987 1
                    $dy     = abs($radius * (sin($a) - sin($prev_a)) * 1.2);
988 1
                    if ($vstep > 0) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $vstep does not seem to be defined for all execution paths leading up to this point.
Loading history...
989 1
                        $yt += max($vstep, $dy);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $yt does not seem to be defined for all execution paths leading up to this point.
Loading history...
990
                    } else {
991 1
                        $yt += min($vstep, -$dy);
992
                    }
993
                }
994
995 1
                $label = $this->labels[$clusters[$i][0] + $idx];
996
997 1
                if ($csize == 1) {
998
                    // A "meta" cluster with only one slice
999 1
                    $r  = $radius + $this->explode_radius[$n - 1 - ($clusters[$i][0] + $idx)];
1000 1
                    $rr = $r + $img->GetFontHeight() / 2;
1001 1
                    $xt = round($rr * cos($a) + $xc);
1002 1
                    $yt = round($yc - $rr * sin($a));
1003 1
                    $this->StrokeLabel($label, $img, $xc, $yc, $a, $r);
1004 1
                    if ($this->iShowGuideLineForSingle) {
1005 1
                        $this->guideline->Stroke($img, $x, $y, $xt, $yt);
1006
                    }
1007
                } else {
1008 1
                    $this->guideline->Stroke($img, $x, $y, $xt, $yt);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $xt does not seem to be defined for all execution paths leading up to this point.
Loading history...
1009 1
                    if ($q == 1 || $q == 2) {
1010
                        // Left side of Pie
1011 1
                        $this->guideline->Stroke($img, $xt, $yt, $xt - $this->guidelinemargin, $yt);
1012 1
                        $lbladj              = -$this->guidelinemargin - 5;
1013 1
                        $this->value->halign = 'right';
1014 1
                        $this->value->valign = 'center';
1015
                    } else {
1016
                        // Right side of pie
1017 1
                        $this->guideline->Stroke($img, $xt, $yt, $xt + $this->guidelinemargin, $yt);
1018 1
                        $lbladj              = $this->guidelinemargin + 5;
1019 1
                        $this->value->halign = 'left';
1020 1
                        $this->value->valign = 'center';
1021
                    }
1022 1
                    $this->value->Stroke($img, $label, $xt + $lbladj, $yt);
1023
                }
1024
1025
                // Udate idx to point to next slice in the cluster to process
1026 1
                $idx += $step;
1027
            }
1028
        }
1029 1
    }
1030
1031 3
    public function StrokeAllLabels($img, $xc, $yc, $radius)
1032
    {
1033
        // First normalize all angles for labels
1034 3
        $n = safe_count($this->la);
1035 3
        for ($i = 0; $i < $n; ++$i) {
1036 3
            $this->la[$i] = $this->NormAngle($this->la[$i]);
1037
        }
1038 3
        if ($this->guideline->iShow) {
1039 1
            $this->StrokeGuideLabels($img, $xc, $yc, $radius);
1040
        } else {
1041 3
            $n = safe_count($this->labels);
1042 3
            for ($i = 0; $i < $n; ++$i) {
1043 3
                $this->StrokeLabel(
1044 3
                    $this->labels[$i],
1045 3
                    $img,
1046 3
                    $xc,
1047 3
                    $yc,
1048 3
                    $this->la[$i],
1049 3
                    $radius + $this->explode_radius[$n - 1 - $i]
1050
                );
1051
            }
1052
        }
1053 3
    }
1054
1055
    // Position the labels of each slice
1056 3
    public function StrokeLabel($label, $img, $xc, $yc, $a, $r)
1057
    {
1058
        // Default value
1059 3
        if ($this->ilabelposadj === 'auto') {
0 ignored issues
show
introduced by
The condition $this->ilabelposadj === 'auto' is always false.
Loading history...
1060
            $this->ilabelposadj = 0.65;
1061
        }
1062
1063
        // We position the values diferently depending on if they are inside
1064
        // or outside the pie
1065 3
        if ($this->ilabelposadj < 1.0) {
1066 1
            $this->value->SetAlign('center', 'center');
1067 1
            $this->value->margin = 0;
1068
1069 1
            $xt = round($this->ilabelposadj * $r * cos($a) + $xc);
1070 1
            $yt = round($yc - $this->ilabelposadj * $r * sin($a));
1071
1072 1
            $this->value->Stroke($img, $label, $xt, $yt);
1073
        } else {
1074 3
            $this->value->halign = 'left';
1075 3
            $this->value->valign = 'top';
1076 3
            $this->value->margin = 0;
1077
1078
            // Position the axis title.
1079
            // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text
1080
            // that intersects with the extension of the corresponding axis. The code looks a little
1081
            // bit messy but this is really the only way of having a reasonable position of the
1082
            // axis titles.
1083 3
            $this->value->ApplyFont($img);
1084 3
            $h = $img->GetTextHeight($label);
1085
            // For numeric values the format of the display value
1086
            // must be taken into account
1087 3
            if (is_numeric($label)) {
1088 3
                if ($label > 0) {
1089 3
                    $w = $img->GetTextWidth(sprintf($this->value->format, $label));
1090
                } else {
1091 3
                    $w = $img->GetTextWidth(sprintf($this->value->negformat, $label));
1092
                }
1093
            } else {
1094 1
                $w = $img->GetTextWidth($label);
1095
            }
1096
1097 3
            if ($this->ilabelposadj > 1.0 && $this->ilabelposadj < 5.0) {
1098
                $r *= $this->ilabelposadj;
1099
            }
1100
1101 3
            $r += $img->GetFontHeight() / 1.5;
1102
1103 3
            $xt = round($r * cos($a) + $xc);
1104 3
            $yt = round($yc - $r * sin($a));
1105
1106
            // Normalize angle
1107 3
            while ($a < 0) {
1108
                $a += 2 * M_PI;
1109
            }
1110
1111 3
            while ($a > 2 * M_PI) {
1112
                $a -= 2 * M_PI;
1113
            }
1114
1115 3
            if ($a >= 7 * M_PI / 4 || $a <= M_PI / 4) {
1116 3
                $dx = 0;
1117
            }
1118
1119 3
            if ($a >= M_PI / 4 && $a <= 3 * M_PI / 4) {
1120 3
                $dx = ($a - M_PI / 4) * 2 / M_PI;
1121
            }
1122
1123 3
            if ($a >= 3 * M_PI / 4 && $a <= 5 * M_PI / 4) {
1124 3
                $dx = 1;
1125
            }
1126
1127 3
            if ($a >= 5 * M_PI / 4 && $a <= 7 * M_PI / 4) {
1128 3
                $dx = (1 - ($a - M_PI * 5 / 4) * 2 / M_PI);
1129
            }
1130
1131 3
            if ($a >= 7 * M_PI / 4) {
1132 3
                $dy = (($a - M_PI) - 3 * M_PI / 4) * 2 / M_PI;
1133
            }
1134
1135 3
            if ($a <= M_PI / 4) {
1136 2
                $dy = (1 - $a * 2 / M_PI);
1137
            }
1138
1139 3
            if ($a >= M_PI / 4 && $a <= 3 * M_PI / 4) {
1140 3
                $dy = 1;
1141
            }
1142
1143 3
            if ($a >= 3 * M_PI / 4 && $a <= 5 * M_PI / 4) {
1144 3
                $dy = (1 - ($a - 3 * M_PI / 4) * 2 / M_PI);
1145
            }
1146
1147 3
            if ($a >= 5 * M_PI / 4 && $a <= 7 * M_PI / 4) {
1148 3
                $dy = 0;
1149
            }
1150
1151 3
            $this->value->Stroke($img, $label, $xt - $dx * $w, $yt - $dy * $h);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dy does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $dx does not seem to be defined for all execution paths leading up to this point.
Loading history...
1152
        }
1153 3
    }
1154
1155 3
    public function UsePlotThemeColors($flag = true)
1156
    {
1157 3
        $this->use_plot_theme_colors = $flag;
1158 3
    }
1159
} // @class
1160
1161
/* EOF */
1162