PlotMark   F
last analyzed

Complexity

Total Complexity 85

Size/Duplication

Total Lines 502
Duplicated Lines 0 %

Test Coverage

Coverage 60.9%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 326
c 1
b 0
f 0
dl 0
loc 502
ccs 204
cts 335
cp 0.609
rs 2
wmc 85

21 Methods

Rating   Name   Duplication   Size   Complexity  
A GetCSIMAreas() 0 3 1
A GetType() 0 3 1
A Show() 0 3 1
A SetWidth() 0 3 1
A SetCSIMAltVal() 0 4 1
A SetColor() 0 3 1
A SetFillColor() 0 3 1
A SetCSIMAlt() 0 3 1
A SetWeight() 0 3 1
A SetCallback() 0 3 1
A SetCSIMTarget() 0 4 1
A SetCallbackYX() 0 3 1
A SetSize() 0 3 1
A SetDefaultWidth() 0 10 3
A SetType() 0 8 3
A __construct() 0 6 1
A AddCSIMPoly() 0 21 5
A Hide() 0 3 1
A AddCSIMCircle() 0 19 4
A GetWidth() 0 3 1
F Stroke() 0 309 54

How to fix   Complexity   

Complex Class

Complex classes like PlotMark often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PlotMark, and based on these observations, apply Extract Interface, too.

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\Image;
11
use Amenadiel\JpGraph\Text;
12
use Amenadiel\JpGraph\Util;
13
14
/**
15
 * File:        JPGRAPH_PLOTMARK.PHP
16
 * // Description: Class file. Handles plotmarks
17
 * // Created:     2003-03-21
18
 * // Ver:         $Id: jpgraph_plotmark.inc.php 1106 2009-02-22 20:16:35Z ljp $
19
 * //
20
 * // Copyright (c) Asial Corporation. All rights reserved.
21
 */
22
23
/**
24
 * @class PlotMark
25
 * // Description: Handles the plot marks in graphs
26
 */
27
class PlotMark
28
{
29
    public $title;
30
    public $show = true;
31
    public $type;
32
    public $weight           = 1;
33
    public $iFormatCallback  = '';
34
    public $iFormatCallback2 = '';
35
    public $fill_color       = 'blue';
36
    public $color            = 'black';
37
    public $width            = 4;
38
    private $yvalue;
39
    private $xvalue = '';
40
    private $csimtarget;
41
    private $csimwintarget = '';
42
    private $csimalt;
43
    private $csimareas;
44
    private $markimg     = '';
45
    private $iScale      = 1.0;
46
    private $oldfilename = '';
47
    private $iFileName   = '';
48
    private $imgdata_balls;
49
    private $imgdata_diamonds;
50
    private $imgdata_squares;
51
    private $imgdata_bevels;
52
    private $imgdata_stars;
53
    private $imgdata_pushpins;
54
55
    /**
56
     * CONSTRUCTOR.
57
     */
58 16
    public function __construct()
59
    {
60 16
        $this->title = new Text\Text();
61 16
        $this->title->Hide();
62 16
        $this->csimareas = '';
63 16
        $this->type      = -1;
64 16
    }
65
66
    /**
67
     * PUBLIC METHODS.
68
     *
69
     * @param mixed $aType
70
     * @param mixed $aFileName
71
     * @param mixed $aScale
72
     */
73 8
    public function SetType($aType, $aFileName = '', $aScale = 1.0)
74
    {
75 8
        $this->type = $aType;
76 8
        if ($aType == MARK_IMG && $aFileName == '') {
77
            Util\JpGraphError::RaiseL(23003); //('A filename must be specified if you set the mark type to MARK_IMG.');
78
        }
79 8
        $this->iFileName = $aFileName;
80 8
        $this->iScale    = $aScale;
81 8
    }
82
83
    public function SetCallback($aFunc)
84
    {
85
        $this->iFormatCallback = $aFunc;
86
    }
87
88 1
    public function SetCallbackYX($aFunc)
89
    {
90 1
        $this->iFormatCallback2 = $aFunc;
91 1
    }
92
93 11
    public function GetType()
94
    {
95 11
        return $this->type;
96
    }
97
98 2
    public function SetColor($aColor)
99
    {
100 2
        $this->color = $aColor;
101 2
    }
102
103 5
    public function SetFillColor($aFillColor)
104
    {
105 5
        $this->fill_color = $aFillColor;
106 5
    }
107
108
    public function SetWeight($aWeight)
109
    {
110
        $this->weight = $aWeight;
111
    }
112
113
    // Synonym for SetWidth()
114 5
    public function SetSize($aWidth)
115
    {
116 5
        $this->width = $aWidth;
117 5
    }
118
119 4
    public function SetWidth($aWidth)
120
    {
121 4
        $this->width = $aWidth;
122 4
    }
123
124
    public function SetDefaultWidth()
125
    {
126
        switch ($this->type) {
127
            case MARK_CIRCLE:
128
            case MARK_FILLEDCIRCLE:
129
                $this->width = 4;
130
131
                break;
132
            default:
133
                $this->width = 7;
134
        }
135
    }
136
137
    public function GetWidth()
138
    {
139
        return $this->width;
140
    }
141
142
    public function Hide($aHide = true)
143
    {
144
        $this->show = !$aHide;
145
    }
146
147 1
    public function Show($aShow = true)
148
    {
149 1
        $this->show = $aShow;
150 1
    }
151
152 8
    public function SetCSIMAltVal($aY, $aX = '')
153
    {
154 8
        $this->yvalue = $aY;
155 8
        $this->xvalue = $aX;
156 8
    }
157
158
    public function SetCSIMTarget($aTarget, $aWinTarget = '')
159
    {
160
        $this->csimtarget    = $aTarget;
161
        $this->csimwintarget = $aWinTarget;
162
    }
163
164
    public function SetCSIMAlt($aAlt)
165
    {
166
        $this->csimalt = $aAlt;
167
    }
168
169 8
    public function GetCSIMAreas()
170
    {
171 8
        return $this->csimareas;
172
    }
173
174 3
    public function AddCSIMPoly($aPts)
175
    {
176 3
        $coords = round($aPts[0]) . ', ' . round($aPts[1]);
177 3
        $n      = safe_count($aPts) / 2;
178 3
        for ($i = 1; $i < $n; ++$i) {
179 3
            $coords .= ', ' . round($aPts[2 * $i]) . ', ' . round($aPts[2 * $i + 1]);
180
        }
181 3
        $this->csimareas = '';
182 3
        if (!empty($this->csimtarget)) {
183
            $this->csimareas .= "<area shape=\"poly\" coords=\"${coords}\" ";
184
            $this->csimareas .= 'href="' . htmlentities($this->csimtarget) . '"';
185
186
            if (!empty($this->csimwintarget)) {
187
                $this->csimareas .= ' target="' . $this->csimwintarget . '" ';
188
            }
189
190
            if (!empty($this->csimalt)) {
191
                $tmp = sprintf($this->csimalt, $this->yvalue, $this->xvalue);
192
                $this->csimareas .= " title=\"${tmp}\" alt=\"${tmp}\"";
193
            }
194
            $this->csimareas .= " />\n";
195
        }
196 3
    }
197
198 5
    public function AddCSIMCircle($x, $y, $r)
199
    {
200 5
        $x               = round($x);
201 5
        $y               = round($y);
202 5
        $r               = round($r);
203 5
        $this->csimareas = '';
204 5
        if (!empty($this->csimtarget)) {
205
            $this->csimareas .= "<area shape=\"circle\" coords=\"${x},${y},${r}\" ";
206
            $this->csimareas .= 'href="' . htmlentities($this->csimtarget) . '"';
207
208
            if (!empty($this->csimwintarget)) {
209
                $this->csimareas .= ' target="' . $this->csimwintarget . '" ';
210
            }
211
212
            if (!empty($this->csimalt)) {
213
                $tmp = sprintf($this->csimalt, $this->yvalue, $this->xvalue);
214
                $this->csimareas .= " title=\"${tmp}\" alt=\"${tmp}\" ";
215
            }
216
            $this->csimareas .= " />\n";
217
        }
218 5
    }
219
220 8
    public function Stroke($img, $x, $y)
221
    {
222 8
        if (!$this->show) {
223
            return;
224
        }
225
226 8
        if ($this->iFormatCallback != '' || $this->iFormatCallback2 != '') {
227 1
            if ($this->iFormatCallback != '') {
228
                $f                            = $this->iFormatCallback;
229
                list($width, $color, $fcolor) = call_user_func($f, $this->yvalue);
230
                $filename                     = $this->iFileName;
231
                $imgscale                     = $this->iScale;
232
            } else {
233 1
                $f                                                  = $this->iFormatCallback2;
234 1
                list($width, $color, $fcolor, $filename, $imgscale) = call_user_func($f, $this->yvalue, $this->xvalue);
235 1
                if ($filename == '') {
236
                    $filename = $this->iFileName;
237
                }
238
239 1
                if ($imgscale == '') {
240
                    $imgscale = $this->iScale;
241
                }
242
            }
243
244 1
            if ($width == '') {
245 1
                $width = $this->width;
246
            }
247
248 1
            if ($color == '') {
249 1
                $color = $this->color;
250
            }
251
252 1
            if ($fcolor == '') {
253 1
                $fcolor = $this->fill_color;
254
            }
255
        } else {
256 8
            $fcolor   = $this->fill_color;
257 8
            $color    = $this->color;
258 8
            $width    = $this->width;
259 8
            $filename = $this->iFileName;
260 8
            $imgscale = $this->iScale;
261
        }
262
263 8
        if ($this->type == MARK_IMG ||
264 7
            ($this->type >= MARK_FLAG1 && $this->type <= MARK_FLAG4) ||
265 8
            $this->type >= MARK_IMG_PUSHPIN) {
266
            // Note: For the builtin images we use the "filename" parameter
267
            // to denote the color
268 4
            $anchor_x = 0.5;
269 4
            $anchor_y = 0.5;
270 4
            switch ($this->type) {
271 4
                case MARK_FLAG1:
272 4
                case MARK_FLAG2:
273 4
                case MARK_FLAG3:
274 4
                case MARK_FLAG4:
275 1
                    $this->markimg = Util\FlagCache::GetFlagImgByName($this->type - MARK_FLAG1 + 1, $filename);
276
277 1
                    break;
278 4
                case MARK_IMG:
279
                    // Load an image and use that as a marker
280
                    // Small optimization, if we have already read an image don't
281
                    // waste time reading it again.
282 2
                    if ($this->markimg == '' || !($this->oldfilename === $filename)) {
283 2
                        $this->markimg     = Graph\Graph::LoadBkgImage('', $filename);
284 2
                        $this->oldfilename = $filename;
285
                    }
286
287 2
                    break;
288 3
                case MARK_IMG_PUSHPIN:
289 2
                case MARK_IMG_SPUSHPIN:
290 2
                case MARK_IMG_LPUSHPIN:
291 1
                    if ($this->imgdata_pushpins == null) {
292 1
                        $this->imgdata_pushpins = new Image\ImgData_PushPins();
293
                    }
294 1
                    $this->markimg             = $this->imgdata_pushpins->GetImg($this->type, $filename);
295 1
                    list($anchor_x, $anchor_y) = $this->imgdata_pushpins->GetAnchor();
296
297 1
                    break;
298 2
                case MARK_IMG_SQUARE:
299
                    if ($this->imgdata_squares == null) {
300
                        $this->imgdata_squares = new Image\ImgData_Squares();
301
                    }
302
                    $this->markimg             = $this->imgdata_squares->GetImg($this->type, $filename);
303
                    list($anchor_x, $anchor_y) = $this->imgdata_squares->GetAnchor();
304
305
                    break;
306 2
                case MARK_IMG_STAR:
307
                    if ($this->imgdata_stars == null) {
308
                        $this->imgdata_stars = new Image\ImgData_Stars();
309
                    }
310
                    $this->markimg             = $this->imgdata_stars->GetImg($this->type, $filename);
311
                    list($anchor_x, $anchor_y) = $this->imgdata_stars->GetAnchor();
312
313
                    break;
314 2
                case MARK_IMG_BEVEL:
315
                    if ($this->imgdata_bevels == null) {
316
                        $this->imgdata_bevels = new Image\ImgData_Bevels();
317
                    }
318
                    $this->markimg             = $this->imgdata_bevels->GetImg($this->type, $filename);
319
                    list($anchor_x, $anchor_y) = $this->imgdata_bevels->GetAnchor();
320
321
                    break;
322 2
                case MARK_IMG_DIAMOND:
323 2
                    if ($this->imgdata_diamonds == null) {
324 2
                        $this->imgdata_diamonds = new Image\ImgData_Diamonds();
325
                    }
326 2
                    $this->markimg             = $this->imgdata_diamonds->GetImg($this->type, $filename);
327 2
                    list($anchor_x, $anchor_y) = $this->imgdata_diamonds->GetAnchor();
328
329 2
                    break;
330 1
                case MARK_IMG_BALL:
331 1
                case MARK_IMG_SBALL:
332 1
                case MARK_IMG_MBALL:
333
                case MARK_IMG_LBALL:
334 1
                    if ($this->imgdata_balls == null) {
335 1
                        $this->imgdata_balls = new Image\ImgData_Balls();
336
                    }
337 1
                    $this->markimg             = $this->imgdata_balls->GetImg($this->type, $filename);
338 1
                    list($anchor_x, $anchor_y) = $this->imgdata_balls->GetAnchor();
339
340 1
                    break;
341
            }
342
343 4
            $w = $img->GetWidth($this->markimg);
344 4
            $h = $img->GetHeight($this->markimg);
345
346 4
            $dw = round($imgscale * $w);
347 4
            $dh = round($imgscale * $h);
348
349
            // Do potential rotation
350 4
            list($x, $y) = $img->Rotate($x, $y);
351
352 4
            $dx = round($x - $dw * $anchor_x);
353 4
            $dy = round($y - $dh * $anchor_y);
354
355 4
            $this->width = max($dx, $dy);
356
357 4
            $img->Copy($this->markimg, $dx, $dy, 0, 0, $dw, $dh, $w, $h);
358 4
            if (!empty($this->csimtarget)) {
359
                $this->csimareas = '<area shape="rect" coords="' .
360
                $dx . ',' . $dy . ',' . round($dx + $dw) . ',' . round($dy + $dh) . '" ' .
361
                'href="' . htmlentities($this->csimtarget) . '"';
362
363
                if (!empty($this->csimwintarget)) {
364
                    $this->csimareas .= ' target="' . $this->csimwintarget . '" ';
365
                }
366
367
                if (!empty($this->csimalt)) {
368
                    $tmp = sprintf($this->csimalt, $this->yvalue, $this->xvalue);
369
                    $this->csimareas .= " title=\"${tmp}\" alt=\"${tmp}\" ";
370
                }
371
                $this->csimareas .= " />\n";
372
            }
373
374
            // Stroke title
375 4
            $this->title->Align('center', 'top');
376 4
            $this->title->Stroke($img, $x, $y + round($dh / 2));
377
378 4
            return;
379
        }
380
381 6
        $weight = $this->weight;
382 6
        $dx     = round($width / 2, 0);
383 6
        $dy     = round($width / 2, 0);
384 6
        $pts    = 0;
385
386 6
        switch ($this->type) {
387 6
            case MARK_SQUARE:
388 1
                $c[] = $x - $dx;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$c was never initialized. Although not strictly required by PHP, it is generally a good practice to add $c = array(); before regardless.
Loading history...
389 1
                $c[] = $y - $dy;
390 1
                $c[] = $x + $dx;
391 1
                $c[] = $y - $dy;
392 1
                $c[] = $x + $dx;
393 1
                $c[] = $y + $dy;
394 1
                $c[] = $x - $dx;
395 1
                $c[] = $y + $dy;
396 1
                $c[] = $x - $dx;
397 1
                $c[] = $y - $dy;
398 1
                $pts = 5;
399
400 1
                break;
401 6
            case MARK_UTRIANGLE:
402 1
                ++$dx; ++$dy;
403 1
                $c[] = $x - $dx;
404 1
                $c[] = $y + 0.87 * $dy; // tan(60)/2*$dx
405 1
                $c[] = $x;
406 1
                $c[] = $y - 0.87 * $dy;
407 1
                $c[] = $x + $dx;
408 1
                $c[] = $y + 0.87 * $dy;
409 1
                $c[] = $x - $dx;
410 1
                $c[] = $y + 0.87 * $dy; // tan(60)/2*$dx
411 1
                $pts = 4;
412
413 1
                break;
414 6
            case MARK_DTRIANGLE:
415
                ++$dx; ++$dy;
416
                $c[] = $x;
417
                $c[] = $y + 0.87 * $dy; // tan(60)/2*$dx
418
                $c[] = $x - $dx;
419
                $c[] = $y - 0.87 * $dy;
420
                $c[] = $x + $dx;
421
                $c[] = $y - 0.87 * $dy;
422
                $c[] = $x;
423
                $c[] = $y + 0.87 * $dy; // tan(60)/2*$dx
424
                $pts = 4;
425
426
                break;
427 6
            case MARK_DIAMOND:
428 2
                $c[] = $x;
429 2
                $c[] = $y + $dy;
430 2
                $c[] = $x - $dx;
431 2
                $c[] = $y;
432 2
                $c[] = $x;
433 2
                $c[] = $y - $dy;
434 2
                $c[] = $x + $dx;
435 2
                $c[] = $y;
436 2
                $c[] = $x;
437 2
                $c[] = $y + $dy;
438 2
                $pts = 5;
439
440 2
                break;
441 5
            case MARK_LEFTTRIANGLE:
442
                $c[] = $x;
443
                $c[] = $y;
444
                $c[] = $x;
445
                $c[] = $y + 2 * $dy;
446
                $c[] = $x + $dx * 2;
447
                $c[] = $y;
448
                $c[] = $x;
449
                $c[] = $y;
450
                $pts = 4;
451
452
                break;
453 5
            case MARK_RIGHTTRIANGLE:
454
                $c[] = $x - $dx * 2;
455
                $c[] = $y;
456
                $c[] = $x;
457
                $c[] = $y + 2 * $dy;
458
                $c[] = $x;
459
                $c[] = $y;
460
                $c[] = $x - $dx * 2;
461
                $c[] = $y;
462
                $pts = 4;
463
464
                break;
465 5
            case MARK_FLASH:
466
                $dy *= 2;
467
                $c[] = $x + $dx / 2;
468
                $c[] = $y - $dy;
469
                $c[] = $x - $dx + $dx / 2;
470
                $c[] = $y + $dy * 0.7 - $dy;
471
                $c[] = $x + $dx / 2;
472
                $c[] = $y + $dy * 1.3 - $dy;
473
                $c[] = $x - $dx + $dx / 2;
474
                $c[] = $y + 2 * $dy - $dy;
475
                $img->SetLineWeight($weight);
476
                $img->SetColor($color);
477
                $img->Polygon($c);
478
                $img->SetLineWeight(1);
479
                $this->AddCSIMPoly($c);
480
481
                break;
482
        }
483
484 6
        if ($pts > 0) {
485 3
            $this->AddCSIMPoly($c);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $c does not seem to be defined for all execution paths leading up to this point.
Loading history...
486 3
            $img->SetLineWeight($weight);
487 3
            $img->SetColor($fcolor);
488 3
            $img->FilledPolygon($c);
489 3
            $img->SetColor($color);
490 3
            $img->Polygon($c);
491 3
            $img->SetLineWeight(1);
492 5
        } elseif ($this->type == MARK_CIRCLE) {
493 1
            $img->SetColor($color);
494 1
            $img->Circle($x, $y, $width);
495 1
            $this->AddCSIMCircle($x, $y, $width);
496 5
        } elseif ($this->type == MARK_FILLEDCIRCLE) {
497 5
            $img->SetColor($fcolor);
498 5
            $img->FilledCircle($x, $y, $width);
499 5
            $img->SetColor($color);
500 5
            $img->Circle($x, $y, $width);
501 5
            $this->AddCSIMCircle($x, $y, $width);
502 2
        } elseif ($this->type == MARK_CROSS) {
503
            // Oversize by a pixel to match the X
504
            $img->SetColor($color);
505
            $img->SetLineWeight($weight);
506
            $img->Line($x, $y + $dy + 1, $x, $y - $dy - 1);
507
            $img->Line($x - $dx - 1, $y, $x + $dx + 1, $y);
508
            $this->AddCSIMCircle($x, $y, $dx);
509 2
        } elseif ($this->type == MARK_X) {
510
            $img->SetColor($color);
511
            $img->SetLineWeight($weight);
512
            $img->Line($x + $dx, $y + $dy, $x - $dx, $y - $dy);
513
            $img->Line($x - $dx, $y + $dy, $x + $dx, $y - $dy);
514
            $this->AddCSIMCircle($x, $y, $dx + $dy);
515 2
        } elseif ($this->type == MARK_STAR) {
516 2
            $img->SetColor($color);
517 2
            $img->SetLineWeight($weight);
518 2
            $img->Line($x + $dx, $y + $dy, $x - $dx, $y - $dy);
519 2
            $img->Line($x - $dx, $y + $dy, $x + $dx, $y - $dy);
520
            // Oversize by a pixel to match the X
521 2
            $img->Line($x, $y + $dy + 1, $x, $y - $dy - 1);
522 2
            $img->Line($x - $dx - 1, $y, $x + $dx + 1, $y);
523 2
            $this->AddCSIMCircle($x, $y, $dx + $dy);
524
        }
525
526
        // Stroke title
527 6
        $this->title->Align('center', 'center');
528 6
        $this->title->Stroke($img, $x, $y);
529 6
    }
530
} // @class
531