| 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 |