Total Complexity | 179 |
Total Lines | 1221 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Complex classes like GanttScale 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 GanttScale, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
19 | class GanttScale |
||
20 | { |
||
21 | public $minute; |
||
22 | public $hour; |
||
23 | public $day; |
||
24 | public $week; |
||
25 | public $month; |
||
26 | public $year; |
||
27 | public $divider; |
||
28 | public $dividerh; |
||
29 | public $tableTitle; |
||
30 | public $iStartDate = -1; |
||
31 | public $iEndDate = -1; |
||
32 | // Number of gantt bar position (n.b not necessariliy the same as the number of bars) |
||
33 | // we could have on bar in position 1, and one bar in position 5 then there are two |
||
34 | // bars but the number of bar positions is 5 |
||
35 | public $actinfo; |
||
36 | public $iTopPlotMargin = 10; |
||
37 | public $iBottomPlotMargin = 15; |
||
38 | public $iVertLines = -1; |
||
39 | public $iVertHeaderSize = -1; |
||
40 | // The width of the labels (defaults to the widest of all labels) |
||
41 | private $iLabelWidth; |
||
42 | // Out image to stroke the scale to |
||
43 | private $iImg; |
||
44 | private $iTableHeaderBackgroundColor = 'white'; |
||
45 | private $iTableHeaderFrameColor = 'black'; |
||
46 | private $iTableHeaderFrameWeight = 1; |
||
47 | private $iAvailableHeight = -1; |
||
48 | private $iVertSpacing = -1; |
||
49 | private $iDateLocale; |
||
50 | private $iVertLayout = GANTT_EVEN; |
||
51 | private $iUsePlotWeekendBackground = true; |
||
52 | private $iWeekStart = 1; // Default to have weekends start on Monday |
||
53 | |||
54 | /** |
||
55 | * CONSTRUCTOR. |
||
56 | * |
||
57 | * @param mixed $aImg |
||
58 | */ |
||
59 | public function __construct($aImg) |
||
60 | { |
||
61 | $this->iImg = $aImg; |
||
62 | $this->iDateLocale = new Util\DateLocale(); |
||
63 | |||
64 | $this->minute = new HeaderProperty(); |
||
65 | $this->minute->SetIntervall(15); |
||
66 | $this->minute->SetLabelFormatString('i'); |
||
67 | $this->minute->SetFont(FF_FONT0); |
||
68 | $this->minute->grid->SetColor('gray'); |
||
69 | |||
70 | $this->hour = new HeaderProperty(); |
||
71 | $this->hour->SetFont(FF_FONT0); |
||
72 | $this->hour->SetIntervall(6); |
||
73 | $this->hour->SetStyle(HOURSTYLE_HM24); |
||
74 | $this->hour->SetLabelFormatString('H:i'); |
||
75 | $this->hour->grid->SetColor('gray'); |
||
76 | |||
77 | $this->day = new HeaderProperty(); |
||
78 | $this->day->grid->SetColor('gray'); |
||
79 | $this->day->SetLabelFormatString('l'); |
||
80 | |||
81 | $this->week = new HeaderProperty(); |
||
82 | $this->week->SetLabelFormatString('w%d'); |
||
83 | $this->week->SetFont(FF_FONT1); |
||
84 | |||
85 | $this->month = new HeaderProperty(); |
||
86 | $this->month->SetFont(FF_FONT1, FS_BOLD); |
||
87 | |||
88 | $this->year = new HeaderProperty(); |
||
89 | $this->year->SetFont(FF_FONT1, FS_BOLD); |
||
90 | |||
91 | $this->divider = new LineProperty(); |
||
92 | $this->dividerh = new LineProperty(); |
||
93 | $this->dividerh->SetWeight(2); |
||
94 | $this->divider->SetWeight(6); |
||
95 | $this->divider->SetColor('gray'); |
||
96 | $this->divider->SetStyle('fancy'); |
||
97 | |||
98 | $this->tableTitle = new Text\TextProperty(); |
||
99 | $this->tableTitle->Show(false); |
||
100 | $this->actinfo = new GanttActivityInfo(); |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * PUBLIC METHODS |
||
105 | * // Specify what headers should be visible. |
||
106 | * |
||
107 | * @param mixed $aFlg |
||
108 | */ |
||
109 | public function ShowHeaders($aFlg) |
||
110 | { |
||
111 | $this->day->Show($aFlg & GANTT_HDAY); |
||
112 | $this->week->Show($aFlg & GANTT_HWEEK); |
||
113 | $this->month->Show($aFlg & GANTT_HMONTH); |
||
114 | $this->year->Show($aFlg & GANTT_HYEAR); |
||
115 | $this->hour->Show($aFlg & GANTT_HHOUR); |
||
116 | $this->minute->Show($aFlg & GANTT_HMIN); |
||
117 | |||
118 | // Make some default settings of gridlines whihc makes sense |
||
119 | if ($aFlg & GANTT_HWEEK) { |
||
120 | $this->month->grid->Show(false); |
||
121 | $this->year->grid->Show(false); |
||
122 | } |
||
123 | if ($aFlg & GANTT_HHOUR) { |
||
124 | $this->day->grid->SetColor('black'); |
||
125 | } |
||
126 | } |
||
127 | |||
128 | // Should the weekend background stretch all the way down in the plotarea |
||
129 | public function UseWeekendBackground($aShow) |
||
130 | { |
||
131 | $this->iUsePlotWeekendBackground = $aShow; |
||
132 | } |
||
133 | |||
134 | // Have a range been specified? |
||
135 | public function IsRangeSet() |
||
136 | { |
||
137 | return $this->iStartDate != -1 && $this->iEndDate != -1; |
||
138 | } |
||
139 | |||
140 | // Should the layout be from top or even? |
||
141 | public function SetVertLayout($aLayout) |
||
142 | { |
||
143 | $this->iVertLayout = $aLayout; |
||
144 | } |
||
145 | |||
146 | // Which locale should be used? |
||
147 | public function SetDateLocale($aLocale) |
||
148 | { |
||
149 | $this->iDateLocale->Set($aLocale); |
||
150 | } |
||
151 | |||
152 | // Number of days we are showing |
||
153 | public function GetNumberOfDays() |
||
154 | { |
||
155 | return round(($this->iEndDate - $this->iStartDate) / SECPERDAY); |
||
156 | } |
||
157 | |||
158 | // The width of the actual plot area |
||
159 | public function GetPlotWidth() |
||
160 | { |
||
161 | $img = $this->iImg; |
||
162 | |||
163 | return $img->width - $img->left_margin - $img->right_margin; |
||
164 | } |
||
165 | |||
166 | // Specify the width of the titles(labels) for the activities |
||
167 | // (This is by default set to the minimum width enought for the |
||
168 | // widest title) |
||
169 | public function SetLabelWidth($aLabelWidth) |
||
170 | { |
||
171 | $this->iLabelWidth = $aLabelWidth; |
||
172 | } |
||
173 | |||
174 | // Which day should the week start? |
||
175 | // 0==Sun, 1==Monday, 2==Tuesday etc |
||
176 | public function SetWeekStart($aStartDay) |
||
177 | { |
||
178 | $this->iWeekStart = $aStartDay % 7; |
||
179 | |||
180 | //Recalculate the startday since this will change the week start |
||
181 | $this->SetRange($this->iStartDate, $this->iEndDate); |
||
182 | } |
||
183 | |||
184 | // Do we show min scale? |
||
185 | public function IsDisplayMinute() |
||
186 | { |
||
187 | return $this->minute->iShowLabels; |
||
188 | } |
||
189 | |||
190 | // Do we show day scale? |
||
191 | public function IsDisplayHour() |
||
192 | { |
||
193 | return $this->hour->iShowLabels; |
||
194 | } |
||
195 | |||
196 | // Do we show day scale? |
||
197 | public function IsDisplayDay() |
||
198 | { |
||
199 | return $this->day->iShowLabels; |
||
200 | } |
||
201 | |||
202 | // Do we show week scale? |
||
203 | public function IsDisplayWeek() |
||
204 | { |
||
205 | return $this->week->iShowLabels; |
||
206 | } |
||
207 | |||
208 | // Do we show month scale? |
||
209 | public function IsDisplayMonth() |
||
210 | { |
||
211 | return $this->month->iShowLabels; |
||
212 | } |
||
213 | |||
214 | // Do we show year scale? |
||
215 | public function IsDisplayYear() |
||
216 | { |
||
217 | return $this->year->iShowLabels; |
||
218 | } |
||
219 | |||
220 | // Specify spacing (in percent of bar height) between activity bars |
||
221 | public function SetVertSpacing($aSpacing) |
||
222 | { |
||
223 | $this->iVertSpacing = $aSpacing; |
||
224 | } |
||
225 | |||
226 | // Specify scale min and max date either as timestamp or as date strings |
||
227 | // Always round to the nearest week boundary |
||
228 | public function SetRange($aMin, $aMax) |
||
229 | { |
||
230 | $this->iStartDate = $this->NormalizeDate($aMin); |
||
231 | $this->iEndDate = $this->NormalizeDate($aMax); |
||
232 | } |
||
233 | |||
234 | // Adjust the start and end date so they fit to beginning/ending |
||
235 | // of the week taking the specified week start day into account. |
||
236 | public function AdjustStartEndDay() |
||
237 | { |
||
238 | if (!($this->IsDisplayYear() || $this->IsDisplayMonth() || $this->IsDisplayWeek())) { |
||
239 | // Don't adjust |
||
240 | return; |
||
241 | } |
||
242 | |||
243 | // Get day in week for start and ending date (Sun==0) |
||
244 | $ds = strftime('%w', $this->iStartDate); |
||
245 | $de = strftime('%w', $this->iEndDate); |
||
246 | |||
247 | // We want to start on iWeekStart day. But first we subtract a week |
||
248 | // if the startdate is "behind" the day the week start at. |
||
249 | // This way we ensure that the given start date is always included |
||
250 | // in the range. If we don't do this the nearest correct weekday in the week |
||
251 | // to start at might be later than the start date. |
||
252 | if ($ds < $this->iWeekStart) { |
||
253 | $d = strtotime('-7 day', $this->iStartDate); |
||
254 | } else { |
||
255 | $d = $this->iStartDate; |
||
256 | } |
||
257 | |||
258 | $adjdate = strtotime(($this->iWeekStart - $ds) . ' day', $d/*$this->iStartDate*/); |
||
259 | $this->iStartDate = $adjdate; |
||
260 | |||
261 | // We want to end on the last day of the week |
||
262 | $preferredEndDay = ($this->iWeekStart + 6) % 7; |
||
263 | if ($preferredEndDay != $de) { |
||
264 | // Solve equivalence eq: $de + x ~ $preferredDay (mod 7) |
||
265 | $adj = (7 + ($preferredEndDay - $de)) % 7; |
||
266 | $adjdate = strtotime("+${adj} day", $this->iEndDate); |
||
267 | $this->iEndDate = $adjdate; |
||
268 | } |
||
269 | } |
||
270 | |||
271 | // Specify background for the table title area (upper left corner of the table) |
||
272 | public function SetTableTitleBackground($aColor) |
||
273 | { |
||
274 | $this->iTableHeaderBackgroundColor = $aColor; |
||
275 | } |
||
276 | |||
277 | /////////////////////////////////////// |
||
278 | // PRIVATE Methods |
||
279 | |||
280 | // Determine the height of all the scale headers combined |
||
281 | public function GetHeaderHeight() |
||
282 | { |
||
283 | $img = $this->iImg; |
||
284 | $height = 1; |
||
285 | if ($this->minute->iShowLabels) { |
||
286 | $height += $this->minute->GetFontHeight($img); |
||
287 | $height += $this->minute->iTitleVertMargin; |
||
288 | } |
||
289 | if ($this->hour->iShowLabels) { |
||
290 | $height += $this->hour->GetFontHeight($img); |
||
291 | $height += $this->hour->iTitleVertMargin; |
||
292 | } |
||
293 | if ($this->day->iShowLabels) { |
||
294 | $height += $this->day->GetFontHeight($img); |
||
295 | $height += $this->day->iTitleVertMargin; |
||
296 | } |
||
297 | if ($this->week->iShowLabels) { |
||
298 | $height += $this->week->GetFontHeight($img); |
||
299 | $height += $this->week->iTitleVertMargin; |
||
300 | } |
||
301 | if ($this->month->iShowLabels) { |
||
302 | $height += $this->month->GetFontHeight($img); |
||
303 | $height += $this->month->iTitleVertMargin; |
||
304 | } |
||
305 | if ($this->year->iShowLabels) { |
||
306 | $height += $this->year->GetFontHeight($img); |
||
307 | $height += $this->year->iTitleVertMargin; |
||
308 | } |
||
309 | |||
310 | return $height; |
||
311 | } |
||
312 | |||
313 | // Get width (in pixels) for a single day |
||
314 | public function GetDayWidth() |
||
315 | { |
||
316 | return ($this->GetPlotWidth() - $this->iLabelWidth + 1) / $this->GetNumberOfDays(); |
||
317 | } |
||
318 | |||
319 | // Get width (in pixels) for a single hour |
||
320 | public function GetHourWidth() |
||
321 | { |
||
322 | return $this->GetDayWidth() / 24; |
||
323 | } |
||
324 | |||
325 | public function GetMinuteWidth() |
||
326 | { |
||
327 | return $this->GetHourWidth() / 60; |
||
328 | } |
||
329 | |||
330 | // Nuber of days in a year |
||
331 | public function GetNumDaysInYear($aYear) |
||
332 | { |
||
333 | if ($this->IsLeap($aYear)) { |
||
334 | return 366; |
||
335 | } |
||
336 | |||
337 | return 365; |
||
338 | } |
||
339 | |||
340 | // Get week number |
||
341 | public function GetWeekNbr($aDate, $aSunStart = true) |
||
342 | { |
||
343 | // We can't use the internal strftime() since it gets the weeknumber |
||
344 | // wrong since it doesn't follow ISO on all systems since this is |
||
345 | // system linrary dependent. |
||
346 | // Even worse is that this works differently if we are on a Windows |
||
347 | // or UNIX box (it even differs between UNIX boxes how strftime() |
||
348 | // is natively implemented) |
||
349 | // |
||
350 | // Credit to Nicolas Hoizey <[email protected]> for this elegant |
||
351 | // version of Week Nbr calculation. |
||
352 | |||
353 | $day = $this->NormalizeDate($aDate); |
||
354 | if ($aSunStart) { |
||
355 | $day += 60 * 60 * 24; |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * According to ISO-8601 : |
||
360 | * "Week 01 of a year is per definition the first week that has the Thursday in this year, |
||
361 | * which is equivalent to the week that contains the fourth day of January. |
||
362 | * In other words, the first week of a new year is the week that has the majority of its |
||
363 | * days in the new year.". |
||
364 | * |
||
365 | * Be carefull, with PHP, -3 % 7 = -3, instead of 4 !!! |
||
366 | * |
||
367 | * day of year = date("z", $day) + 1 |
||
368 | * offset to thursday = 3 - (date("w", $day) + 6) % 7 |
||
369 | * first thursday of year = 1 + (11 - date("w", mktime(0, 0, 0, 1, 1, date("Y", $day)))) % 7 |
||
370 | * week number = (thursday's day of year - first thursday's day of year) / 7 + 1 |
||
371 | * ---------------------------------------------------------------------------*/ |
||
372 | $thursday = $day + 60 * 60 * 24 * (3 - (date('w', $day) + 6) % 7); // take week's thursday |
||
|
|||
373 | $week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7; |
||
374 | |||
375 | return $week; |
||
376 | } |
||
377 | |||
378 | // Is year a leap year? |
||
379 | public function IsLeap($aYear) |
||
380 | { |
||
381 | // Is the year a leap year? |
||
382 | //$year = 0+date("Y",$aDate); |
||
383 | if ($aYear % 4 == 0) { |
||
384 | if (!($aYear % 100 == 0) || ($aYear % 400 == 0)) { |
||
385 | return true; |
||
386 | } |
||
387 | } |
||
388 | |||
389 | return false; |
||
390 | } |
||
391 | |||
392 | // Get current year |
||
393 | public function GetYear($aDate) |
||
394 | { |
||
395 | return 0 + date('Y', $aDate); |
||
396 | } |
||
397 | |||
398 | // Return number of days in a year |
||
399 | public function GetNumDaysInMonth($aMonth, $aYear) |
||
400 | { |
||
401 | $days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; |
||
402 | $daysl = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; |
||
403 | if ($this->IsLeap($aYear)) { |
||
404 | return $daysl[$aMonth]; |
||
405 | } |
||
406 | |||
407 | return $days[$aMonth]; |
||
408 | } |
||
409 | |||
410 | // Get day in month |
||
411 | public function GetMonthDayNbr($aDate) |
||
412 | { |
||
413 | return 0 + strftime('%d', $aDate); |
||
414 | } |
||
415 | |||
416 | // Get day in year |
||
417 | public function GetYearDayNbr($aDate) |
||
418 | { |
||
419 | return 0 + strftime('%j', $aDate); |
||
420 | } |
||
421 | |||
422 | // Get month number |
||
423 | public function GetMonthNbr($aDate) |
||
424 | { |
||
425 | return 0 + strftime('%m', $aDate); |
||
426 | } |
||
427 | |||
428 | // Translate a date to screen coordinates (horizontal scale) |
||
429 | public function TranslateDate($aDate) |
||
430 | { |
||
431 | // |
||
432 | // In order to handle the problem with Daylight savings time |
||
433 | // the scale written with equal number of seconds per day beginning |
||
434 | // with the start date. This means that we "cement" the state of |
||
435 | // DST as it is in the start date. If later the scale includes the |
||
436 | // switchover date (depends on the locale) we need to adjust back |
||
437 | // if the date we try to translate has a different DST status since |
||
438 | // we would otherwise be off by one hour. |
||
439 | $aDate = $this->NormalizeDate($aDate); |
||
440 | $tmp = localtime($aDate); |
||
441 | $cloc = $tmp[8]; |
||
442 | $tmp = localtime($this->iStartDate); |
||
443 | $sloc = $tmp[8]; |
||
444 | $offset = 0; |
||
445 | if ($sloc != $cloc) { |
||
446 | if ($sloc) { |
||
447 | $offset = 3600; |
||
448 | } else { |
||
449 | $offset = -3600; |
||
450 | } |
||
451 | } |
||
452 | $img = $this->iImg; |
||
453 | |||
454 | return ($aDate - $this->iStartDate - $offset) / SECPERDAY * $this->GetDayWidth() + $img->left_margin + $this->iLabelWidth; |
||
455 | } |
||
456 | |||
457 | // Get screen coordinatesz for the vertical position for a bar |
||
458 | public function TranslateVertPos($aPos, $atTop = false) |
||
459 | { |
||
460 | $img = $this->iImg; |
||
461 | if ($aPos > $this->iVertLines) { |
||
462 | Util\JpGraphError::RaiseL(6015, $aPos); |
||
463 | } |
||
464 | |||
465 | // 'Illegal vertical position %d' |
||
466 | if ($this->iVertLayout == GANTT_EVEN) { |
||
467 | // Position the top bar at 1 vert spacing from the scale |
||
468 | $pos = round($img->top_margin + $this->iVertHeaderSize + ($aPos + 1) * $this->iVertSpacing); |
||
469 | } else { |
||
470 | // position the top bar at 1/2 a vert spacing from the scale |
||
471 | $pos = round($img->top_margin + $this->iVertHeaderSize + $this->iTopPlotMargin + ($aPos + 1) * $this->iVertSpacing); |
||
472 | } |
||
473 | |||
474 | if ($atTop) { |
||
475 | $pos -= $this->iVertSpacing; |
||
476 | } |
||
477 | |||
478 | return $pos; |
||
479 | } |
||
480 | |||
481 | // What is the vertical spacing? |
||
482 | public function GetVertSpacing() |
||
483 | { |
||
484 | return $this->iVertSpacing; |
||
485 | } |
||
486 | |||
487 | // Convert a date to timestamp |
||
488 | public function NormalizeDate($aDate) |
||
489 | { |
||
490 | if ($aDate === false) { |
||
491 | return false; |
||
492 | } |
||
493 | |||
494 | if (is_string($aDate)) { |
||
495 | $t = strtotime($aDate); |
||
496 | if ($t === false || $t === -1) { |
||
497 | Util\JpGraphError::RaiseL(6016, $aDate); |
||
498 | //("Date string ($aDate) specified for Gantt activity can not be interpretated. Please make sure it is a valid time string, e.g. 2005-04-23 13:30"); |
||
499 | } |
||
500 | |||
501 | return $t; |
||
502 | } |
||
503 | if (is_int($aDate) || is_float($aDate)) { |
||
504 | return $aDate; |
||
505 | } |
||
506 | Util\JpGraphError::RaiseL(6017, $aDate); |
||
507 | |||
508 | //Unknown date format in GanttScale ($aDate)."); |
||
509 | } |
||
510 | |||
511 | // Convert a time string to minutes |
||
512 | |||
513 | public function TimeToMinutes($aTimeString) |
||
514 | { |
||
515 | // Split in hours and minutes |
||
516 | $pos = strpos($aTimeString, ':'); |
||
517 | $minint = 60; |
||
518 | if ($pos === false) { |
||
519 | $hourint = $aTimeString; |
||
520 | $minint = 0; |
||
521 | } else { |
||
522 | $hourint = floor(substr($aTimeString, 0, $pos)); |
||
523 | $minint = floor(substr($aTimeString, $pos + 1)); |
||
524 | } |
||
525 | $minint += 60 * $hourint; |
||
526 | |||
527 | return $minint; |
||
528 | } |
||
529 | |||
530 | // Stroke the day scale (including gridlines) |
||
531 | public function StrokeMinutes($aYCoord, $getHeight = false) |
||
532 | { |
||
533 | $img = $this->iImg; |
||
534 | $xt = $img->left_margin + $this->iLabelWidth; |
||
535 | $yt = $aYCoord + $img->top_margin; |
||
536 | if ($this->minute->iShowLabels) { |
||
537 | $img->SetFont($this->minute->iFFamily, $this->minute->iFStyle, $this->minute->iFSize); |
||
538 | $yb = $yt + $img->GetFontHeight() + |
||
539 | $this->minute->iTitleVertMargin + $this->minute->iFrameWeight; |
||
540 | if ($getHeight) { |
||
541 | return $yb - $img->top_margin; |
||
542 | } |
||
543 | $xb = $img->width - $img->right_margin + 1; |
||
544 | $img->SetColor($this->minute->iBackgroundColor); |
||
545 | $img->FilledRectangle($xt, $yt, $xb, $yb); |
||
546 | |||
547 | $x = $xt; |
||
548 | $img->SetTextAlign('center'); |
||
549 | $day = date('w', $this->iStartDate); |
||
550 | $minint = $this->minute->GetIntervall(); |
||
551 | |||
552 | if (60 % $minint !== 0) { |
||
553 | Util\JpGraphError::RaiseL(6018, $minint); |
||
554 | //'Intervall for minutes must divide the hour evenly, e.g. 1,5,10,12,15,20,30 etc You have specified an intervall of '.$minint.' minutes.'); |
||
555 | } |
||
556 | |||
557 | $n = 60 / $minint; |
||
558 | $datestamp = $this->iStartDate; |
||
559 | $width = $this->GetHourWidth() / $n; |
||
560 | if ($width < 8) { |
||
561 | // TO small width to draw minute scale |
||
562 | Util\JpGraphError::RaiseL(6019, $width); |
||
563 | //('The available width ('.$width.') for minutes are to small for this scale to be displayed. Please use auto-sizing or increase the width of the graph.'); |
||
564 | } |
||
565 | |||
566 | $nh = ceil(24 * 60 / $this->TimeToMinutes($this->hour->GetIntervall())); |
||
567 | $nd = $this->GetNumberOfDays(); |
||
568 | // Convert to intervall to seconds |
||
569 | $minint *= 60; |
||
570 | for ($j = 0; $j < $nd; ++$j, ++$day, $day %= 7) { |
||
571 | for ($k = 0; $k < $nh; ++$k) { |
||
572 | for ($i = 0; $i < $n; ++$i, $x += $width, $datestamp += $minint) { |
||
573 | if ($day == 6 || $day == 0) { |
||
574 | $img->PushColor($this->day->iWeekendBackgroundColor); |
||
575 | if ($this->iUsePlotWeekendBackground) { |
||
576 | $img->FilledRectangle($x, $yt + $this->day->iFrameWeight, $x + $width, $img->height - $img->bottom_margin); |
||
577 | } else { |
||
578 | $img->FilledRectangle($x, $yt + $this->day->iFrameWeight, $x + $width, $yb - $this->day->iFrameWeight); |
||
579 | } |
||
580 | |||
581 | $img->PopColor(); |
||
582 | } |
||
583 | |||
584 | if ($day == 0) { |
||
585 | $img->SetColor($this->day->iSundayTextColor); |
||
586 | } else { |
||
587 | $img->SetColor($this->day->iTextColor); |
||
588 | } |
||
589 | |||
590 | switch ($this->minute->iStyle) { |
||
591 | case MINUTESTYLE_CUSTOM: |
||
592 | $txt = date($this->minute->iLabelFormStr, $datestamp); |
||
593 | |||
594 | break; |
||
595 | case MINUTESTYLE_MM: |
||
596 | default: |
||
597 | // 15 |
||
598 | $txt = date('i', $datestamp); |
||
599 | |||
600 | break; |
||
601 | } |
||
602 | $img->StrokeText(round($x + $width / 2), round($yb - $this->minute->iTitleVertMargin), $txt); |
||
603 | |||
604 | // Fix a rounding problem the wrong way .. |
||
605 | // If we also have hour scale then don't draw the firsta or last |
||
606 | // gridline since that will be overwritten by the hour scale gridline if such exists. |
||
607 | // However, due to the propagation of rounding of the 'x+=width' term in the loop |
||
608 | // this might sometimes be one pixel of so we fix this by not drawing it. |
||
609 | // The proper way to fix it would be to re-calculate the scale for each step and |
||
610 | // not using the additive term. |
||
611 | if (!(($i == $n || $i == 0) && $this->hour->iShowLabels && $this->hour->grid->iShow)) { |
||
612 | $img->SetColor($this->minute->grid->iColor); |
||
613 | $img->SetLineWeight($this->minute->grid->iWeight); |
||
614 | $img->Line($x, $yt, $x, $yb); |
||
615 | $this->minute->grid->Stroke($img, $x, $yb, $x, $img->height - $img->bottom_margin); |
||
616 | } |
||
617 | } |
||
618 | } |
||
619 | } |
||
620 | $img->SetColor($this->minute->iFrameColor); |
||
621 | $img->SetLineWeight($this->minute->iFrameWeight); |
||
622 | $img->Rectangle($xt, $yt, $xb, $yb); |
||
623 | |||
624 | return $yb - $img->top_margin; |
||
625 | } |
||
626 | |||
627 | return $aYCoord; |
||
628 | } |
||
629 | |||
630 | // Stroke the day scale (including gridlines) |
||
631 | public function StrokeHours($aYCoord, $getHeight = false) |
||
632 | { |
||
633 | $img = $this->iImg; |
||
634 | $xt = $img->left_margin + $this->iLabelWidth; |
||
635 | $yt = $aYCoord + $img->top_margin; |
||
636 | if ($this->hour->iShowLabels) { |
||
637 | $img->SetFont($this->hour->iFFamily, $this->hour->iFStyle, $this->hour->iFSize); |
||
638 | $yb = $yt + $img->GetFontHeight() + |
||
639 | $this->hour->iTitleVertMargin + $this->hour->iFrameWeight; |
||
640 | if ($getHeight) { |
||
641 | return $yb - $img->top_margin; |
||
642 | } |
||
643 | $xb = $img->width - $img->right_margin + 1; |
||
644 | $img->SetColor($this->hour->iBackgroundColor); |
||
645 | $img->FilledRectangle($xt, $yt, $xb, $yb); |
||
646 | |||
647 | $x = $xt; |
||
648 | $img->SetTextAlign('center'); |
||
649 | $tmp = $this->hour->GetIntervall(); |
||
650 | $minint = $this->TimeToMinutes($tmp); |
||
651 | if (1440 % $minint !== 0) { |
||
652 | Util\JpGraphError::RaiseL(6020, $tmp); |
||
653 | //('Intervall for hours must divide the day evenly, e.g. 0:30, 1:00, 1:30, 4:00 etc. You have specified an intervall of '.$tmp); |
||
654 | } |
||
655 | |||
656 | $n = ceil(24 * 60 / $minint); |
||
657 | $datestamp = $this->iStartDate; |
||
658 | $day = date('w', $this->iStartDate); |
||
659 | $doback = !$this->minute->iShowLabels; |
||
660 | $width = $this->GetDayWidth() / $n; |
||
661 | for ($j = 0; $j < $this->GetNumberOfDays(); ++$j, ++$day, $day %= 7) { |
||
662 | for ($i = 0; $i < $n; ++$i, $x += $width) { |
||
663 | if ($day == 6 || $day == 0) { |
||
664 | $img->PushColor($this->day->iWeekendBackgroundColor); |
||
665 | if ($this->iUsePlotWeekendBackground && $doback) { |
||
666 | $img->FilledRectangle($x, $yt + $this->day->iFrameWeight, $x + $width, $img->height - $img->bottom_margin); |
||
667 | } else { |
||
668 | $img->FilledRectangle($x, $yt + $this->day->iFrameWeight, $x + $width, $yb - $this->day->iFrameWeight); |
||
669 | } |
||
670 | |||
671 | $img->PopColor(); |
||
672 | } |
||
673 | |||
674 | if ($day == 0) { |
||
675 | $img->SetColor($this->day->iSundayTextColor); |
||
676 | } else { |
||
677 | $img->SetColor($this->day->iTextColor); |
||
678 | } |
||
679 | |||
680 | switch ($this->hour->iStyle) { |
||
681 | case HOURSTYLE_HMAMPM: |
||
682 | // 1:35pm |
||
683 | $txt = date('g:ia', $datestamp); |
||
684 | |||
685 | break; |
||
686 | case HOURSTYLE_H24: |
||
687 | // 13 |
||
688 | $txt = date('H', $datestamp); |
||
689 | |||
690 | break; |
||
691 | case HOURSTYLE_HAMPM: |
||
692 | $txt = date('ga', $datestamp); |
||
693 | |||
694 | break; |
||
695 | case HOURSTYLE_CUSTOM: |
||
696 | $txt = date($this->hour->iLabelFormStr, $datestamp); |
||
697 | |||
698 | break; |
||
699 | case HOURSTYLE_HM24: |
||
700 | default: |
||
701 | $txt = date('H:i', $datestamp); |
||
702 | |||
703 | break; |
||
704 | } |
||
705 | $img->StrokeText(round($x + $width / 2), round($yb - $this->hour->iTitleVertMargin), $txt); |
||
706 | $img->SetColor($this->hour->grid->iColor); |
||
707 | $img->SetLineWeight($this->hour->grid->iWeight); |
||
708 | $img->Line($x, $yt, $x, $yb); |
||
709 | $this->hour->grid->Stroke($img, $x, $yb, $x, $img->height - $img->bottom_margin); |
||
710 | //$datestamp += $minint*60 |
||
711 | $datestamp = mktime( |
||
712 | date('H', $datestamp), |
||
713 | date('i', $datestamp) + $minint, |
||
714 | 0, |
||
715 | date('m', $datestamp), |
||
716 | date('d', $datestamp) + 1, |
||
717 | date('Y', $datestamp) |
||
718 | ); |
||
719 | } |
||
720 | } |
||
721 | $img->SetColor($this->hour->iFrameColor); |
||
722 | $img->SetLineWeight($this->hour->iFrameWeight); |
||
723 | $img->Rectangle($xt, $yt, $xb, $yb); |
||
724 | |||
725 | return $yb - $img->top_margin; |
||
726 | } |
||
727 | |||
728 | return $aYCoord; |
||
729 | } |
||
730 | |||
731 | // Stroke the day scale (including gridlines) |
||
732 | public function StrokeDays($aYCoord, $getHeight = false) |
||
733 | { |
||
734 | $img = $this->iImg; |
||
735 | $daywidth = $this->GetDayWidth(); |
||
736 | $xt = $img->left_margin + $this->iLabelWidth; |
||
737 | $yt = $aYCoord + $img->top_margin; |
||
738 | if ($this->day->iShowLabels) { |
||
739 | $img->SetFont($this->day->iFFamily, $this->day->iFStyle, $this->day->iFSize); |
||
740 | $yb = $yt + $img->GetFontHeight() + $this->day->iTitleVertMargin + $this->day->iFrameWeight; |
||
741 | if ($getHeight) { |
||
742 | return $yb - $img->top_margin; |
||
743 | } |
||
744 | $xb = $img->width - $img->right_margin + 1; |
||
745 | $img->SetColor($this->day->iBackgroundColor); |
||
746 | $img->FilledRectangle($xt, $yt, $xb, $yb); |
||
747 | |||
748 | $x = $xt; |
||
749 | $img->SetTextAlign('center'); |
||
750 | $day = date('w', $this->iStartDate); |
||
751 | $datestamp = $this->iStartDate; |
||
752 | |||
753 | $doback = !($this->hour->iShowLabels || $this->minute->iShowLabels); |
||
754 | |||
755 | setlocale(LC_TIME, $this->iDateLocale->iLocale); |
||
756 | |||
757 | for ($i = 0; $i < $this->GetNumberOfDays(); ++$i, $x += $daywidth, ++$day, $day %= 7) { |
||
758 | if ($day == 6 || $day == 0) { |
||
759 | $img->SetColor($this->day->iWeekendBackgroundColor); |
||
760 | if ($this->iUsePlotWeekendBackground && $doback) { |
||
761 | $img->FilledRectangle( |
||
762 | $x, |
||
763 | $yt + $this->day->iFrameWeight, |
||
764 | $x + $daywidth, |
||
765 | $img->height - $img->bottom_margin |
||
766 | ); |
||
767 | } else { |
||
768 | $img->FilledRectangle( |
||
769 | $x, |
||
770 | $yt + $this->day->iFrameWeight, |
||
771 | $x + $daywidth, |
||
772 | $yb - $this->day->iFrameWeight |
||
773 | ); |
||
774 | } |
||
775 | } |
||
776 | |||
777 | $mn = strftime('%m', $datestamp); |
||
778 | if ($mn[0] == '0') { |
||
779 | $mn = $mn[1]; |
||
780 | } |
||
781 | |||
782 | switch ($this->day->iStyle) { |
||
783 | case DAYSTYLE_LONG: |
||
784 | // "Monday" |
||
785 | $txt = strftime('%A', $datestamp); |
||
786 | |||
787 | break; |
||
788 | case DAYSTYLE_SHORT: |
||
789 | // "Mon" |
||
790 | $txt = strftime('%a', $datestamp); |
||
791 | |||
792 | break; |
||
793 | case DAYSTYLE_SHORTDAYDATE1: |
||
794 | // "Mon 23/6" |
||
795 | $txt = strftime('%a %d/' . $mn, $datestamp); |
||
796 | |||
797 | break; |
||
798 | case DAYSTYLE_SHORTDAYDATE2: |
||
799 | // "Mon 23 Jun" |
||
800 | $txt = strftime('%a %d %b', $datestamp); |
||
801 | |||
802 | break; |
||
803 | case DAYSTYLE_SHORTDAYDATE3: |
||
804 | // "Mon 23 Jun 2003" |
||
805 | $txt = strftime('%a %d %b %Y', $datestamp); |
||
806 | |||
807 | break; |
||
808 | case DAYSTYLE_LONGDAYDATE1: |
||
809 | // "Monday 23 Jun" |
||
810 | $txt = strftime('%A %d %b', $datestamp); |
||
811 | |||
812 | break; |
||
813 | case DAYSTYLE_LONGDAYDATE2: |
||
814 | // "Monday 23 Jun 2003" |
||
815 | $txt = strftime('%A %d %b %Y', $datestamp); |
||
816 | |||
817 | break; |
||
818 | case DAYSTYLE_SHORTDATE1: |
||
819 | // "23/6" |
||
820 | $txt = strftime('%d/' . $mn, $datestamp); |
||
821 | |||
822 | break; |
||
823 | case DAYSTYLE_SHORTDATE2: |
||
824 | // "23 Jun" |
||
825 | $txt = strftime('%d %b', $datestamp); |
||
826 | |||
827 | break; |
||
828 | case DAYSTYLE_SHORTDATE3: |
||
829 | // "Mon 23" |
||
830 | $txt = strftime('%a %d', $datestamp); |
||
831 | |||
832 | break; |
||
833 | case DAYSTYLE_SHORTDATE4: |
||
834 | // "23" |
||
835 | $txt = strftime('%d', $datestamp); |
||
836 | |||
837 | break; |
||
838 | case DAYSTYLE_CUSTOM: |
||
839 | // Custom format |
||
840 | $txt = strftime($this->day->iLabelFormStr, $datestamp); |
||
841 | |||
842 | break; |
||
843 | case DAYSTYLE_ONELETTER: |
||
844 | default: |
||
845 | // "M" |
||
846 | $txt = strftime('%A', $datestamp); |
||
847 | $txt = strtoupper($txt[0]); |
||
848 | |||
849 | break; |
||
850 | } |
||
851 | |||
852 | if ($day == 0) { |
||
853 | $img->SetColor($this->day->iSundayTextColor); |
||
854 | } else { |
||
855 | $img->SetColor($this->day->iTextColor); |
||
856 | } |
||
857 | |||
858 | $img->StrokeText( |
||
859 | round($x + $daywidth / 2 + 1), |
||
860 | round($yb - $this->day->iTitleVertMargin), |
||
861 | $txt |
||
862 | ); |
||
863 | $img->SetColor($this->day->grid->iColor); |
||
864 | $img->SetLineWeight($this->day->grid->iWeight); |
||
865 | $img->Line($x, $yt, $x, $yb); |
||
866 | $this->day->grid->Stroke($img, $x, $yb, $x, $img->height - $img->bottom_margin); |
||
867 | $datestamp = mktime(0, 0, 0, date('m', $datestamp), date('d', $datestamp) + 1, date('Y', $datestamp)); |
||
868 | //$datestamp += SECPERDAY; |
||
869 | } |
||
870 | $img->SetColor($this->day->iFrameColor); |
||
871 | $img->SetLineWeight($this->day->iFrameWeight); |
||
872 | $img->Rectangle($xt, $yt, $xb, $yb); |
||
873 | |||
874 | return $yb - $img->top_margin; |
||
875 | } |
||
876 | |||
877 | return $aYCoord; |
||
878 | } |
||
879 | |||
880 | // Stroke week header and grid |
||
881 | public function StrokeWeeks($aYCoord, $getHeight = false) |
||
882 | { |
||
883 | if ($this->week->iShowLabels) { |
||
884 | $img = $this->iImg; |
||
885 | $yt = $aYCoord + $img->top_margin; |
||
886 | $img->SetFont($this->week->iFFamily, $this->week->iFStyle, $this->week->iFSize); |
||
887 | $yb = $yt + $img->GetFontHeight() + $this->week->iTitleVertMargin + $this->week->iFrameWeight; |
||
888 | |||
889 | if ($getHeight) { |
||
890 | return $yb - $img->top_margin; |
||
891 | } |
||
892 | |||
893 | $xt = $img->left_margin + $this->iLabelWidth; |
||
894 | $weekwidth = $this->GetDayWidth() * 7; |
||
895 | $wdays = $this->iDateLocale->GetDayAbb(); |
||
896 | $xb = $img->width - $img->right_margin + 1; |
||
897 | $week = $this->iStartDate; |
||
898 | $weeknbr = $this->GetWeekNbr($week); |
||
899 | $img->SetColor($this->week->iBackgroundColor); |
||
900 | $img->FilledRectangle($xt, $yt, $xb, $yb); |
||
901 | $img->SetColor($this->week->grid->iColor); |
||
902 | $x = $xt; |
||
903 | if ($this->week->iStyle == WEEKSTYLE_WNBR) { |
||
904 | $img->SetTextAlign('center'); |
||
905 | $txtOffset = $weekwidth / 2 + 1; |
||
906 | } elseif ($this->week->iStyle == WEEKSTYLE_FIRSTDAY || |
||
907 | $this->week->iStyle == WEEKSTYLE_FIRSTDAY2 || |
||
908 | $this->week->iStyle == WEEKSTYLE_FIRSTDAYWNBR || |
||
909 | $this->week->iStyle == WEEKSTYLE_FIRSTDAY2WNBR) { |
||
910 | $img->SetTextAlign('left'); |
||
911 | $txtOffset = 3; |
||
912 | } else { |
||
913 | Util\JpGraphError::RaiseL(6021); |
||
914 | //("Unknown formatting style for week."); |
||
915 | } |
||
916 | |||
917 | for ($i = 0; $i < $this->GetNumberOfDays() / 7; ++$i, $x += $weekwidth) { |
||
918 | $img->PushColor($this->week->iTextColor); |
||
919 | |||
920 | if ($this->week->iStyle == WEEKSTYLE_WNBR) { |
||
921 | $txt = sprintf($this->week->iLabelFormStr, $weeknbr); |
||
922 | } elseif ($this->week->iStyle == WEEKSTYLE_FIRSTDAY || |
||
923 | $this->week->iStyle == WEEKSTYLE_FIRSTDAYWNBR) { |
||
924 | $txt = date('j/n', $week); |
||
925 | } elseif ($this->week->iStyle == WEEKSTYLE_FIRSTDAY2 || |
||
926 | $this->week->iStyle == WEEKSTYLE_FIRSTDAY2WNBR) { |
||
927 | $monthnbr = date('n', $week) - 1; |
||
928 | $shortmonth = $this->iDateLocale->GetShortMonthName($monthnbr); |
||
929 | $txt = date('j', $week) . ' ' . $shortmonth; |
||
930 | } |
||
931 | |||
932 | if ($this->week->iStyle == WEEKSTYLE_FIRSTDAYWNBR || |
||
933 | $this->week->iStyle == WEEKSTYLE_FIRSTDAY2WNBR) { |
||
934 | $w = sprintf($this->week->iLabelFormStr, $weeknbr); |
||
935 | $txt .= ' ' . $w; |
||
936 | } |
||
937 | |||
938 | $img->StrokeText( |
||
939 | round($x + $txtOffset), |
||
940 | round($yb - $this->week->iTitleVertMargin), |
||
941 | $txt |
||
942 | ); |
||
943 | |||
944 | $week = strtotime('+7 day', $week); |
||
945 | $weeknbr = $this->GetWeekNbr($week); |
||
946 | $img->PopColor(); |
||
947 | $img->SetLineWeight($this->week->grid->iWeight); |
||
948 | $img->Line($x, $yt, $x, $yb); |
||
949 | $this->week->grid->Stroke($img, $x, $yb, $x, $img->height - $img->bottom_margin); |
||
950 | } |
||
951 | $img->SetColor($this->week->iFrameColor); |
||
952 | $img->SetLineWeight($this->week->iFrameWeight); |
||
953 | $img->Rectangle($xt, $yt, $xb, $yb); |
||
954 | |||
955 | return $yb - $img->top_margin; |
||
956 | } |
||
957 | |||
958 | return $aYCoord; |
||
959 | } |
||
960 | |||
961 | // Format the mont scale header string |
||
962 | public function GetMonthLabel($aMonthNbr, $year) |
||
998 | } |
||
999 | |||
1000 | // Stroke month scale and gridlines |
||
1001 | public function StrokeMonths($aYCoord, $getHeight = false) |
||
1002 | { |
||
1003 | if ($this->month->iShowLabels) { |
||
1004 | $img = $this->iImg; |
||
1005 | $img->SetFont($this->month->iFFamily, $this->month->iFStyle, $this->month->iFSize); |
||
1006 | $yt = $aYCoord + $img->top_margin; |
||
1007 | $yb = $yt + $img->GetFontHeight() + $this->month->iTitleVertMargin + $this->month->iFrameWeight; |
||
1008 | if ($getHeight) { |
||
1009 | return $yb - $img->top_margin; |
||
1010 | } |
||
1011 | $monthnbr = $this->GetMonthNbr($this->iStartDate) - 1; |
||
1012 | $xt = $img->left_margin + $this->iLabelWidth; |
||
1013 | $xb = $img->width - $img->right_margin + 1; |
||
1014 | |||
1015 | $img->SetColor($this->month->iBackgroundColor); |
||
1016 | $img->FilledRectangle($xt, $yt, $xb, $yb); |
||
1017 | |||
1018 | $img->SetLineWeight($this->month->grid->iWeight); |
||
1019 | $img->SetColor($this->month->iTextColor); |
||
1020 | $year = 0 + strftime('%Y', $this->iStartDate); |
||
1021 | $img->SetTextAlign('center'); |
||
1022 | if ($this->GetMonthNbr($this->iStartDate) == $this->GetMonthNbr($this->iEndDate) |
||
1023 | && $this->GetYear($this->iStartDate) == $this->GetYear($this->iEndDate)) { |
||
1024 | $monthwidth = $this->GetDayWidth() * ($this->GetMonthDayNbr($this->iEndDate) - $this->GetMonthDayNbr($this->iStartDate) + 1); |
||
1025 | } else { |
||
1026 | $monthwidth = $this->GetDayWidth() * ($this->GetNumDaysInMonth($monthnbr, $year) - $this->GetMonthDayNbr($this->iStartDate) + 1); |
||
1027 | } |
||
1028 | // Is it enough space to stroke the first month? |
||
1029 | $monthName = $this->GetMonthLabel($monthnbr, $year); |
||
1030 | if ($monthwidth >= 1.2 * $img->GetTextWidth($monthName)) { |
||
1031 | $img->SetColor($this->month->iTextColor); |
||
1032 | $img->StrokeText( |
||
1033 | round($xt + $monthwidth / 2 + 1), |
||
1034 | round($yb - $this->month->iTitleVertMargin), |
||
1035 | $monthName |
||
1036 | ); |
||
1037 | } |
||
1038 | $x = $xt + $monthwidth; |
||
1039 | while ($x < $xb) { |
||
1040 | $img->SetColor($this->month->grid->iColor); |
||
1041 | $img->Line($x, $yt, $x, $yb); |
||
1042 | $this->month->grid->Stroke($img, $x, $yb, $x, $img->height - $img->bottom_margin); |
||
1043 | ++$monthnbr; |
||
1044 | if ($monthnbr == 12) { |
||
1045 | $monthnbr = 0; |
||
1046 | ++$year; |
||
1047 | } |
||
1048 | $monthName = $this->GetMonthLabel($monthnbr, $year); |
||
1049 | $monthwidth = $this->GetDayWidth() * $this->GetNumDaysInMonth($monthnbr, $year); |
||
1050 | if ($x + $monthwidth < $xb) { |
||
1051 | $w = $monthwidth; |
||
1052 | } else { |
||
1053 | $w = $xb - $x; |
||
1054 | } |
||
1055 | |||
1056 | if ($w >= 1.2 * $img->GetTextWidth($monthName)) { |
||
1057 | $img->SetColor($this->month->iTextColor); |
||
1058 | $img->StrokeText( |
||
1059 | round($x + $w / 2 + 1), |
||
1060 | round($yb - $this->month->iTitleVertMargin), |
||
1061 | $monthName |
||
1062 | ); |
||
1063 | } |
||
1064 | $x += $monthwidth; |
||
1065 | } |
||
1066 | $img->SetColor($this->month->iFrameColor); |
||
1067 | $img->SetLineWeight($this->month->iFrameWeight); |
||
1068 | $img->Rectangle($xt, $yt, $xb, $yb); |
||
1069 | |||
1070 | return $yb - $img->top_margin; |
||
1071 | } |
||
1072 | |||
1073 | return $aYCoord; |
||
1074 | } |
||
1075 | |||
1076 | // Stroke year scale and gridlines |
||
1077 | public function StrokeYears($aYCoord, $getHeight = false) |
||
1078 | { |
||
1079 | if ($this->year->iShowLabels) { |
||
1080 | $img = $this->iImg; |
||
1081 | $yt = $aYCoord + $img->top_margin; |
||
1082 | $img->SetFont($this->year->iFFamily, $this->year->iFStyle, $this->year->iFSize); |
||
1083 | $yb = $yt + $img->GetFontHeight() + $this->year->iTitleVertMargin + $this->year->iFrameWeight; |
||
1084 | |||
1085 | if ($getHeight) { |
||
1086 | return $yb - $img->top_margin; |
||
1087 | } |
||
1088 | |||
1089 | $xb = $img->width - $img->right_margin + 1; |
||
1090 | $xt = $img->left_margin + $this->iLabelWidth; |
||
1091 | $year = $this->GetYear($this->iStartDate); |
||
1092 | $img->SetColor($this->year->iBackgroundColor); |
||
1093 | $img->FilledRectangle($xt, $yt, $xb, $yb); |
||
1094 | $img->SetLineWeight($this->year->grid->iWeight); |
||
1095 | $img->SetTextAlign('center'); |
||
1096 | if ($year == $this->GetYear($this->iEndDate)) { |
||
1097 | $yearwidth = $this->GetDayWidth() * ($this->GetYearDayNbr($this->iEndDate) - $this->GetYearDayNbr($this->iStartDate) + 1); |
||
1098 | } else { |
||
1099 | $yearwidth = $this->GetDayWidth() * ($this->GetNumDaysInYear($year) - $this->GetYearDayNbr($this->iStartDate) + 1); |
||
1100 | } |
||
1101 | |||
1102 | // The space for a year must be at least 20% bigger than the actual text |
||
1103 | // so we allow 10% margin on each side |
||
1104 | if ($yearwidth >= 1.20 * $img->GetTextWidth('' . $year)) { |
||
1105 | $img->SetColor($this->year->iTextColor); |
||
1106 | $img->StrokeText( |
||
1107 | round($xt + $yearwidth / 2 + 1), |
||
1108 | round($yb - $this->year->iTitleVertMargin), |
||
1109 | $year |
||
1110 | ); |
||
1111 | } |
||
1112 | $x = $xt + $yearwidth; |
||
1113 | while ($x < $xb) { |
||
1114 | $img->SetColor($this->year->grid->iColor); |
||
1115 | $img->Line($x, $yt, $x, $yb); |
||
1116 | $this->year->grid->Stroke($img, $x, $yb, $x, $img->height - $img->bottom_margin); |
||
1117 | ++$year; |
||
1118 | $yearwidth = $this->GetDayWidth() * $this->GetNumDaysInYear($year); |
||
1119 | if ($x + $yearwidth < $xb) { |
||
1120 | $w = $yearwidth; |
||
1121 | } else { |
||
1122 | $w = $xb - $x; |
||
1123 | } |
||
1124 | |||
1125 | if ($w >= 1.2 * $img->GetTextWidth('' . $year)) { |
||
1126 | $img->SetColor($this->year->iTextColor); |
||
1127 | $img->StrokeText( |
||
1128 | round($x + $w / 2 + 1), |
||
1129 | round($yb - $this->year->iTitleVertMargin), |
||
1130 | $year |
||
1131 | ); |
||
1132 | } |
||
1133 | $x += $yearwidth; |
||
1134 | } |
||
1135 | $img->SetColor($this->year->iFrameColor); |
||
1136 | $img->SetLineWeight($this->year->iFrameWeight); |
||
1137 | $img->Rectangle($xt, $yt, $xb, $yb); |
||
1138 | |||
1139 | return $yb - $img->top_margin; |
||
1140 | } |
||
1141 | |||
1142 | return $aYCoord; |
||
1143 | } |
||
1144 | |||
1145 | // Stroke table title (upper left corner) |
||
1146 | public function StrokeTableHeaders($aYBottom) |
||
1147 | { |
||
1148 | $img = $this->iImg; |
||
1149 | $xt = $img->left_margin; |
||
1150 | $yt = $img->top_margin; |
||
1151 | $xb = $xt + $this->iLabelWidth; |
||
1152 | $yb = $aYBottom + $img->top_margin; |
||
1153 | |||
1154 | if ($this->tableTitle->iShow) { |
||
1155 | $img->SetColor($this->iTableHeaderBackgroundColor); |
||
1156 | $img->FilledRectangle($xt, $yt, $xb, $yb); |
||
1157 | $this->tableTitle->Align('center', 'top'); |
||
1158 | $this->tableTitle->Stroke($img, $xt + ($xb - $xt) / 2 + 1, $yt + 2); |
||
1159 | $img->SetColor($this->iTableHeaderFrameColor); |
||
1160 | $img->SetLineWeight($this->iTableHeaderFrameWeight); |
||
1161 | $img->Rectangle($xt, $yt, $xb, $yb); |
||
1162 | } |
||
1163 | |||
1164 | $this->actinfo->Stroke($img, $xt, $yt, $xb, $yb, $this->tableTitle->iShow); |
||
1165 | |||
1166 | // Draw the horizontal dividing line |
||
1167 | $this->dividerh->Stroke($img, $xt, $yb, $img->width - $img->right_margin, $yb); |
||
1168 | |||
1169 | // Draw the vertical dividing line |
||
1170 | // We do the width "manually" since we want the line only to grow |
||
1171 | // to the left |
||
1172 | $fancy = $this->divider->iStyle == 'fancy'; |
||
1173 | if ($fancy) { |
||
1174 | $this->divider->iStyle = 'solid'; |
||
1175 | } |
||
1176 | |||
1177 | $tmp = $this->divider->iWeight; |
||
1178 | $this->divider->iWeight = 1; |
||
1179 | $y = $img->height - $img->bottom_margin; |
||
1180 | for ($i = 0; $i < $tmp; ++$i) { |
||
1181 | $this->divider->Stroke($img, $xb - $i, $yt, $xb - $i, $y); |
||
1182 | } |
||
1183 | |||
1184 | // Should we draw "fancy" divider |
||
1185 | if ($fancy) { |
||
1186 | $img->SetLineWeight(1); |
||
1187 | $img->SetColor($this->iTableHeaderFrameColor); |
||
1188 | $img->Line($xb, $yt, $xb, $y); |
||
1189 | $img->Line($xb - $tmp + 1, $yt, $xb - $tmp + 1, $y); |
||
1190 | $img->SetColor('white'); |
||
1191 | $img->Line($xb - $tmp + 2, $yt, $xb - $tmp + 2, $y); |
||
1192 | } |
||
1193 | } |
||
1194 | |||
1195 | // Main entry point to stroke scale |
||
1196 | public function Stroke() |
||
1240 | } |
||
1241 | } |
||
1242 | } |
||
1243 |