| Total Complexity | 70 |
| Total Lines | 507 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like DateScale 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 DateScale, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 19 | class DateScale extends LinearScale |
||
| 20 | { |
||
| 21 | private $date_format = ''; |
||
| 22 | private $iStartAlign = false; |
||
| 23 | private $iEndAlign = false; |
||
| 24 | private $iStartTimeAlign = false; |
||
| 25 | private $iEndTimeAlign = false; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * CONSTRUCTOR. |
||
| 29 | * |
||
| 30 | * @param mixed $aMin |
||
| 31 | * @param mixed $aMax |
||
| 32 | * @param mixed $aType |
||
| 33 | */ |
||
| 34 | public function __construct($aMin = 0, $aMax = 0, $aType = 'x') |
||
| 35 | { |
||
| 36 | assert($aType == 'x'); |
||
| 37 | assert($aMin <= $aMax); |
||
| 38 | |||
| 39 | $this->type = $aType; |
||
| 40 | $this->scale = [$aMin, $aMax]; |
||
| 41 | $this->world_size = $aMax - $aMin; |
||
|
|
|||
| 42 | $this->ticks = new LinearTicks(); |
||
| 43 | $this->intscale = true; |
||
| 44 | } |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Utility Function AdjDate() |
||
| 48 | * // Description: Will round a given time stamp to an even year, month or day |
||
| 49 | * // argument. |
||
| 50 | * |
||
| 51 | * @param mixed $aTime |
||
| 52 | * @param mixed $aRound |
||
| 53 | * @param mixed $aYearType |
||
| 54 | * @param mixed $aMonthType |
||
| 55 | * @param mixed $aDayType |
||
| 56 | */ |
||
| 57 | public function AdjDate($aTime, $aRound = 0, $aYearType = false, $aMonthType = false, $aDayType = false) |
||
| 58 | { |
||
| 59 | $y = (int) date('Y', $aTime); |
||
| 60 | $m = (int) date('m', $aTime); |
||
| 61 | $d = (int) date('d', $aTime); |
||
| 62 | $h = 0; |
||
| 63 | $i = 0; |
||
| 64 | $s = 0; |
||
| 65 | if ($aYearType !== false) { |
||
| 66 | $yearAdj = [0 => 1, 1 => 2, 2 => 5]; |
||
| 67 | if ($aRound == 0) { |
||
| 68 | $y = floor($y / $yearAdj[$aYearType]) * $yearAdj[$aYearType]; |
||
| 69 | } else { |
||
| 70 | ++$y; |
||
| 71 | $y = ceil($y / $yearAdj[$aYearType]) * $yearAdj[$aYearType]; |
||
| 72 | } |
||
| 73 | $m = 1; |
||
| 74 | $d = 1; |
||
| 75 | } elseif ($aMonthType !== false) { |
||
| 76 | $monthAdj = [0 => 1, 1 => 6]; |
||
| 77 | if ($aRound == 0) { |
||
| 78 | $m = floor($m / $monthAdj[$aMonthType]) * $monthAdj[$aMonthType]; |
||
| 79 | $d = 1; |
||
| 80 | } else { |
||
| 81 | ++$m; |
||
| 82 | $m = ceil($m / $monthAdj[$aMonthType]) * $monthAdj[$aMonthType]; |
||
| 83 | $d = 1; |
||
| 84 | } |
||
| 85 | } elseif ($aDayType !== false) { |
||
| 86 | if ($aDayType == 0) { |
||
| 87 | if ($aRound == 1) { |
||
| 88 | //++$d; |
||
| 89 | $h = 23; |
||
| 90 | $i = 59; |
||
| 91 | $s = 59; |
||
| 92 | } |
||
| 93 | } else { |
||
| 94 | // Adjust to an even week boundary. |
||
| 95 | $w = (int) date('w', $aTime); // Day of week 0=Sun, 6=Sat |
||
| 96 | |||
| 97 | // Adjust to start on Mon |
||
| 98 | if ($w == 0) { |
||
| 99 | $w = 6; |
||
| 100 | } else { |
||
| 101 | --$w; |
||
| 102 | } |
||
| 103 | |||
| 104 | if ($aRound == 0) { |
||
| 105 | $d -= $w; |
||
| 106 | } else { |
||
| 107 | $d += (7 - $w); |
||
| 108 | $h = 23; |
||
| 109 | $i = 59; |
||
| 110 | $s = 59; |
||
| 111 | } |
||
| 112 | } |
||
| 113 | } |
||
| 114 | |||
| 115 | return mktime($h, $i, $s, $m, $d, $y); |
||
| 116 | } |
||
| 117 | |||
| 118 | /** |
||
| 119 | * Wrapper for AdjDate that will round a timestamp to an even date rounding |
||
| 120 | * // it downwards. |
||
| 121 | * |
||
| 122 | * @param mixed $aTime |
||
| 123 | * @param mixed $aYearType |
||
| 124 | * @param mixed $aMonthType |
||
| 125 | * @param mixed $aDayType |
||
| 126 | */ |
||
| 127 | public function AdjStartDate($aTime, $aYearType = false, $aMonthType = false, $aDayType = false) |
||
| 128 | { |
||
| 129 | return $this->AdjDate($aTime, 0, $aYearType, $aMonthType, $aDayType); |
||
| 130 | } |
||
| 131 | |||
| 132 | /** |
||
| 133 | * Wrapper for AdjDate that will round a timestamp to an even date rounding |
||
| 134 | * // it upwards. |
||
| 135 | * |
||
| 136 | * @param mixed $aTime |
||
| 137 | * @param mixed $aYearType |
||
| 138 | * @param mixed $aMonthType |
||
| 139 | * @param mixed $aDayType |
||
| 140 | */ |
||
| 141 | public function AdjEndDate($aTime, $aYearType = false, $aMonthType = false, $aDayType = false) |
||
| 142 | { |
||
| 143 | return $this->AdjDate($aTime, 1, $aYearType, $aMonthType, $aDayType); |
||
| 144 | } |
||
| 145 | |||
| 146 | /** |
||
| 147 | * Utility Function AdjTime() |
||
| 148 | * // Description: Will round a given time stamp to an even time according to |
||
| 149 | * // argument. |
||
| 150 | * |
||
| 151 | * @param mixed $aTime |
||
| 152 | * @param mixed $aRound |
||
| 153 | * @param mixed $aHourType |
||
| 154 | * @param mixed $aMinType |
||
| 155 | * @param mixed $aSecType |
||
| 156 | */ |
||
| 157 | public function AdjTime($aTime, $aRound = 0, $aHourType = false, $aMinType = false, $aSecType = false) |
||
| 158 | { |
||
| 159 | $y = (int) date('Y', $aTime); |
||
| 160 | $m = (int) date('m', $aTime); |
||
| 161 | $d = (int) date('d', $aTime); |
||
| 162 | $h = (int) date('H', $aTime); |
||
| 163 | $i = (int) date('i', $aTime); |
||
| 164 | $s = (int) date('s', $aTime); |
||
| 165 | if ($aHourType !== false) { |
||
| 166 | $aHourType %= 6; |
||
| 167 | $hourAdj = [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 6, 5 => 12]; |
||
| 168 | if ($aRound == 0) { |
||
| 169 | $h = floor($h / $hourAdj[$aHourType]) * $hourAdj[$aHourType]; |
||
| 170 | } else { |
||
| 171 | if (($h % $hourAdj[$aHourType] == 0) && ($i > 0 || $s > 0)) { |
||
| 172 | ++$h; |
||
| 173 | } |
||
| 174 | $h = ceil($h / $hourAdj[$aHourType]) * $hourAdj[$aHourType]; |
||
| 175 | if ($h >= 24) { |
||
| 176 | $aTime += 86400; |
||
| 177 | $y = (int) date('Y', $aTime); |
||
| 178 | $m = (int) date('m', $aTime); |
||
| 179 | $d = (int) date('d', $aTime); |
||
| 180 | $h -= 24; |
||
| 181 | } |
||
| 182 | } |
||
| 183 | $i = 0; |
||
| 184 | $s = 0; |
||
| 185 | } elseif ($aMinType !== false) { |
||
| 186 | $aMinType %= 5; |
||
| 187 | $minAdj = [0 => 1, 1 => 5, 2 => 10, 3 => 15, 4 => 30]; |
||
| 188 | if ($aRound == 0) { |
||
| 189 | $i = floor($i / $minAdj[$aMinType]) * $minAdj[$aMinType]; |
||
| 190 | } else { |
||
| 191 | if (($i % $minAdj[$aMinType] == 0) && $s > 0) { |
||
| 192 | ++$i; |
||
| 193 | } |
||
| 194 | $i = ceil($i / $minAdj[$aMinType]) * $minAdj[$aMinType]; |
||
| 195 | if ($i >= 60) { |
||
| 196 | $aTime += 3600; |
||
| 197 | $y = (int) date('Y', $aTime); |
||
| 198 | $m = (int) date('m', $aTime); |
||
| 199 | $d = (int) date('d', $aTime); |
||
| 200 | $h = (int) date('H', $aTime); |
||
| 201 | $i = 0; |
||
| 202 | } |
||
| 203 | } |
||
| 204 | $s = 0; |
||
| 205 | } elseif ($aSecType !== false) { |
||
| 206 | $aSecType %= 5; |
||
| 207 | $secAdj = [0 => 1, 1 => 5, 2 => 10, 3 => 15, 4 => 30]; |
||
| 208 | if ($aRound == 0) { |
||
| 209 | $s = floor($s / $secAdj[$aSecType]) * $secAdj[$aSecType]; |
||
| 210 | } else { |
||
| 211 | $s = ceil($s / $secAdj[$aSecType] * 1.0) * $secAdj[$aSecType]; |
||
| 212 | if ($s >= 60) { |
||
| 213 | $s = 0; |
||
| 214 | $aTime += 60; |
||
| 215 | $y = (int) date('Y', $aTime); |
||
| 216 | $m = (int) date('m', $aTime); |
||
| 217 | $d = (int) date('d', $aTime); |
||
| 218 | $h = (int) date('H', $aTime); |
||
| 219 | $i = (int) date('i', $aTime); |
||
| 220 | } |
||
| 221 | } |
||
| 222 | } |
||
| 223 | |||
| 224 | return mktime($h, $i, $s, $m, $d, $y); |
||
| 225 | } |
||
| 226 | |||
| 227 | /** |
||
| 228 | * Wrapper for AdjTime that will round a timestamp to an even time rounding |
||
| 229 | * // it downwards. |
||
| 230 | * // Example: AdjStartTime(mktime(18,27,13,2,22,2005),false,2) => 18:20. |
||
| 231 | * |
||
| 232 | * @param mixed $aTime |
||
| 233 | * @param mixed $aHourType |
||
| 234 | * @param mixed $aMinType |
||
| 235 | * @param mixed $aSecType |
||
| 236 | */ |
||
| 237 | public function AdjStartTime($aTime, $aHourType = false, $aMinType = false, $aSecType = false) |
||
| 238 | { |
||
| 239 | return $this->AdjTime($aTime, 0, $aHourType, $aMinType, $aSecType); |
||
| 240 | } |
||
| 241 | |||
| 242 | /** |
||
| 243 | * Wrapper for AdjTime that will round a timestamp to an even time rounding |
||
| 244 | * // it upwards |
||
| 245 | * // Example: AdjEndTime(mktime(18,27,13,2,22,2005),false,2) => 18:30. |
||
| 246 | * |
||
| 247 | * @param mixed $aTime |
||
| 248 | * @param mixed $aHourType |
||
| 249 | * @param mixed $aMinType |
||
| 250 | * @param mixed $aSecType |
||
| 251 | */ |
||
| 252 | public function AdjEndTime($aTime, $aHourType = false, $aMinType = false, $aSecType = false) |
||
| 253 | { |
||
| 254 | return $this->AdjTime($aTime, 1, $aHourType, $aMinType, $aSecType); |
||
| 255 | } |
||
| 256 | |||
| 257 | /** |
||
| 258 | * DateAutoScale |
||
| 259 | * // Autoscale a date axis given start and end time |
||
| 260 | * // Returns an array ($start,$end,$major,$minor,$format). |
||
| 261 | * |
||
| 262 | * @param mixed $aStartTime |
||
| 263 | * @param mixed $aEndTime |
||
| 264 | * @param mixed $aDensity |
||
| 265 | * @param mixed $aAdjust |
||
| 266 | */ |
||
| 267 | public function DoDateAutoScale($aStartTime, $aEndTime, $aDensity = 0, $aAdjust = true) |
||
| 268 | { |
||
| 269 | // Format of array |
||
| 270 | // array ( Decision point, array( array( Major-scale-step-array ), |
||
| 271 | // array( Minor-scale-step-array ), |
||
| 272 | // array( 0=date-adjust, 1=time-adjust, adjustment-alignment) ) |
||
| 273 | // |
||
| 274 | $scalePoints = |
||
| 275 | [ |
||
| 276 | /* Intervall larger than 10 years */ |
||
| 277 | SECPERYEAR * 10, [[SECPERYEAR * 5, SECPERYEAR * 2], |
||
| 278 | [SECPERYEAR], |
||
| 279 | [0, YEARADJ_1, 0, YEARADJ_1], ], |
||
| 280 | |||
| 281 | /* Intervall larger than 2 years */ |
||
| 282 | SECPERYEAR * 2, [[SECPERYEAR], [SECPERYEAR], |
||
| 283 | [0, YEARADJ_1], ], |
||
| 284 | |||
| 285 | /* Intervall larger than 90 days (approx 3 month) */ |
||
| 286 | SECPERDAY * 90, [[SECPERDAY * 30, SECPERDAY * 14, SECPERDAY * 7, SECPERDAY], |
||
| 287 | [SECPERDAY * 5, SECPERDAY * 7, SECPERDAY, SECPERDAY], |
||
| 288 | [0, MONTHADJ_1, 0, DAYADJ_WEEK, 0, DAYADJ_1, 0, DAYADJ_1], ], |
||
| 289 | |||
| 290 | /* Intervall larger than 30 days (approx 1 month) */ |
||
| 291 | SECPERDAY * 30, [[SECPERDAY * 14, SECPERDAY * 7, SECPERDAY * 2, SECPERDAY], |
||
| 292 | [SECPERDAY, SECPERDAY, SECPERDAY, SECPERDAY], |
||
| 293 | [0, DAYADJ_WEEK, 0, DAYADJ_1, 0, DAYADJ_1, 0, DAYADJ_1], ], |
||
| 294 | |||
| 295 | /* Intervall larger than 7 days */ |
||
| 296 | SECPERDAY * 7, [[SECPERDAY, SECPERHOUR * 12, SECPERHOUR * 6, SECPERHOUR * 2], |
||
| 297 | [SECPERHOUR * 6, SECPERHOUR * 3, SECPERHOUR, SECPERHOUR], |
||
| 298 | [0, DAYADJ_1, 1, HOURADJ_12, 1, HOURADJ_6, 1, HOURADJ_1], ], |
||
| 299 | |||
| 300 | /* Intervall larger than 1 day */ |
||
| 301 | SECPERDAY, [[SECPERDAY, SECPERHOUR * 12, SECPERHOUR * 6, SECPERHOUR * 2, SECPERHOUR], |
||
| 302 | [SECPERHOUR * 6, SECPERHOUR * 2, SECPERHOUR, SECPERHOUR, SECPERHOUR], |
||
| 303 | [1, HOURADJ_12, 1, HOURADJ_6, 1, HOURADJ_1, 1, HOURADJ_1], ], |
||
| 304 | |||
| 305 | /* Intervall larger than 12 hours */ |
||
| 306 | SECPERHOUR * 12, [[SECPERHOUR * 2, SECPERHOUR, SECPERMIN * 30, 900, 600], |
||
| 307 | [1800, 1800, 900, 300, 300], |
||
| 308 | [1, HOURADJ_1, 1, MINADJ_30, 1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5], ], |
||
| 309 | |||
| 310 | /* Intervall larger than 2 hours */ |
||
| 311 | SECPERHOUR * 2, [[SECPERHOUR, SECPERMIN * 30, 900, 600, 300], |
||
| 312 | [1800, 900, 300, 120, 60], |
||
| 313 | [1, HOURADJ_1, 1, MINADJ_30, 1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5], ], |
||
| 314 | |||
| 315 | /* Intervall larger than 1 hours */ |
||
| 316 | SECPERHOUR, [[SECPERMIN * 30, 900, 600, 300], [900, 300, 120, 60], |
||
| 317 | [1, MINADJ_30, 1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5], ], |
||
| 318 | |||
| 319 | /* Intervall larger than 30 min */ |
||
| 320 | SECPERMIN * 30, [[SECPERMIN * 15, SECPERMIN * 10, SECPERMIN * 5, SECPERMIN], |
||
| 321 | [300, 300, 60, 10], |
||
| 322 | [1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5, 1, MINADJ_1], ], |
||
| 323 | |||
| 324 | /* Intervall larger than 1 min */ |
||
| 325 | SECPERMIN, [[SECPERMIN, 15, 10, 5], |
||
| 326 | [15, 5, 2, 1], |
||
| 327 | [1, MINADJ_1, 1, SECADJ_15, 1, SECADJ_10, 1, SECADJ_5], ], |
||
| 328 | |||
| 329 | /* Intervall larger than 10 sec */ |
||
| 330 | 10, [[5, 2], |
||
| 331 | [1, 1], |
||
| 332 | [1, SECADJ_5, 1, SECADJ_1], ], |
||
| 333 | |||
| 334 | /* Intervall larger than 1 sec */ |
||
| 335 | 1, [[1], |
||
| 336 | [1], |
||
| 337 | [1, SECADJ_1], ], |
||
| 338 | ]; |
||
| 339 | |||
| 340 | $ns = safe_count($scalePoints); |
||
| 341 | // Establish major and minor scale units for the date scale |
||
| 342 | $diff = $aEndTime - $aStartTime; |
||
| 343 | if ($diff < 1) { |
||
| 344 | return false; |
||
| 345 | } |
||
| 346 | |||
| 347 | $done = false; |
||
| 348 | $i = 0; |
||
| 349 | while (!$done) { |
||
| 350 | if ($diff > $scalePoints[2 * $i]) { |
||
| 351 | // Get major and minor scale for this intervall |
||
| 352 | $scaleSteps = $scalePoints[2 * $i + 1]; |
||
| 353 | $major = $scaleSteps[0][min($aDensity, safe_count($scaleSteps[0]) - 1)]; |
||
| 354 | // Try to find out which minor step looks best |
||
| 355 | $minor = $scaleSteps[1][min($aDensity, safe_count($scaleSteps[1]) - 1)]; |
||
| 356 | if ($aAdjust) { |
||
| 357 | // Find out how we should align the start and end timestamps |
||
| 358 | $idx = 2 * min($aDensity, floor(safe_count($scaleSteps[2]) / 2) - 1); |
||
| 359 | if ($scaleSteps[2][$idx] === 0) { |
||
| 360 | // Use date adjustment |
||
| 361 | $adj = $scaleSteps[2][$idx + 1]; |
||
| 362 | if ($adj >= 30) { |
||
| 363 | $start = $this->AdjStartDate($aStartTime, $adj - 30); |
||
| 364 | $end = $this->AdjEndDate($aEndTime, $adj - 30); |
||
| 365 | } elseif ($adj >= 20) { |
||
| 366 | $start = $this->AdjStartDate($aStartTime, false, $adj - 20); |
||
| 367 | $end = $this->AdjEndDate($aEndTime, false, $adj - 20); |
||
| 368 | } else { |
||
| 369 | $start = $this->AdjStartDate($aStartTime, false, false, $adj); |
||
| 370 | $end = $this->AdjEndDate($aEndTime, false, false, $adj); |
||
| 371 | // We add 1 second for date adjustment to make sure we end on 00:00 the following day |
||
| 372 | // This makes the final major tick be srawn when we step day-by-day instead of ending |
||
| 373 | // on xx:59:59 which would not draw the final major tick |
||
| 374 | ++$end; |
||
| 375 | } |
||
| 376 | } else { |
||
| 377 | // Use time adjustment |
||
| 378 | $adj = $scaleSteps[2][$idx + 1]; |
||
| 379 | if ($adj >= 30) { |
||
| 380 | $start = $this->AdjStartTime($aStartTime, $adj - 30); |
||
| 381 | $end = $this->AdjEndTime($aEndTime, $adj - 30); |
||
| 382 | } elseif ($adj >= 20) { |
||
| 383 | $start = $this->AdjStartTime($aStartTime, false, $adj - 20); |
||
| 384 | $end = $this->AdjEndTime($aEndTime, false, $adj - 20); |
||
| 385 | } else { |
||
| 386 | $start = $this->AdjStartTime($aStartTime, false, false, $adj); |
||
| 387 | $end = $this->AdjEndTime($aEndTime, false, false, $adj); |
||
| 388 | } |
||
| 389 | } |
||
| 390 | } |
||
| 391 | // If the overall date span is larger than 1 day ten we show date |
||
| 392 | $format = ''; |
||
| 393 | if (($end - $start) > SECPERDAY) { |
||
| 394 | $format = 'Y-m-d '; |
||
| 395 | } |
||
| 396 | // If the major step is less than 1 day we need to whow hours + min |
||
| 397 | if ($major < SECPERDAY) { |
||
| 398 | $format .= 'H:i'; |
||
| 399 | } |
||
| 400 | // If the major step is less than 1 min we need to show sec |
||
| 401 | if ($major < 60) { |
||
| 402 | $format .= ':s'; |
||
| 403 | } |
||
| 404 | $done = true; |
||
| 405 | } |
||
| 406 | ++$i; |
||
| 407 | } |
||
| 408 | |||
| 409 | return [$start, $end, $major, $minor, $format]; |
||
| 410 | } |
||
| 411 | |||
| 412 | // Overrides the automatic determined date format. Must be a valid date() format string |
||
| 413 | public function SetDateFormat($aFormat) |
||
| 414 | { |
||
| 415 | $this->date_format = $aFormat; |
||
| 416 | $this->ticks->SetLabelDateFormat($this->date_format); |
||
| 417 | } |
||
| 418 | |||
| 419 | public function AdjustForDST($aFlg = true) |
||
| 422 | } |
||
| 423 | |||
| 424 | public function SetDateAlign($aStartAlign, $aEndAlign = false) |
||
| 431 | } |
||
| 432 | |||
| 433 | public function SetTimeAlign($aStartAlign, $aEndAlign = false) |
||
| 440 | } |
||
| 441 | |||
| 442 | public function AutoScale($img, $aStartTime, $aEndTime, $aNumSteps, $_adummy = false) |
||
| 443 | { |
||
| 444 | // We need to have one dummy argument to make the signature of AutoScale() |
||
| 445 | // identical to LinearScale::AutoScale |
||
| 446 | if ($aStartTime == $aEndTime) { |
||
| 529 |