GanttBar::Stroke()   F
last analyzed

Complexity

Conditions 28
Paths 13506

Size

Total Lines 170
Code Lines 105

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 812

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 28
eloc 105
nc 13506
nop 2
dl 0
loc 170
ccs 0
cts 128
cp 0
crap 812
rs 0
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\Image;
11
use Amenadiel\JpGraph\Text;
12
use Amenadiel\JpGraph\Util;
13
14
/**
15
 * @class GanttBar
16
 * // Responsible for formatting individual gantt bars
17
 */
18
class GanttBar extends GanttPlotObject
19
{
20
    public $progress;
21
    public $leftMark;
22
    public $rightMark;
23
    private $iEnd;
24
    private $iHeightFactor    = 0.5;
25
    private $iFillColor       = 'white';
26
    private $iFrameColor      = 'black';
27
    private $iShadow          = false;
28
    private $iShadowColor     = 'darkgray';
29
    private $iShadowWidth     = 1;
30
    private $iShadowFrame     = 'black';
0 ignored issues
show
introduced by
The private property $iShadowFrame is not used, and could be removed.
Loading history...
31
    private $iPattern         = GANTT_RDIAG;
32
    private $iPatternColor    = 'blue';
33
    private $iPatternDensity  = 95;
34
    private $iBreakStyle      = false;
35
    private $iBreakLineStyle  = 'dotted';
36
    private $iBreakLineWeight = 1;
37
38
    /**
39
     * CONSTRUCTOR.
40
     *
41
     * @param mixed $aPos
42
     * @param mixed $aLabel
43
     * @param mixed $aStart
44
     * @param mixed $aEnd
45
     * @param mixed $aCaption
46
     * @param mixed $aHeightFactor
47
     */
48
    public function __construct($aPos, $aLabel, $aStart, $aEnd, $aCaption = '', $aHeightFactor = 0.6)
49
    {
50
        parent::__construct();
51
        $this->iStart = $aStart;
52
        // Is the end date given as a date or as number of days added to start date?
53
        if (is_string($aEnd)) {
54
            // If end date has been specified without a time we will asssume
55
            // end date is at the end of that date
56
            if (strpos($aEnd, ':') === false) {
57
                $this->iEnd = strtotime($aEnd) + SECPERDAY - 1;
58
            } else {
59
                $this->iEnd = $aEnd;
60
            }
61
        } elseif (is_int($aEnd) || is_float($aEnd)) {
62
            $this->iEnd = strtotime($aStart) + round($aEnd * SECPERDAY);
63
        }
64
        $this->iVPos         = $aPos;
65
        $this->iHeightFactor = $aHeightFactor;
66
        $this->title->Set($aLabel);
67
        $this->caption = new Text\TextProperty($aCaption);
68
        $this->caption->Align('left', 'center');
69
        $this->leftMark = new PlotMark();
70
        $this->leftMark->Hide();
71
        $this->rightMark = new PlotMark();
72
        $this->rightMark->Hide();
73
        $this->progress = new Image\Progress();
74
    }
75
76
    /**
77
     * PUBLIC METHODS.
78
     *
79
     * @param mixed $aShadow
80
     * @param mixed $aColor
81
     */
82
    public function SetShadow($aShadow = true, $aColor = 'gray')
83
    {
84
        $this->iShadow      = $aShadow;
85
        $this->iShadowColor = $aColor;
86
    }
87
88
    public function SetBreakStyle($aFlg = true, $aLineStyle = 'dotted', $aLineWeight = 1)
89
    {
90
        $this->iBreakStyle      = $aFlg;
91
        $this->iBreakLineStyle  = $aLineStyle;
92
        $this->iBreakLineWeight = $aLineWeight;
93
    }
94
95
    public function GetMaxDate()
96
    {
97
        return $this->iEnd;
98
    }
99
100
    public function SetHeight($aHeight)
101
    {
102
        $this->iHeightFactor = $aHeight;
103
    }
104
105
    public function SetColor($aColor)
106
    {
107
        $this->iFrameColor = $aColor;
108
    }
109
110
    public function SetFillColor($aColor)
111
    {
112
        $this->iFillColor = $aColor;
113
    }
114
115
    public function GetAbsHeight($aImg)
116
    {
117
        if (is_int($this->iHeightFactor) || $this->leftMark->show || $this->rightMark->show) {
118
            $m = -1;
119
            if (is_int($this->iHeightFactor)) {
120
                $m = $this->iHeightFactor;
121
            }
122
123
            if ($this->leftMark->show) {
124
                $m = max($m, $this->leftMark->width * 2);
125
            }
126
127
            if ($this->rightMark->show) {
128
                $m = max($m, $this->rightMark->width * 2);
129
            }
130
131
            return $m;
132
        }
133
134
        return -1;
135
    }
136
137
    public function SetPattern($aPattern, $aColor = 'blue', $aDensity = 95)
138
    {
139
        $this->iPattern        = $aPattern;
140
        $this->iPatternColor   = $aColor;
141
        $this->iPatternDensity = $aDensity;
142
    }
143
144
    public function Stroke($aImg, $aScale)
145
    {
146
        $factory = new Graph\RectPatternFactory();
147
        $prect   = $factory->Create($this->iPattern, $this->iPatternColor);
148
        $prect->SetDensity($this->iPatternDensity);
149
150
        // If height factor is specified as a float between 0,1 then we take it as meaning
151
        // percetage of the scale width between horizontal line.
152
        // If it is an integer > 1 we take it to mean the absolute height in pixels
153
        if ($this->iHeightFactor > -0.0 && $this->iHeightFactor <= 1.1) {
154
            $vs = $aScale->GetVertSpacing() * $this->iHeightFactor;
155
        } elseif (is_int($this->iHeightFactor) && $this->iHeightFactor > 2 && $this->iHeightFactor < 200) {
156
            $vs = $this->iHeightFactor;
157
        } else {
158
            Util\JpGraphError::RaiseL(6028, $this->iHeightFactor);
159
            //    ("Specified height (".$this->iHeightFactor.") for gantt bar is out of range.");
160
        }
161
162
        // Clip date to min max dates to show
163
        $st = $aScale->NormalizeDate($this->iStart);
164
        $en = $aScale->NormalizeDate($this->iEnd);
165
166
        $limst = max($st, $aScale->iStartDate);
167
        $limen = min($en, $aScale->iEndDate);
168
169
        $xt     = round($aScale->TranslateDate($limst));
170
        $xb     = round($aScale->TranslateDate($limen));
171
        $yt     = round($aScale->TranslateVertPos($this->iVPos) - $vs - ($aScale->GetVertSpacing() / 2 - $vs / 2));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $vs does not seem to be defined for all execution paths leading up to this point.
Loading history...
172
        $yb     = round($aScale->TranslateVertPos($this->iVPos) - ($aScale->GetVertSpacing() / 2 - $vs / 2));
173
        $middle = round($yt + ($yb - $yt) / 2);
174
        $this->StrokeActInfo($aImg, $aScale, $middle);
175
176
        // CSIM for title
177
        if (!empty($this->title->csimtarget)) {
178
            $colwidth  = $this->title->GetColWidth($aImg);
179
            $colstarts = [];
180
            $aScale->actinfo->GetColStart($aImg, $colstarts, true);
181
            $n = min(safe_count($colwidth), safe_count($this->title->csimtarget));
182
            for ($i = 0; $i < $n; ++$i) {
183
                $title_xt = $colstarts[$i];
184
                $title_xb = $title_xt + $colwidth[$i];
185
                $coords   = "${title_xt},${yt},${title_xb},${yt},${title_xb},${yb},${title_xt},${yb}";
186
187
                if (!empty($this->title->csimtarget[$i])) {
188
                    $this->csimarea .= "<area shape=\"poly\" coords=\"${coords}\" href=\"" . $this->title->csimtarget[$i] . '"';
189
190
                    if (!empty($this->title->csimwintarget[$i])) {
191
                        $this->csimarea .= 'target="' . $this->title->csimwintarget[$i] . '" ';
192
                    }
193
194
                    if (!empty($this->title->csimalt[$i])) {
195
                        $tmp = $this->title->csimalt[$i];
196
                        $this->csimarea .= " title=\"${tmp}\" alt=\"${tmp}\" ";
197
                    }
198
                    $this->csimarea .= " />\n";
199
                }
200
            }
201
        }
202
203
        // Check if the bar is totally outside the current scale range
204
        if ($en < $aScale->iStartDate || $st > $aScale->iEndDate) {
205
            return;
206
        }
207
208
        // Remember the positions for the bar
209
        $this->SetConstrainPos($xt, $yt, $xb, $yb);
210
211
        $prect->ShowFrame(false);
212
        $prect->SetBackground($this->iFillColor);
213
        if ($this->iBreakStyle) {
214
            $aImg->SetColor($this->iFrameColor);
215
            $olds = $aImg->SetLineStyle($this->iBreakLineStyle);
216
            $oldw = $aImg->SetLineWeight($this->iBreakLineWeight);
217
            $aImg->StyleLine($xt, $yt, $xb, $yt);
218
            $aImg->StyleLine($xt, $yb, $xb, $yb);
219
            $aImg->SetLineStyle($olds);
220
            $aImg->SetLineWeight($oldw);
221
        } else {
222
            if ($this->iShadow) {
223
                $aImg->SetColor($this->iFrameColor);
224
                $aImg->ShadowRectangle($xt, $yt, $xb, $yb, $this->iFillColor, $this->iShadowWidth, $this->iShadowColor);
225
                $prect->SetPos(new Util\Rectangle($xt + 1, $yt + 1, $xb - $xt - $this->iShadowWidth - 2, $yb - $yt - $this->iShadowWidth - 2));
226
                $prect->Stroke($aImg);
227
            } else {
228
                $prect->SetPos(new Util\Rectangle($xt, $yt, $xb - $xt + 1, $yb - $yt + 1));
229
                $prect->Stroke($aImg);
230
                $aImg->SetColor($this->iFrameColor);
231
                $aImg->Rectangle($xt, $yt, $xb, $yb);
232
            }
233
        }
234
        // CSIM for bar
235
        if (!empty($this->csimtarget)) {
236
            $coords = "${xt},${yt},${xb},${yt},${xb},${yb},${xt},${yb}";
237
            $this->csimarea .= "<area shape=\"poly\" coords=\"${coords}\" href=\"" . $this->csimtarget . '"';
238
239
            if (!empty($this->csimwintarget)) {
240
                $this->csimarea .= ' target="' . $this->csimwintarget . '" ';
241
            }
242
243
            if ($this->csimalt != '') {
244
                $tmp = $this->csimalt;
245
                $this->csimarea .= " title=\"${tmp}\" alt=\"${tmp}\" ";
246
            }
247
            $this->csimarea .= " />\n";
248
        }
249
250
        // Draw progress bar inside activity bar
251
        if ($this->progress->iProgress > 0) {
252
            $xtp = $aScale->TranslateDate($st);
253
            $xbp = $aScale->TranslateDate($en);
254
            $len = ($xbp - $xtp) * $this->progress->iProgress;
255
256
            $endpos = $xtp + $len;
257
            if ($endpos > $xt) {
258
                // Take away the length of the progress that is not visible (before the start date)
259
                $len -= ($xt - $xtp);
260
261
                // Is the the progress bar visible after the start date?
262
                if ($xtp < $xt) {
263
                    $xtp = $xt;
264
                }
265
266
                // Make sure that the progess bar doesn't extend over the end date
267
                if ($xtp + $len - 1 > $xb) {
268
                    $len = $xb - $xtp;
269
                }
270
271
                $prog = $factory->Create($this->progress->iPattern, $this->progress->iColor);
272
                $prog->SetDensity($this->progress->iDensity);
273
                $prog->SetBackground($this->progress->iFillColor);
274
                $barheight = ($yb - $yt + 1);
275
                if ($this->iShadow) {
276
                    $barheight -= $this->iShadowWidth;
277
                }
278
279
                $progressheight = floor($barheight * $this->progress->iHeight);
280
                $marg           = ceil(($barheight - $progressheight) / 2);
281
                $pos            = new Util\Rectangle($xtp, $yt + $marg, $len, $barheight - 2 * $marg);
282
                $prog->SetPos($pos);
283
                $prog->Stroke($aImg);
284
            }
285
        }
286
287
        // We don't plot the end mark if the bar has been capped
288
        if ($limst == $st) {
289
            $y = $middle;
290
            // We treat the RIGHT and LEFT triangle mark a little bi
291
            // special so that these marks are placed right under the
292
            // bar.
293
            if ($this->leftMark->GetType() == MARK_LEFTTRIANGLE) {
294
                $y = $yb;
295
            }
296
            $this->leftMark->Stroke($aImg, $xt, $y);
297
        }
298
        if ($limen == $en) {
299
            $y = $middle;
300
            // We treat the RIGHT and LEFT triangle mark a little bi
301
            // special so that these marks are placed right under the
302
            // bar.
303
            if ($this->rightMark->GetType() == MARK_RIGHTTRIANGLE) {
304
                $y = $yb;
305
            }
306
            $this->rightMark->Stroke($aImg, $xb, $y);
307
308
            $margin = $this->iCaptionMargin;
309
            if ($this->rightMark->show) {
310
                $margin += $this->rightMark->GetWidth();
311
            }
312
313
            $this->caption->Stroke($aImg, $xb + $margin, $middle);
314
        }
315
    }
316
}
317