Issues (459)

src/graph/PolarAxis.php (8 issues)

1
<?php
2
3
/**
4
 * JPGraph v4.0.3
5
 */
6
7
namespace Amenadiel\JpGraph\Graph;
8
9
use Amenadiel\JpGraph\Text;
10
use Amenadiel\JpGraph\Util;
11
12
/**
13
 * @class PolarAxis
14
 */
15
class PolarAxis extends Axis
16
{
17
    private $angle_step        = 15;
18
    private $angle_color       = 'lightgray';
19
    private $angle_label_color = 'black';
0 ignored issues
show
The private property $angle_label_color is not used, and could be removed.
Loading history...
20
    private $angle_fontfam     = FF_FONT1;
21
    private $angle_fontstyle   = FS_NORMAL;
22
    private $angle_fontsize    = 10;
23
    private $angle_fontcolor   = 'navy';
24
    private $gridminor_color   = 'lightgray';
25
    private $gridmajor_color   = 'lightgray';
26
    private $show_minor_grid   = false;
27
    private $show_major_grid   = true;
28
    private $show_angle_mark   = true;
29
    private $show_angle_grid   = true;
30
    private $show_angle_label  = true;
31
    private $angle_tick_len    = 3;
32
    private $angle_tick_len2   = 3;
33
    private $angle_tick_color  = 'black';
34
    private $show_angle_tick   = true;
35
    private $radius_tick_color = 'black';
36
37
    public function __construct($img, $aScale)
38
    {
39
        parent::__construct($img, $aScale);
40
    }
41
42
    public function ShowAngleDegreeMark($aFlg = true)
43
    {
44
        $this->show_angle_mark = $aFlg;
45
    }
46
47
    public function SetAngleStep($aStep)
48
    {
49
        $this->angle_step = $aStep;
50
    }
51
52
    public function HideTicks($aFlg = true, $aAngleFlg = true)
53
    {
54
        parent::HideTicks($aFlg, $aFlg);
55
        $this->show_angle_tick = !$aAngleFlg;
56
    }
57
58
    public function ShowAngleLabel($aFlg = true)
59
    {
60
        $this->show_angle_label = $aFlg;
61
    }
62
63
    public function ShowGrid($aMajor = true, $aMinor = false, $aAngle = true)
64
    {
65
        $this->show_minor_grid = $aMinor;
66
        $this->show_major_grid = $aMajor;
67
        $this->show_angle_grid = $aAngle;
68
    }
69
70
    public function SetAngleFont($aFontFam, $aFontStyle = FS_NORMAL, $aFontSize = 10)
71
    {
72
        $this->angle_fontfam   = $aFontFam;
73
        $this->angle_fontstyle = $aFontStyle;
74
        $this->angle_fontsize  = $aFontSize;
75
    }
76
77
    public function SetColor($aColor, $aRadColor = '', $aAngleColor = '')
78
    {
79
        if ($aAngleColor == '') {
80
            $aAngleColor = $aColor;
81
        }
82
83
        parent::SetColor($aColor, $aRadColor);
84
        $this->angle_fontcolor = $aAngleColor;
85
    }
86
87
    public function SetGridColor($aMajorColor, $aMinorColor = '', $aAngleColor = '')
88
    {
89
        if ($aMinorColor == '') {
90
            $aMinorColor = $aMajorColor;
91
        }
92
93
        if ($aAngleColor == '') {
94
            $aAngleColor = $aMajorColor;
95
        }
96
97
        $this->gridminor_color = $aMinorColor;
98
        $this->gridmajor_color = $aMajorColor;
99
        $this->angle_color     = $aAngleColor;
100
    }
101
102
    public function SetTickColors($aRadColor, $aAngleColor = '')
103
    {
104
        $this->radius_tick_color = $aRadColor;
105
        $this->angle_tick_color  = $aAngleColor;
106
    }
107
108
    // Private methods
109
    public function StrokeGrid($pos)
110
    {
111
        $x = round($this->img->left_margin + $this->img->plotwidth / 2);
112
        $this->scale->ticks->Stroke($this->img, $this->scale, $pos);
113
114
        // Stroke the minor arcs
115
        $pmin = [];
116
        $p    = $this->scale->ticks->ticks_pos;
117
        $n    = safe_count($p);
118
        $i    = 0;
119
        $this->img->SetColor($this->gridminor_color);
120
        while ($i < $n) {
121
            $r      = $p[$i] - $x + 1;
122
            $pmin[] = $r;
123
            if ($this->show_minor_grid) {
124
                $this->img->Circle($x, $pos, $r);
125
            }
126
            ++$i;
127
        }
128
129
        $limit = max($this->img->plotwidth, $this->img->plotheight) * 1.4;
130
        while ($r < $limit) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $r does not seem to be defined for all execution paths leading up to this point.
Loading history...
131
            $off = $r;
132
            $i   = 1;
133
            $r   = $off + round($p[$i] - $x + 1);
134
            while ($r < $limit && $i < $n) {
135
                $r      = $off + $p[$i] - $x;
136
                $pmin[] = $r;
137
                if ($this->show_minor_grid) {
138
                    $this->img->Circle($x, $pos, $r);
139
                }
140
                ++$i;
141
            }
142
        }
143
144
        // Stroke the major arcs
145
        if ($this->show_major_grid) {
146
            // First determine how many minor step on
147
            // every major step. We have recorded the minor radius
148
            // in pmin and use these values. This is done in order
149
            // to avoid rounding errors if we were to recalculate the
150
            // different major radius.
151
            $pmaj = $this->scale->ticks->maj_ticks_pos;
152
            $p    = $this->scale->ticks->ticks_pos;
153
            if ($this->scale->name == 'lin') {
154
                $step = round(($pmaj[1] - $pmaj[0]) / ($p[1] - $p[0]));
155
            } else {
156
                $step = 9;
157
            }
158
            $n = round(safe_count($pmin) / $step);
159
            $i = 0;
0 ignored issues
show
The assignment to $i is dead and can be removed.
Loading history...
160
            $this->img->SetColor($this->gridmajor_color);
161
            $limit = max($this->img->plotwidth, $this->img->plotheight) * 1.4;
162
            $off   = $r;
0 ignored issues
show
The assignment to $off is dead and can be removed.
Loading history...
163
            $i     = 0;
164
            $r     = $pmin[$i * $step];
165
            while ($r < $limit && $i < $n) {
166
                $r = $pmin[$i * $step];
167
                $this->img->Circle($x, $pos, $r);
168
                ++$i;
169
            }
170
        }
171
172
        // Draw angles
173
        if ($this->show_angle_grid) {
174
            $this->img->SetColor($this->angle_color);
175
            $d            = max($this->img->plotheight, $this->img->plotwidth) * 1.4;
176
            $a            = 0;
177
            $p            = $this->scale->ticks->ticks_pos;
178
            $start_radius = $p[1] - $x;
179
            while ($a < 360) {
180
                if ($a == 90 || $a == 270) {
181
                    // Make sure there are no rounding problem with
182
                    // exactly vertical lines
183
                    $this->img->Line(
184
                        $x + $start_radius * cos($a / 180 * M_PI) + 1,
185
                        $pos - $start_radius * sin($a / 180 * M_PI),
186
                        $x + $start_radius * cos($a / 180 * M_PI) + 1,
187
                        $pos - $d * sin($a / 180 * M_PI)
188
                    );
189
                } else {
190
                    $this->img->Line(
191
                        $x + $start_radius * cos($a / 180 * M_PI) + 1,
192
                        $pos - $start_radius * sin($a / 180 * M_PI),
193
                        $x + $d * cos($a / 180 * M_PI),
194
                        $pos - $d * sin($a / 180 * M_PI)
195
                    );
196
                }
197
                $a += $this->angle_step;
198
            }
199
        }
200
    }
201
202
    public function StrokeAngleLabels($pos, $type)
203
    {
204
        if (!$this->show_angle_label) {
205
            return;
206
        }
207
208
        $x0 = round($this->img->left_margin + $this->img->plotwidth / 2) + 1;
209
210
        $d = max($this->img->plotwidth, $this->img->plotheight) * 1.42;
211
        $a = $this->angle_step;
212
        $t = new Text\Text();
213
        $t->SetColor($this->angle_fontcolor);
214
        $t->SetFont($this->angle_fontfam, $this->angle_fontstyle, $this->angle_fontsize);
215
        $xright  = $this->img->width - $this->img->right_margin;
216
        $ytop    = $this->img->top_margin;
217
        $xleft   = $this->img->left_margin;
218
        $ybottom = $this->img->height - $this->img->bottom_margin;
219
        $ha      = 'left';
220
        $va      = 'center';
221
        $w       = $this->img->plotwidth / 2;
222
        $h       = $this->img->plotheight / 2;
223
        $xt      = $x0;
224
        $yt      = $pos;
225
        $margin  = 5;
226
227
        $tl  = $this->angle_tick_len; // Outer len
228
        $tl2 = $this->angle_tick_len2; // Interior len
229
230
        $this->img->SetColor($this->angle_tick_color);
231
        $rot90 = $this->img->a == 90;
232
233
        if ($type == POLAR_360) {
234
            // Corner angles of the four corners
235
            $ca1 = atan($h / $w) / M_PI * 180;
236
            $ca2 = 180 - $ca1;
237
            $ca3 = $ca1 + 180;
238
            $ca4 = 360 - $ca1;
239
            $end = 360;
240
241
            while ($a < $end) {
242
                $ca = cos($a / 180 * M_PI);
243
                $sa = sin($a / 180 * M_PI);
244
                $x  = $d * $ca;
245
                $y  = $d * $sa;
246
                $xt = 1000;
247
                $yt = 1000;
248
                if ($a <= $ca1 || $a >= $ca4) {
249
                    $yt = $pos - $w * $y / $x;
250
                    $xt = $xright + $margin;
251
                    if ($rot90) {
252
                        $ha = 'center';
253
                        $va = 'top';
254
                    } else {
255
                        $ha = 'left';
256
                        $va = 'center';
257
                    }
258
                    $x1 = $xright - $tl2;
259
                    $x2 = $xright + $tl;
260
                    $y1 = $y2 = $yt;
261
                } elseif ($a > $ca1 && $a < $ca2) {
262
                    $xt = $x0 + $h * $x / $y;
263
                    $yt = $ytop - $margin;
264
                    if ($rot90) {
265
                        $ha = 'left';
266
                        $va = 'center';
267
                    } else {
268
                        $ha = 'center';
269
                        $va = 'bottom';
270
                    }
271
                    $y1 = $ytop + $tl2;
272
                    $y2 = $ytop - $tl;
273
                    $x1 = $x2 = $xt;
274
                } elseif ($a >= $ca2 && $a <= $ca3) {
275
                    $yt = $pos + $w * $y / $x;
276
                    $xt = $xleft - $margin;
277
                    if ($rot90) {
278
                        $ha = 'center';
279
                        $va = 'bottom';
280
                    } else {
281
                        $ha = 'right';
282
                        $va = 'center';
283
                    }
284
                    $x1 = $xleft + $tl2;
285
                    $x2 = $xleft - $tl;
286
                    $y1 = $y2 = $yt;
287
                } else {
288
                    $xt = $x0 - $h * $x / $y;
289
                    $yt = $ybottom + $margin;
290
                    if ($rot90) {
291
                        $ha = 'right';
292
                        $va = 'center';
293
                    } else {
294
                        $ha = 'center';
295
                        $va = 'top';
296
                    }
297
                    $y1 = $ybottom - $tl2;
298
                    $y2 = $ybottom + $tl;
299
                    $x1 = $x2 = $xt;
300
                }
301
                if ($a != 0 && $a != 180) {
302
                    $t->Align($ha, $va);
303
                    if ($this->scale->clockwise) {
304
                        $t->Set(360 - $a);
305
                    } else {
306
                        $t->Set($a);
307
                    }
308
                    if ($this->show_angle_mark && $t->font_family > 4) {
309
                        $a .= SymChar::Get('degree');
310
                    }
311
                    $t->Stroke($this->img, $xt, $yt);
312
                    if ($this->show_angle_tick) {
313
                        $this->img->Line($x1, $y1, $x2, $y2);
314
                    }
315
                }
316
                $a += $this->angle_step;
317
            }
318
        } else {
319
            // POLAR_HALF
320
            $ca1 = atan($h / $w * 2) / M_PI * 180;
321
            $ca2 = 180 - $ca1;
322
            $end = 180;
323
            while ($a < $end) {
324
                $ca = cos($a / 180 * M_PI);
325
                $sa = sin($a / 180 * M_PI);
326
                $x  = $d * $ca;
327
                $y  = $d * $sa;
328
                if ($a <= $ca1) {
329
                    $yt = $pos - $w * $y / $x;
330
                    $xt = $xright + $margin;
331
                    if ($rot90) {
332
                        $ha = 'center';
333
                        $va = 'top';
334
                    } else {
335
                        $ha = 'left';
336
                        $va = 'center';
337
                    }
338
                    $x1 = $xright - $tl2;
339
                    $x2 = $xright + $tl;
340
                    $y1 = $y2 = $yt;
341
                } elseif ($a > $ca1 && $a < $ca2) {
342
                    $xt = $x0 + 2 * $h * $x / $y;
343
                    $yt = $ytop - $margin;
344
                    if ($rot90) {
345
                        $ha = 'left';
346
                        $va = 'center';
347
                    } else {
348
                        $ha = 'center';
349
                        $va = 'bottom';
350
                    }
351
                    $y1 = $ytop + $tl2;
352
                    $y2 = $ytop - $tl;
353
                    $x1 = $x2 = $xt;
354
                } elseif ($a >= $ca2) {
355
                    $yt = $pos + $w * $y / $x;
356
                    $xt = $xleft - $margin;
357
                    if ($rot90) {
358
                        $ha = 'center';
359
                        $va = 'bottom';
360
                    } else {
361
                        $ha = 'right';
362
                        $va = 'center';
363
                    }
364
                    $x1 = $xleft + $tl2;
365
                    $x2 = $xleft - $tl;
366
                    $y1 = $y2 = $yt;
367
                }
368
                $t->Align($ha, $va);
369
                if ($this->show_angle_mark && $t->font_family > 4) {
370
                    $a .= SymChar::Get('degree');
371
                }
372
                $t->Set($a);
373
                $t->Stroke($this->img, $xt, $yt);
374
                if ($this->show_angle_tick) {
375
                    $this->img->Line($x1, $y1, $x2, $y2);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $x2 does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $y1 does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $x1 does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $y2 does not seem to be defined for all execution paths leading up to this point.
Loading history...
376
                }
377
                $a += $this->angle_step;
378
            }
379
        }
380
    }
381
382
    public function Stroke($pos, $dummy = true)
383
    {
384
        $this->img->SetLineWeight($this->weight);
385
        $this->img->SetColor($this->color);
386
        $this->img->SetFont($this->font_family, $this->font_style, $this->font_size);
387
        if (!$this->hide_line) {
388
            $this->img->FilledRectangle(
389
                $this->img->left_margin,
390
                $pos,
391
                $this->img->width - $this->img->right_margin,
392
                $pos + $this->weight - 1
393
            );
394
        }
395
        $y = $pos + $this->img->GetFontHeight() + $this->title_margin + $this->title->margin;
396
        if ($this->title_adjust == 'high') {
397
            $this->title->SetPos($this->img->width - $this->img->right_margin, $y, 'right', 'top');
398
        } elseif ($this->title_adjust == 'middle' || $this->title_adjust == 'center') {
399
            $this->title->SetPos(
400
                ($this->img->width - $this->img->left_margin - $this->img->right_margin) / 2 + $this->img->left_margin,
401
                $y,
402
                'center',
403
                'top'
404
            );
405
        } elseif ($this->title_adjust == 'low') {
406
            $this->title->SetPos($this->img->left_margin, $y, 'left', 'top');
407
        } else {
408
            Util\JpGraphError::RaiseL(17002, $this->title_adjust);
409
            //('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')');
410
        }
411
412
        if (!$this->hide_labels) {
413
            $this->StrokeLabels($pos, false);
414
        }
415
        $this->img->SetColor($this->radius_tick_color);
416
        $this->scale->ticks->Stroke($this->img, $this->scale, $pos);
417
418
        //
419
        // Mirror the positions for the left side of the scale
420
        //
421
        $mid = 2 * ($this->img->left_margin + $this->img->plotwidth / 2);
422
        $n   = safe_count($this->scale->ticks->ticks_pos);
423
        $i   = 0;
424
        while ($i < $n) {
425
            $this->scale->ticks->ticks_pos[$i] =
426
            $mid - $this->scale->ticks->ticks_pos[$i];
427
            ++$i;
428
        }
429
430
        $n = safe_count($this->scale->ticks->maj_ticks_pos);
431
        $i = 0;
432
        while ($i < $n) {
433
            $this->scale->ticks->maj_ticks_pos[$i] =
434
            $mid - $this->scale->ticks->maj_ticks_pos[$i];
435
            ++$i;
436
        }
437
438
        $n = safe_count($this->scale->ticks->maj_ticklabels_pos);
439
        $i = 1;
440
        while ($i < $n) {
441
            $this->scale->ticks->maj_ticklabels_pos[$i] =
442
            $mid - $this->scale->ticks->maj_ticklabels_pos[$i];
443
            ++$i;
444
        }
445
446
        // Draw the left side of the scale
447
        $n  = safe_count($this->scale->ticks->ticks_pos);
448
        $yu = $pos - $this->scale->ticks->direction * $this->scale->ticks->GetMinTickAbsSize();
449
450
        // Minor ticks
451
        if (!$this->scale->ticks->supress_minor_tickmarks) {
452
            $i = 1;
453
            while ($i < $n / 2) {
454
                $x = round($this->scale->ticks->ticks_pos[$i]);
455
                $this->img->Line($x, $pos, $x, $yu);
456
                ++$i;
457
            }
458
        }
459
460
        $n  = safe_count($this->scale->ticks->maj_ticks_pos);
461
        $yu = $pos - $this->scale->ticks->direction * $this->scale->ticks->GetMajTickAbsSize();
462
463
        // Major ticks
464
        if (!$this->scale->ticks->supress_tickmarks) {
465
            $i = 1;
466
            while ($i < $n / 2) {
467
                $x = round($this->scale->ticks->maj_ticks_pos[$i]);
468
                $this->img->Line($x, $pos, $x, $yu);
469
                ++$i;
470
            }
471
        }
472
        if (!$this->hide_labels) {
473
            $this->StrokeLabels($pos, false);
474
        }
475
        $this->title->Stroke($this->img);
476
    }
477
}
478