1
|
|
|
<?php |
2
|
|
|
namespace Amenadiel\JpGraph\Graph; |
3
|
|
|
|
4
|
|
|
use Amenadiel\JpGraph\Util; |
5
|
|
|
|
6
|
|
|
/*======================================================================= |
7
|
|
|
// File: JPGRAPH_DATE.PHP |
8
|
|
|
// Description: Classes to handle Date scaling |
9
|
|
|
// Created: 2005-05-02 |
10
|
|
|
// Ver: $Id: jpgraph_date.php 1106 2009-02-22 20:16:35Z ljp $ |
11
|
|
|
// |
12
|
|
|
// Copyright (c) Asial Corporation. All rights reserved. |
13
|
|
|
//======================================================================== |
14
|
|
|
*/ |
15
|
|
|
|
16
|
|
|
define('HOURADJ_1', 0 + 30); |
17
|
|
|
define('HOURADJ_2', 1 + 30); |
18
|
|
|
define('HOURADJ_3', 2 + 30); |
19
|
|
|
define('HOURADJ_4', 3 + 30); |
20
|
|
|
define('HOURADJ_6', 4 + 30); |
21
|
|
|
define('HOURADJ_12', 5 + 30); |
22
|
|
|
|
23
|
|
|
define('MINADJ_1', 0 + 20); |
24
|
|
|
define('MINADJ_5', 1 + 20); |
25
|
|
|
define('MINADJ_10', 2 + 20); |
26
|
|
|
define('MINADJ_15', 3 + 20); |
27
|
|
|
define('MINADJ_30', 4 + 20); |
28
|
|
|
|
29
|
|
|
define('SECADJ_1', 0); |
30
|
|
|
define('SECADJ_5', 1); |
31
|
|
|
define('SECADJ_10', 2); |
32
|
|
|
define('SECADJ_15', 3); |
33
|
|
|
define('SECADJ_30', 4); |
34
|
|
|
|
35
|
|
|
define('YEARADJ_1', 0 + 30); |
36
|
|
|
define('YEARADJ_2', 1 + 30); |
37
|
|
|
define('YEARADJ_5', 2 + 30); |
38
|
|
|
|
39
|
|
|
define('MONTHADJ_1', 0 + 20); |
40
|
|
|
define('MONTHADJ_6', 1 + 20); |
41
|
|
|
|
42
|
|
|
define('DAYADJ_1', 0); |
43
|
|
|
define('DAYADJ_WEEK', 1); |
44
|
|
|
define('DAYADJ_7', 1); |
45
|
|
|
|
46
|
|
|
define('SECPERYEAR', 31536000); |
47
|
|
|
define('SECPERDAY', 86400); |
48
|
|
|
define('SECPERHOUR', 3600); |
49
|
|
|
define('SECPERMIN', 60); |
50
|
|
|
|
51
|
|
|
class DateScale extends LinearScale |
52
|
|
|
{ |
53
|
|
|
private $date_format = ''; |
54
|
|
|
private $iStartAlign = false; |
55
|
|
|
private $iEndAlign = false; |
56
|
|
|
private $iStartTimeAlign = false; |
57
|
|
|
private $iEndTimeAlign = false; |
58
|
|
|
|
59
|
|
|
//--------------- |
60
|
|
|
// CONSTRUCTOR |
61
|
|
View Code Duplication |
public function __construct($aMin = 0, $aMax = 0, $aType = 'x') |
|
|
|
|
62
|
|
|
{ |
63
|
|
|
assert($aType == "x"); |
64
|
|
|
assert($aMin <= $aMax); |
65
|
|
|
|
66
|
|
|
$this->type = $aType; |
67
|
|
|
$this->scale = [$aMin, $aMax]; |
68
|
|
|
$this->world_size = $aMax - $aMin; |
|
|
|
|
69
|
|
|
$this->ticks = new LinearTicks(); |
70
|
|
|
$this->intscale = true; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
//------------------------------------------------------------------------------------------ |
74
|
|
|
// Utility Function AdjDate() |
|
|
|
|
75
|
|
|
// Description: Will round a given time stamp to an even year, month or day |
76
|
|
|
// argument. |
77
|
|
|
//------------------------------------------------------------------------------------------ |
78
|
|
|
|
79
|
|
|
public function AdjDate($aTime, $aRound = 0, $aYearType = false, $aMonthType = false, $aDayType = false) |
80
|
|
|
{ |
81
|
|
|
$y = (int) date('Y', $aTime); |
82
|
|
|
$m = (int) date('m', $aTime); |
83
|
|
|
$d = (int) date('d', $aTime); |
84
|
|
|
$h = 0; |
85
|
|
|
$i = 0; |
86
|
|
|
$s = 0; |
87
|
|
|
if ($aYearType !== false) { |
88
|
|
|
$yearAdj = [0 => 1, 1 => 2, 2 => 5]; |
89
|
|
|
if ($aRound == 0) { |
90
|
|
|
$y = floor($y / $yearAdj[$aYearType]) * $yearAdj[$aYearType]; |
91
|
|
|
} else { |
92
|
|
|
++$y; |
93
|
|
|
$y = ceil($y / $yearAdj[$aYearType]) * $yearAdj[$aYearType]; |
94
|
|
|
} |
95
|
|
|
$m = 1; |
96
|
|
|
$d = 1; |
97
|
|
|
} elseif ($aMonthType !== false) { |
98
|
|
|
$monthAdj = [0 => 1, 1 => 6]; |
99
|
|
|
if ($aRound == 0) { |
100
|
|
|
$m = floor($m / $monthAdj[$aMonthType]) * $monthAdj[$aMonthType]; |
101
|
|
|
$d = 1; |
102
|
|
|
} else { |
103
|
|
|
++$m; |
104
|
|
|
$m = ceil($m / $monthAdj[$aMonthType]) * $monthAdj[$aMonthType]; |
105
|
|
|
$d = 1; |
106
|
|
|
} |
107
|
|
|
} elseif ($aDayType !== false) { |
108
|
|
|
if ($aDayType == 0) { |
109
|
|
|
if ($aRound == 1) { |
110
|
|
|
//++$d; |
111
|
|
|
$h = 23; |
112
|
|
|
$i = 59; |
113
|
|
|
$s = 59; |
114
|
|
|
} |
115
|
|
|
} else { |
116
|
|
|
// Adjust to an even week boundary. |
117
|
|
|
$w = (int) date('w', $aTime); // Day of week 0=Sun, 6=Sat |
118
|
|
|
if (true) { |
|
|
|
|
119
|
|
|
// Adjust to start on Mon |
120
|
|
|
if ($w == 0) { |
121
|
|
|
$w = 6; |
122
|
|
|
} else { |
123
|
|
|
--$w; |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
if ($aRound == 0) { |
127
|
|
|
$d -= $w; |
128
|
|
|
} else { |
129
|
|
|
$d += (7 - $w); |
130
|
|
|
$h = 23; |
131
|
|
|
$i = 59; |
132
|
|
|
$s = 59; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
return mktime($h, $i, $s, $m, $d, $y); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
//------------------------------------------------------------------------------------------ |
140
|
|
|
// Wrapper for AdjDate that will round a timestamp to an even date rounding |
141
|
|
|
// it downwards. |
142
|
|
|
//------------------------------------------------------------------------------------------ |
143
|
|
|
public function AdjStartDate($aTime, $aYearType = false, $aMonthType = false, $aDayType = false) |
144
|
|
|
{ |
145
|
|
|
return $this->AdjDate($aTime, 0, $aYearType, $aMonthType, $aDayType); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
//------------------------------------------------------------------------------------------ |
149
|
|
|
// Wrapper for AdjDate that will round a timestamp to an even date rounding |
150
|
|
|
// it upwards |
151
|
|
|
//------------------------------------------------------------------------------------------ |
152
|
|
|
public function AdjEndDate($aTime, $aYearType = false, $aMonthType = false, $aDayType = false) |
153
|
|
|
{ |
154
|
|
|
return $this->AdjDate($aTime, 1, $aYearType, $aMonthType, $aDayType); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
//------------------------------------------------------------------------------------------ |
158
|
|
|
// Utility Function AdjTime() |
|
|
|
|
159
|
|
|
// Description: Will round a given time stamp to an even time according to |
160
|
|
|
// argument. |
161
|
|
|
//------------------------------------------------------------------------------------------ |
162
|
|
|
|
163
|
|
|
public function AdjTime($aTime, $aRound = 0, $aHourType = false, $aMinType = false, $aSecType = false) |
164
|
|
|
{ |
165
|
|
|
$y = (int) date('Y', $aTime); |
166
|
|
|
$m = (int) date('m', $aTime); |
167
|
|
|
$d = (int) date('d', $aTime); |
168
|
|
|
$h = (int) date('H', $aTime); |
169
|
|
|
$i = (int) date('i', $aTime); |
170
|
|
|
$s = (int) date('s', $aTime); |
171
|
|
|
if ($aHourType !== false) { |
172
|
|
|
$aHourType %= 6; |
173
|
|
|
$hourAdj = [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 6, 5 => 12]; |
174
|
|
|
if ($aRound == 0) { |
175
|
|
|
$h = floor($h / $hourAdj[$aHourType]) * $hourAdj[$aHourType]; |
176
|
|
|
} else { |
177
|
|
|
if (($h % $hourAdj[$aHourType] == 0) && ($i > 0 || $s > 0)) { |
178
|
|
|
$h++; |
179
|
|
|
} |
180
|
|
|
$h = ceil($h / $hourAdj[$aHourType]) * $hourAdj[$aHourType]; |
181
|
|
|
if ($h >= 24) { |
182
|
|
|
$aTime += 86400; |
183
|
|
|
$y = (int) date('Y', $aTime); |
184
|
|
|
$m = (int) date('m', $aTime); |
185
|
|
|
$d = (int) date('d', $aTime); |
186
|
|
|
$h -= 24; |
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
$i = 0; |
190
|
|
|
$s = 0; |
191
|
|
|
} elseif ($aMinType !== false) { |
192
|
|
|
$aMinType %= 5; |
193
|
|
|
$minAdj = [0 => 1, 1 => 5, 2 => 10, 3 => 15, 4 => 30]; |
194
|
|
|
if ($aRound == 0) { |
195
|
|
|
$i = floor($i / $minAdj[$aMinType]) * $minAdj[$aMinType]; |
196
|
|
|
} else { |
197
|
|
|
if (($i % $minAdj[$aMinType] == 0) && $s > 0) { |
198
|
|
|
$i++; |
199
|
|
|
} |
200
|
|
|
$i = ceil($i / $minAdj[$aMinType]) * $minAdj[$aMinType]; |
201
|
|
View Code Duplication |
if ($i >= 60) { |
|
|
|
|
202
|
|
|
$aTime += 3600; |
203
|
|
|
$y = (int) date('Y', $aTime); |
204
|
|
|
$m = (int) date('m', $aTime); |
205
|
|
|
$d = (int) date('d', $aTime); |
206
|
|
|
$h = (int) date('H', $aTime); |
207
|
|
|
$i = 0; |
208
|
|
|
} |
209
|
|
|
} |
210
|
|
|
$s = 0; |
211
|
|
|
} elseif ($aSecType !== false) { |
212
|
|
|
$aSecType %= 5; |
213
|
|
|
$secAdj = [0 => 1, 1 => 5, 2 => 10, 3 => 15, 4 => 30]; |
214
|
|
|
if ($aRound == 0) { |
215
|
|
|
$s = floor($s / $secAdj[$aSecType]) * $secAdj[$aSecType]; |
216
|
|
|
} else { |
217
|
|
|
$s = ceil($s / $secAdj[$aSecType] * 1.0) * $secAdj[$aSecType]; |
218
|
|
View Code Duplication |
if ($s >= 60) { |
|
|
|
|
219
|
|
|
$s = 0; |
220
|
|
|
$aTime += 60; |
221
|
|
|
$y = (int) date('Y', $aTime); |
222
|
|
|
$m = (int) date('m', $aTime); |
223
|
|
|
$d = (int) date('d', $aTime); |
224
|
|
|
$h = (int) date('H', $aTime); |
225
|
|
|
$i = (int) date('i', $aTime); |
226
|
|
|
} |
227
|
|
|
} |
228
|
|
|
} |
229
|
|
|
return mktime($h, $i, $s, $m, $d, $y); |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
//------------------------------------------------------------------------------------------ |
233
|
|
|
// Wrapper for AdjTime that will round a timestamp to an even time rounding |
234
|
|
|
// it downwards. |
235
|
|
|
// Example: AdjStartTime(mktime(18,27,13,2,22,2005),false,2) => 18:20 |
|
|
|
|
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
|
|
|
public function AdjEndTime($aTime, $aHourType = false, $aMinType = false, $aSecType = false) |
248
|
|
|
{ |
249
|
|
|
return $this->AdjTime($aTime, 1, $aHourType, $aMinType, $aSecType); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
//------------------------------------------------------------------------------------------ |
253
|
|
|
// DateAutoScale |
254
|
|
|
// Autoscale a date axis given start and end time |
255
|
|
|
// Returns an array ($start,$end,$major,$minor,$format) |
|
|
|
|
256
|
|
|
//------------------------------------------------------------------------------------------ |
257
|
|
|
public function DoDateAutoScale($aStartTime, $aEndTime, $aDensity = 0, $aAdjust = true) |
258
|
|
|
{ |
259
|
|
|
// Format of array |
260
|
|
|
// array ( Decision point, array( array( Major-scale-step-array ), |
|
|
|
|
261
|
|
|
// array( Minor-scale-step-array ), |
|
|
|
|
262
|
|
|
// array( 0=date-adjust, 1=time-adjust, adjustment-alignment) ) |
263
|
|
|
// |
264
|
|
|
$scalePoints = |
265
|
|
|
[ |
266
|
|
|
/* Intervall larger than 10 years */ |
267
|
|
|
SECPERYEAR * 10, [[SECPERYEAR * 5, SECPERYEAR * 2], |
268
|
|
|
[SECPERYEAR], |
269
|
|
|
[0, YEARADJ_1, 0, YEARADJ_1]], |
270
|
|
|
|
271
|
|
|
/* Intervall larger than 2 years */ |
272
|
|
|
SECPERYEAR * 2, [[SECPERYEAR], [SECPERYEAR], |
273
|
|
|
[0, YEARADJ_1]], |
274
|
|
|
|
275
|
|
|
/* Intervall larger than 90 days (approx 3 month) */ |
276
|
|
|
SECPERDAY * 90, [[SECPERDAY * 30, SECPERDAY * 14, SECPERDAY * 7, SECPERDAY], |
277
|
|
|
[SECPERDAY * 5, SECPERDAY * 7, SECPERDAY, SECPERDAY], |
278
|
|
|
[0, MONTHADJ_1, 0, DAYADJ_WEEK, 0, DAYADJ_1, 0, DAYADJ_1]], |
279
|
|
|
|
280
|
|
|
/* Intervall larger than 30 days (approx 1 month) */ |
281
|
|
|
SECPERDAY * 30, [[SECPERDAY * 14, SECPERDAY * 7, SECPERDAY * 2, SECPERDAY], |
282
|
|
|
[SECPERDAY, SECPERDAY, SECPERDAY, SECPERDAY], |
283
|
|
|
[0, DAYADJ_WEEK, 0, DAYADJ_1, 0, DAYADJ_1, 0, DAYADJ_1]], |
284
|
|
|
|
285
|
|
|
/* Intervall larger than 7 days */ |
286
|
|
|
SECPERDAY * 7, [[SECPERDAY, SECPERHOUR * 12, SECPERHOUR * 6, SECPERHOUR * 2], |
287
|
|
|
[SECPERHOUR * 6, SECPERHOUR * 3, SECPERHOUR, SECPERHOUR], |
288
|
|
|
[0, DAYADJ_1, 1, HOURADJ_12, 1, HOURADJ_6, 1, HOURADJ_1]], |
289
|
|
|
|
290
|
|
|
/* Intervall larger than 1 day */ |
291
|
|
|
SECPERDAY, [[SECPERDAY, SECPERHOUR * 12, SECPERHOUR * 6, SECPERHOUR * 2, SECPERHOUR], |
292
|
|
|
[SECPERHOUR * 6, SECPERHOUR * 2, SECPERHOUR, SECPERHOUR, SECPERHOUR], |
293
|
|
|
[1, HOURADJ_12, 1, HOURADJ_6, 1, HOURADJ_1, 1, HOURADJ_1]], |
294
|
|
|
|
295
|
|
|
/* Intervall larger than 12 hours */ |
296
|
|
|
SECPERHOUR * 12, [[SECPERHOUR * 2, SECPERHOUR, SECPERMIN * 30, 900, 600], |
297
|
|
|
[1800, 1800, 900, 300, 300], |
298
|
|
|
[1, HOURADJ_1, 1, MINADJ_30, 1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5]], |
299
|
|
|
|
300
|
|
|
/* Intervall larger than 2 hours */ |
301
|
|
|
SECPERHOUR * 2, [[SECPERHOUR, SECPERMIN * 30, 900, 600, 300], |
302
|
|
|
[1800, 900, 300, 120, 60], |
303
|
|
|
[1, HOURADJ_1, 1, MINADJ_30, 1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5]], |
304
|
|
|
|
305
|
|
|
/* Intervall larger than 1 hours */ |
306
|
|
|
SECPERHOUR, [[SECPERMIN * 30, 900, 600, 300], [900, 300, 120, 60], |
307
|
|
|
[1, MINADJ_30, 1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5]], |
308
|
|
|
|
309
|
|
|
/* Intervall larger than 30 min */ |
310
|
|
|
SECPERMIN * 30, [[SECPERMIN * 15, SECPERMIN * 10, SECPERMIN * 5, SECPERMIN], |
311
|
|
|
[300, 300, 60, 10], |
312
|
|
|
[1, MINADJ_15, 1, MINADJ_10, 1, MINADJ_5, 1, MINADJ_1]], |
313
|
|
|
|
314
|
|
|
/* Intervall larger than 1 min */ |
315
|
|
|
SECPERMIN, [[SECPERMIN, 15, 10, 5], |
316
|
|
|
[15, 5, 2, 1], |
317
|
|
|
[1, MINADJ_1, 1, SECADJ_15, 1, SECADJ_10, 1, SECADJ_5]], |
318
|
|
|
|
319
|
|
|
/* Intervall larger than 10 sec */ |
320
|
|
|
10, [[5, 2], |
321
|
|
|
[1, 1], |
322
|
|
|
[1, SECADJ_5, 1, SECADJ_1]], |
323
|
|
|
|
324
|
|
|
/* Intervall larger than 1 sec */ |
325
|
|
|
1, [[1], |
326
|
|
|
[1], |
327
|
|
|
[1, SECADJ_1]], |
328
|
|
|
]; |
329
|
|
|
|
330
|
|
|
$ns = count($scalePoints); |
|
|
|
|
331
|
|
|
// Establish major and minor scale units for the date scale |
332
|
|
|
$diff = $aEndTime - $aStartTime; |
333
|
|
|
if ($diff < 1) { |
334
|
|
|
return false; |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
$done = false; |
338
|
|
|
$i = 0; |
339
|
|
|
while (!$done) { |
340
|
|
|
if ($diff > $scalePoints[2 * $i]) { |
341
|
|
|
// Get major and minor scale for this intervall |
342
|
|
|
$scaleSteps = $scalePoints[2 * $i + 1]; |
343
|
|
|
$major = $scaleSteps[0][min($aDensity, count($scaleSteps[0]) - 1)]; |
344
|
|
|
// Try to find out which minor step looks best |
345
|
|
|
$minor = $scaleSteps[1][min($aDensity, count($scaleSteps[1]) - 1)]; |
346
|
|
|
if ($aAdjust) { |
347
|
|
|
// Find out how we should align the start and end timestamps |
348
|
|
|
$idx = 2 * min($aDensity, floor(count($scaleSteps[2]) / 2) - 1); |
349
|
|
|
if ($scaleSteps[2][$idx] === 0) { |
350
|
|
|
// Use date adjustment |
351
|
|
|
$adj = $scaleSteps[2][$idx + 1]; |
352
|
|
View Code Duplication |
if ($adj >= 30) { |
|
|
|
|
353
|
|
|
$start = $this->AdjStartDate($aStartTime, $adj - 30); |
|
|
|
|
354
|
|
|
$end = $this->AdjEndDate($aEndTime, $adj - 30); |
|
|
|
|
355
|
|
|
} elseif ($adj >= 20) { |
356
|
|
|
$start = $this->AdjStartDate($aStartTime, false, $adj - 20); |
|
|
|
|
357
|
|
|
$end = $this->AdjEndDate($aEndTime, false, $adj - 20); |
|
|
|
|
358
|
|
|
} else { |
359
|
|
|
$start = $this->AdjStartDate($aStartTime, false, false, $adj); |
360
|
|
|
$end = $this->AdjEndDate($aEndTime, false, false, $adj); |
361
|
|
|
// We add 1 second for date adjustment to make sure we end on 00:00 the following day |
362
|
|
|
// This makes the final major tick be srawn when we step day-by-day instead of ending |
363
|
|
|
// on xx:59:59 which would not draw the final major tick |
364
|
|
|
$end++; |
365
|
|
|
} |
366
|
|
|
} else { |
367
|
|
|
// Use time adjustment |
368
|
|
|
$adj = $scaleSteps[2][$idx + 1]; |
369
|
|
View Code Duplication |
if ($adj >= 30) { |
|
|
|
|
370
|
|
|
$start = $this->AdjStartTime($aStartTime, $adj - 30); |
|
|
|
|
371
|
|
|
$end = $this->AdjEndTime($aEndTime, $adj - 30); |
|
|
|
|
372
|
|
|
} elseif ($adj >= 20) { |
373
|
|
|
$start = $this->AdjStartTime($aStartTime, false, $adj - 20); |
|
|
|
|
374
|
|
|
$end = $this->AdjEndTime($aEndTime, false, $adj - 20); |
|
|
|
|
375
|
|
|
} else { |
376
|
|
|
$start = $this->AdjStartTime($aStartTime, false, false, $adj); |
377
|
|
|
$end = $this->AdjEndTime($aEndTime, false, false, $adj); |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
} |
381
|
|
|
// If the overall date span is larger than 1 day ten we show date |
382
|
|
|
$format = ''; |
383
|
|
|
if (($end - $start) > SECPERDAY) { |
|
|
|
|
384
|
|
|
$format = 'Y-m-d '; |
385
|
|
|
} |
386
|
|
|
// If the major step is less than 1 day we need to whow hours + min |
387
|
|
|
if ($major < SECPERDAY) { |
388
|
|
|
$format .= 'H:i'; |
389
|
|
|
} |
390
|
|
|
// If the major step is less than 1 min we need to show sec |
391
|
|
|
if ($major < 60) { |
392
|
|
|
$format .= ':s'; |
393
|
|
|
} |
394
|
|
|
$done = true; |
395
|
|
|
} |
396
|
|
|
++$i; |
397
|
|
|
} |
398
|
|
|
return [$start, $end, $major, $minor, $format]; |
|
|
|
|
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
// Overrides the automatic determined date format. Must be a valid date() format string |
402
|
|
|
public function SetDateFormat($aFormat) |
403
|
|
|
{ |
404
|
|
|
$this->date_format = $aFormat; |
405
|
|
|
$this->ticks->SetLabelDateFormat($this->date_format); |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
public function AdjustForDST($aFlg = true) |
409
|
|
|
{ |
410
|
|
|
$this->ticks->AdjustForDST($aFlg); |
|
|
|
|
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
public function SetDateAlign($aStartAlign, $aEndAlign = false) |
414
|
|
|
{ |
415
|
|
|
if ($aEndAlign === false) { |
416
|
|
|
$aEndAlign = $aStartAlign; |
417
|
|
|
} |
418
|
|
|
$this->iStartAlign = $aStartAlign; |
419
|
|
|
$this->iEndAlign = $aEndAlign; |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
public function SetTimeAlign($aStartAlign, $aEndAlign = false) |
423
|
|
|
{ |
424
|
|
|
if ($aEndAlign === false) { |
425
|
|
|
$aEndAlign = $aStartAlign; |
426
|
|
|
} |
427
|
|
|
$this->iStartTimeAlign = $aStartAlign; |
428
|
|
|
$this->iEndTimeAlign = $aEndAlign; |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
public function AutoScale($img, $aStartTime, $aEndTime, $aNumSteps, $_adummy = false) |
432
|
|
|
{ |
433
|
|
|
// We need to have one dummy argument to make the signature of AutoScale() |
434
|
|
|
// identical to LinearScale::AutoScale |
435
|
|
|
if ($aStartTime == $aEndTime) { |
436
|
|
|
// Special case when we only have one data point. |
437
|
|
|
// Create a small artifical intervall to do the autoscaling |
438
|
|
|
$aStartTime -= 10; |
439
|
|
|
$aEndTime += 10; |
440
|
|
|
} |
441
|
|
|
$done = false; |
442
|
|
|
$i = 0; |
443
|
|
|
while (!$done && $i < 5) { |
444
|
|
|
list($adjstart, $adjend, $maj, $min, $format) = $this->DoDateAutoScale($aStartTime, $aEndTime, $i); |
445
|
|
|
$n = floor(($adjend - $adjstart) / $maj); |
446
|
|
|
if ($n * 1.7 > $aNumSteps) { |
447
|
|
|
$done = true; |
448
|
|
|
} |
449
|
|
|
$i++; |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/* |
|
|
|
|
453
|
|
|
if( 0 ) { // DEBUG |
454
|
|
|
echo " Start =".date("Y-m-d H:i:s",$aStartTime)."<br>"; |
455
|
|
|
echo " End =".date("Y-m-d H:i:s",$aEndTime)."<br>"; |
456
|
|
|
echo "Adj Start =".date("Y-m-d H:i:s",$adjstart)."<br>"; |
457
|
|
|
echo "Adj End =".date("Y-m-d H:i:s",$adjend)."<p>"; |
458
|
|
|
echo "Major = $maj s, ".floor($maj/60)."min, ".floor($maj/3600)."h, ".floor($maj/86400)."day<br>"; |
459
|
|
|
echo "Min = $min s, ".floor($min/60)."min, ".floor($min/3600)."h, ".floor($min/86400)."day<br>"; |
460
|
|
|
echo "Format=$format<p>"; |
461
|
|
|
} |
462
|
|
|
*/ |
463
|
|
|
|
464
|
|
|
if ($this->iStartTimeAlign !== false && $this->iStartAlign !== false) { |
465
|
|
|
Util\JpGraphError::RaiseL(3001); |
466
|
|
|
//('It is only possible to use either SetDateAlign() or SetTimeAlign() but not both'); |
467
|
|
|
} |
468
|
|
|
|
469
|
|
View Code Duplication |
if ($this->iStartTimeAlign !== false) { |
|
|
|
|
470
|
|
|
if ($this->iStartTimeAlign >= 30) { |
471
|
|
|
$adjstart = $this->AdjStartTime($aStartTime, $this->iStartTimeAlign - 30); |
|
|
|
|
472
|
|
|
} elseif ($this->iStartTimeAlign >= 20) { |
473
|
|
|
$adjstart = $this->AdjStartTime($aStartTime, false, $this->iStartTimeAlign - 20); |
|
|
|
|
474
|
|
|
} else { |
475
|
|
|
$adjstart = $this->AdjStartTime($aStartTime, false, false, $this->iStartTimeAlign); |
476
|
|
|
} |
477
|
|
|
} |
478
|
|
View Code Duplication |
if ($this->iEndTimeAlign !== false) { |
|
|
|
|
479
|
|
|
if ($this->iEndTimeAlign >= 30) { |
480
|
|
|
$adjend = $this->AdjEndTime($aEndTime, $this->iEndTimeAlign - 30); |
|
|
|
|
481
|
|
|
} elseif ($this->iEndTimeAlign >= 20) { |
482
|
|
|
$adjend = $this->AdjEndTime($aEndTime, false, $this->iEndTimeAlign - 20); |
|
|
|
|
483
|
|
|
} else { |
484
|
|
|
$adjend = $this->AdjEndTime($aEndTime, false, false, $this->iEndTimeAlign); |
485
|
|
|
} |
486
|
|
|
} |
487
|
|
|
|
488
|
|
View Code Duplication |
if ($this->iStartAlign !== false) { |
|
|
|
|
489
|
|
|
if ($this->iStartAlign >= 30) { |
490
|
|
|
$adjstart = $this->AdjStartDate($aStartTime, $this->iStartAlign - 30); |
|
|
|
|
491
|
|
|
} elseif ($this->iStartAlign >= 20) { |
492
|
|
|
$adjstart = $this->AdjStartDate($aStartTime, false, $this->iStartAlign - 20); |
|
|
|
|
493
|
|
|
} else { |
494
|
|
|
$adjstart = $this->AdjStartDate($aStartTime, false, false, $this->iStartAlign); |
495
|
|
|
} |
496
|
|
|
} |
497
|
|
View Code Duplication |
if ($this->iEndAlign !== false) { |
|
|
|
|
498
|
|
|
if ($this->iEndAlign >= 30) { |
499
|
|
|
$adjend = $this->AdjEndDate($aEndTime, $this->iEndAlign - 30); |
|
|
|
|
500
|
|
|
} elseif ($this->iEndAlign >= 20) { |
501
|
|
|
$adjend = $this->AdjEndDate($aEndTime, false, $this->iEndAlign - 20); |
|
|
|
|
502
|
|
|
} else { |
503
|
|
|
$adjend = $this->AdjEndDate($aEndTime, false, false, $this->iEndAlign); |
504
|
|
|
} |
505
|
|
|
} |
506
|
|
|
$this->Update($img, $adjstart, $adjend); |
|
|
|
|
507
|
|
|
if (!$this->ticks->IsSpecified()) { |
508
|
|
|
$this->ticks->Set($maj, $min); |
|
|
|
|
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
if ($this->date_format == '') { |
512
|
|
|
$this->ticks->SetLabelDateFormat($format); |
|
|
|
|
513
|
|
|
} else { |
514
|
|
|
$this->ticks->SetLabelDateFormat($this->date_format); |
515
|
|
|
} |
516
|
|
|
} |
517
|
|
|
} |
518
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.