1 |
aurelien |
1 |
<?php
|
|
|
2 |
/*=======================================================================
|
|
|
3 |
// File: JPGRAPH_UTILS.INC
|
|
|
4 |
// Description: Collection of non-essential "nice to have" utilities
|
|
|
5 |
// Created: 2005-11-20
|
|
|
6 |
// Ver: $Id: jpgraph_utils.inc.php 1089 2009-01-18 22:30:30Z ljp $
|
|
|
7 |
//
|
|
|
8 |
// Copyright (c) Aditus Consulting. All rights reserved.
|
|
|
9 |
//========================================================================
|
|
|
10 |
*/
|
|
|
11 |
|
|
|
12 |
//===================================================
|
|
|
13 |
// CLASS FuncGenerator
|
|
|
14 |
// Description: Utility class to help generate data for function plots.
|
|
|
15 |
// The class supports both parametric and regular functions.
|
|
|
16 |
//===================================================
|
|
|
17 |
class FuncGenerator {
|
|
|
18 |
var $iFunc='',$iXFunc='',$iMin,$iMax,$iStepSize;
|
|
|
19 |
|
|
|
20 |
function FuncGenerator($aFunc,$aXFunc='') {
|
|
|
21 |
$this->iFunc = $aFunc;
|
|
|
22 |
$this->iXFunc = $aXFunc;
|
|
|
23 |
}
|
|
|
24 |
|
|
|
25 |
function E($aXMin,$aXMax,$aSteps=50) {
|
|
|
26 |
$this->iMin = $aXMin;
|
|
|
27 |
$this->iMax = $aXMax;
|
|
|
28 |
$this->iStepSize = ($aXMax-$aXMin)/$aSteps;
|
|
|
29 |
|
|
|
30 |
if( $this->iXFunc != '' )
|
|
|
31 |
$t = 'for($i='.$aXMin.'; $i<='.$aXMax.'; $i += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]='.$this->iXFunc.';}';
|
|
|
32 |
elseif( $this->iFunc != '' )
|
|
|
33 |
$t = 'for($x='.$aXMin.'; $x<='.$aXMax.'; $x += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]=$x;} $x='.$aXMax.';$ya[]='.$this->iFunc.';$xa[]=$x;';
|
|
|
34 |
else
|
|
|
35 |
JpGraphError::RaiseL(24001);//('FuncGenerator : No function specified. ');
|
|
|
36 |
|
|
|
37 |
@eval($t);
|
|
|
38 |
|
|
|
39 |
// If there is an error in the function specifcation this is the only
|
|
|
40 |
// way we can discover that.
|
|
|
41 |
if( empty($xa) || empty($ya) )
|
|
|
42 |
JpGraphError::RaiseL(24002);//('FuncGenerator : Syntax error in function specification ');
|
|
|
43 |
|
|
|
44 |
return array($xa,$ya);
|
|
|
45 |
}
|
|
|
46 |
}
|
|
|
47 |
|
|
|
48 |
//=============================================================================
|
|
|
49 |
// CLASS SymChar
|
|
|
50 |
// Description: Code values for some commonly used characters that
|
|
|
51 |
// normally isn't available directly on the keyboard, for example
|
|
|
52 |
// mathematical and greek symbols.
|
|
|
53 |
//=============================================================================
|
|
|
54 |
class SymChar {
|
|
|
55 |
function Get($aSymb,$aCapital=FALSE) {
|
|
|
56 |
static $iSymbols = array(
|
|
|
57 |
/* Greek */
|
|
|
58 |
array('alpha','03B1','0391'),
|
|
|
59 |
array('beta','03B2','0392'),
|
|
|
60 |
array('gamma','03B3','0393'),
|
|
|
61 |
array('delta','03B4','0394'),
|
|
|
62 |
array('epsilon','03B5','0395'),
|
|
|
63 |
array('zeta','03B6','0396'),
|
|
|
64 |
array('ny','03B7','0397'),
|
|
|
65 |
array('eta','03B8','0398'),
|
|
|
66 |
array('theta','03B8','0398'),
|
|
|
67 |
array('iota','03B9','0399'),
|
|
|
68 |
array('kappa','03BA','039A'),
|
|
|
69 |
array('lambda','03BB','039B'),
|
|
|
70 |
array('mu','03BC','039C'),
|
|
|
71 |
array('nu','03BD','039D'),
|
|
|
72 |
array('xi','03BE','039E'),
|
|
|
73 |
array('omicron','03BF','039F'),
|
|
|
74 |
array('pi','03C0','03A0'),
|
|
|
75 |
array('rho','03C1','03A1'),
|
|
|
76 |
array('sigma','03C3','03A3'),
|
|
|
77 |
array('tau','03C4','03A4'),
|
|
|
78 |
array('upsilon','03C5','03A5'),
|
|
|
79 |
array('phi','03C6','03A6'),
|
|
|
80 |
array('chi','03C7','03A7'),
|
|
|
81 |
array('psi','03C8','03A8'),
|
|
|
82 |
array('omega','03C9','03A9'),
|
|
|
83 |
/* Money */
|
|
|
84 |
array('euro','20AC'),
|
|
|
85 |
array('yen','00A5'),
|
|
|
86 |
array('pound','20A4'),
|
|
|
87 |
/* Math */
|
|
|
88 |
array('approx','2248'),
|
|
|
89 |
array('neq','2260'),
|
|
|
90 |
array('not','2310'),
|
|
|
91 |
array('def','2261'),
|
|
|
92 |
array('inf','221E'),
|
|
|
93 |
array('sqrt','221A'),
|
|
|
94 |
array('int','222B'),
|
|
|
95 |
/* Misc */
|
|
|
96 |
array('copy','00A9'),
|
|
|
97 |
array('para','00A7'),
|
|
|
98 |
array('tm','2122'), /* Trademark symbol */
|
|
|
99 |
array('rtm','00AE') /* Registered trademark */
|
|
|
100 |
);
|
|
|
101 |
|
|
|
102 |
$n = count($iSymbols);
|
|
|
103 |
$i=0;
|
|
|
104 |
$found = false;
|
|
|
105 |
$aSymb = strtolower($aSymb);
|
|
|
106 |
while( $i < $n && !$found ) {
|
|
|
107 |
$found = $aSymb === $iSymbols[$i++][0];
|
|
|
108 |
}
|
|
|
109 |
if( $found ) {
|
|
|
110 |
$ca = $iSymbols[--$i];
|
|
|
111 |
if( $aCapital && count($ca)==3 )
|
|
|
112 |
$s = $ca[2];
|
|
|
113 |
else
|
|
|
114 |
$s = $ca[1];
|
|
|
115 |
return sprintf('&#%04d;',hexdec($s));
|
|
|
116 |
}
|
|
|
117 |
else
|
|
|
118 |
return '';
|
|
|
119 |
}
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
|
|
|
123 |
//=============================================================================
|
|
|
124 |
// CLASS DateScaleUtils
|
|
|
125 |
// Description: Help to create a manual date scale
|
|
|
126 |
//=============================================================================
|
|
|
127 |
DEFINE('DSUTILS_MONTH',1); // Major and minor ticks on a monthly basis
|
|
|
128 |
DEFINE('DSUTILS_MONTH1',1); // Major and minor ticks on a monthly basis
|
|
|
129 |
DEFINE('DSUTILS_MONTH2',2); // Major ticks on a bi-monthly basis
|
|
|
130 |
DEFINE('DSUTILS_MONTH3',3); // Major icks on a tri-monthly basis
|
|
|
131 |
DEFINE('DSUTILS_MONTH6',4); // Major on a six-monthly basis
|
|
|
132 |
DEFINE('DSUTILS_WEEK1',5); // Major ticks on a weekly basis
|
|
|
133 |
DEFINE('DSUTILS_WEEK2',6); // Major ticks on a bi-weekly basis
|
|
|
134 |
DEFINE('DSUTILS_WEEK4',7); // Major ticks on a quod-weekly basis
|
|
|
135 |
DEFINE('DSUTILS_DAY1',8); // Major ticks on a daily basis
|
|
|
136 |
DEFINE('DSUTILS_DAY2',9); // Major ticks on a bi-daily basis
|
|
|
137 |
DEFINE('DSUTILS_DAY4',10); // Major ticks on a qoud-daily basis
|
|
|
138 |
DEFINE('DSUTILS_YEAR1',11); // Major ticks on a yearly basis
|
|
|
139 |
DEFINE('DSUTILS_YEAR2',12); // Major ticks on a bi-yearly basis
|
|
|
140 |
DEFINE('DSUTILS_YEAR5',13); // Major ticks on a five-yearly basis
|
|
|
141 |
|
|
|
142 |
|
|
|
143 |
class DateScaleUtils {
|
|
|
144 |
var $iMin=0, $iMax=0;
|
|
|
145 |
var $starthour,$startmonth, $startday, $startyear;
|
|
|
146 |
var $endmonth, $endyear, $endday;
|
|
|
147 |
var $tickPositions=array(),$minTickPositions=array();
|
|
|
148 |
var $iUseWeeks = true;
|
|
|
149 |
|
|
|
150 |
function UseWeekFormat($aFlg) {
|
|
|
151 |
$this->iUseWeeks = $aFlg;
|
|
|
152 |
}
|
|
|
153 |
|
|
|
154 |
function doYearly($aType,$aMinor=false) {
|
|
|
155 |
$i=0; $j=0;
|
|
|
156 |
$m = $this->startmonth;
|
|
|
157 |
$y = $this->startyear;
|
|
|
158 |
|
|
|
159 |
if( $this->startday == 1 ) {
|
|
|
160 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
|
|
|
161 |
}
|
|
|
162 |
++$m;
|
|
|
163 |
|
|
|
164 |
switch( $aType ) {
|
|
|
165 |
case DSUTILS_YEAR1:
|
|
|
166 |
for($y=$this->startyear; $y <= $this->endyear; ++$y ) {
|
|
|
167 |
if( $aMinor ) {
|
|
|
168 |
while( $m <= 12 ) {
|
|
|
169 |
if( !($y == $this->endyear && $m > $this->endmonth) ) {
|
|
|
170 |
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
|
|
|
171 |
}
|
|
|
172 |
++$m;
|
|
|
173 |
}
|
|
|
174 |
$m=1;
|
|
|
175 |
}
|
|
|
176 |
$this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);
|
|
|
177 |
}
|
|
|
178 |
break;
|
|
|
179 |
case DSUTILS_YEAR2:
|
|
|
180 |
$y=$this->startyear;
|
|
|
181 |
while( $y <= $this->endyear ) {
|
|
|
182 |
$this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);
|
|
|
183 |
for($k=0; $k < 1; ++$k ) {
|
|
|
184 |
++$y;
|
|
|
185 |
if( $aMinor ) {
|
|
|
186 |
$this->minTickPositions[$j++] = mktime(0,0,0,1,1,$y);
|
|
|
187 |
}
|
|
|
188 |
}
|
|
|
189 |
++$y;
|
|
|
190 |
}
|
|
|
191 |
break;
|
|
|
192 |
case DSUTILS_YEAR5:
|
|
|
193 |
$y=$this->startyear;
|
|
|
194 |
while( $y <= $this->endyear ) {
|
|
|
195 |
$this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);
|
|
|
196 |
for($k=0; $k < 4; ++$k ) {
|
|
|
197 |
++$y;
|
|
|
198 |
if( $aMinor ) {
|
|
|
199 |
$this->minTickPositions[$j++] = mktime(0,0,0,1,1,$y);
|
|
|
200 |
}
|
|
|
201 |
}
|
|
|
202 |
++$y;
|
|
|
203 |
}
|
|
|
204 |
break;
|
|
|
205 |
}
|
|
|
206 |
}
|
|
|
207 |
|
|
|
208 |
function doDaily($aType,$aMinor=false) {
|
|
|
209 |
$m = $this->startmonth;
|
|
|
210 |
$y = $this->startyear;
|
|
|
211 |
$d = $this->startday;
|
|
|
212 |
$h = $this->starthour;
|
|
|
213 |
$i=0;$j=0;
|
|
|
214 |
|
|
|
215 |
if( $h == 0 ) {
|
|
|
216 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,$d,$y);
|
|
|
217 |
}
|
|
|
218 |
$t = mktime(0,0,0,$m,$d,$y);
|
|
|
219 |
switch($aType) {
|
|
|
220 |
case DSUTILS_DAY1:
|
|
|
221 |
while( $t <= self::$iMax ) {
|
|
|
222 |
$t = strtotime('+1 day',$t);
|
|
|
223 |
$this->tickPositions[$i++] = $t;
|
|
|
224 |
if( $aMinor ) {
|
|
|
225 |
$this->minTickPositions[$j++] = strtotime('+12 hours',$t);
|
|
|
226 |
}
|
|
|
227 |
}
|
|
|
228 |
break;
|
|
|
229 |
case DSUTILS_DAY2:
|
|
|
230 |
while( $t <= $this->iMax ) {
|
|
|
231 |
$t = strtotime('+1 day',$t);
|
|
|
232 |
if( $aMinor ) {
|
|
|
233 |
$this->minTickPositions[$j++] = $t;
|
|
|
234 |
}
|
|
|
235 |
$t = strtotime('+1 day',$t);
|
|
|
236 |
$this->tickPositions[$i++] = $t;
|
|
|
237 |
}
|
|
|
238 |
break;
|
|
|
239 |
case DSUTILS_DAY4:
|
|
|
240 |
while( $t <= $this->iMax ) {
|
|
|
241 |
for($k=0; $k < 3; ++$k ) {
|
|
|
242 |
$t = strtotime('+1 day',$t);
|
|
|
243 |
if( $aMinor ) {
|
|
|
244 |
$this->minTickPositions[$j++] = $t;
|
|
|
245 |
}
|
|
|
246 |
}
|
|
|
247 |
$t = strtotime('+1 day',$t);
|
|
|
248 |
$this->tickPositions[$i++] = $t;
|
|
|
249 |
}
|
|
|
250 |
break;
|
|
|
251 |
}
|
|
|
252 |
}
|
|
|
253 |
|
|
|
254 |
function doWeekly($aType,$aMinor=false) {
|
|
|
255 |
$hpd = 3600*24;
|
|
|
256 |
$hpw = 3600*24*7;
|
|
|
257 |
// Find out week number of min date
|
|
|
258 |
$thursday = $this->iMin + $hpd * (3 - (date('w', $this->iMin) + 6) % 7);
|
|
|
259 |
$week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7;
|
|
|
260 |
$daynumber = date('w',$this->iMin);
|
|
|
261 |
if( $daynumber == 0 ) $daynumber = 7;
|
|
|
262 |
$m = $this->startmonth;
|
|
|
263 |
$y = $this->startyear;
|
|
|
264 |
$d = $this->startday;
|
|
|
265 |
$i=0;$j=0;
|
|
|
266 |
// The assumption is that the weeks start on Monday. If the first day
|
|
|
267 |
// is later in the week then the first week tick has to be on the following
|
|
|
268 |
// week.
|
|
|
269 |
if( $daynumber == 1 ) {
|
|
|
270 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,$d,$y);
|
|
|
271 |
$t = mktime(0,0,0,$m,$d,$y) + $hpw;
|
|
|
272 |
}
|
|
|
273 |
else {
|
|
|
274 |
$t = mktime(0,0,0,$m,$d,$y) + $hpd*(8-$daynumber);
|
|
|
275 |
}
|
|
|
276 |
|
|
|
277 |
switch($aType) {
|
|
|
278 |
case DSUTILS_WEEK1:
|
|
|
279 |
$cnt=0;
|
|
|
280 |
break;
|
|
|
281 |
case DSUTILS_WEEK2:
|
|
|
282 |
$cnt=1;
|
|
|
283 |
break;
|
|
|
284 |
case DSUTILS_WEEK4:
|
|
|
285 |
$cnt=3;
|
|
|
286 |
break;
|
|
|
287 |
}
|
|
|
288 |
while( $t <= $this->iMax ) {
|
|
|
289 |
$this->tickPositions[$i++] = $t;
|
|
|
290 |
for($k=0; $k < $cnt; ++$k ) {
|
|
|
291 |
$t += $hpw;
|
|
|
292 |
if( $aMinor ) {
|
|
|
293 |
$this->minTickPositions[$j++] = $t;
|
|
|
294 |
}
|
|
|
295 |
}
|
|
|
296 |
$t += $hpw;
|
|
|
297 |
}
|
|
|
298 |
}
|
|
|
299 |
|
|
|
300 |
function doMonthly($aType,$aMinor=false) {
|
|
|
301 |
$monthcount=0;
|
|
|
302 |
$m = $this->startmonth;
|
|
|
303 |
$y = $this->startyear;
|
|
|
304 |
$i=0; $j=0;
|
|
|
305 |
|
|
|
306 |
// Skip the first month label if it is before the startdate
|
|
|
307 |
if( $this->startday == 1 ) {
|
|
|
308 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
|
|
|
309 |
$monthcount=1;
|
|
|
310 |
}
|
|
|
311 |
if( $aType == 1 ) {
|
|
|
312 |
if( $this->startday < 15 ) {
|
|
|
313 |
$this->minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
|
|
|
314 |
}
|
|
|
315 |
}
|
|
|
316 |
++$m;
|
|
|
317 |
|
|
|
318 |
// Loop through all the years included in the scale
|
|
|
319 |
for($y=$this->startyear; $y <= $this->endyear; ++$y ) {
|
|
|
320 |
// Loop through all the months. There are three cases to consider:
|
|
|
321 |
// 1. We are in the first year and must start with the startmonth
|
|
|
322 |
// 2. We are in the end year and we must stop at last month of the scale
|
|
|
323 |
// 3. A year in between where we run through all the 12 months
|
|
|
324 |
$stopmonth = $y == $this->endyear ? $this->endmonth : 12;
|
|
|
325 |
while( $m <= $stopmonth ) {
|
|
|
326 |
switch( $aType ) {
|
|
|
327 |
case DSUTILS_MONTH1:
|
|
|
328 |
// Set minor tick at the middle of the month
|
|
|
329 |
if( $aMinor ) {
|
|
|
330 |
if( $m <= $stopmonth ) {
|
|
|
331 |
if( !($y==$this->endyear && $m==$stopmonth && $this->endday < 15) )
|
|
|
332 |
$this->minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
|
|
|
333 |
}
|
|
|
334 |
}
|
|
|
335 |
// Major at month
|
|
|
336 |
// Get timestamp of first hour of first day in each month
|
|
|
337 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
|
|
|
338 |
|
|
|
339 |
break;
|
|
|
340 |
case DSUTILS_MONTH2:
|
|
|
341 |
if( $aMinor ) {
|
|
|
342 |
// Set minor tick at start of each month
|
|
|
343 |
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
|
|
|
344 |
}
|
|
|
345 |
|
|
|
346 |
// Major at every second month
|
|
|
347 |
// Get timestamp of first hour of first day in each month
|
|
|
348 |
if( $monthcount % 2 == 0 ) {
|
|
|
349 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
|
|
|
350 |
}
|
|
|
351 |
break;
|
|
|
352 |
case DSUTILS_MONTH3:
|
|
|
353 |
if( $aMinor ) {
|
|
|
354 |
// Set minor tick at start of each month
|
|
|
355 |
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
|
|
|
356 |
}
|
|
|
357 |
// Major at every third month
|
|
|
358 |
// Get timestamp of first hour of first day in each month
|
|
|
359 |
if( $monthcount % 3 == 0 ) {
|
|
|
360 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
|
|
|
361 |
}
|
|
|
362 |
break;
|
|
|
363 |
case DSUTILS_MONTH6:
|
|
|
364 |
if( $aMinor ) {
|
|
|
365 |
// Set minor tick at start of each month
|
|
|
366 |
$this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
|
|
|
367 |
}
|
|
|
368 |
// Major at every third month
|
|
|
369 |
// Get timestamp of first hour of first day in each month
|
|
|
370 |
if( $monthcount % 6 == 0 ) {
|
|
|
371 |
$this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
|
|
|
372 |
}
|
|
|
373 |
break;
|
|
|
374 |
}
|
|
|
375 |
++$m;
|
|
|
376 |
++$monthcount;
|
|
|
377 |
}
|
|
|
378 |
$m=1;
|
|
|
379 |
}
|
|
|
380 |
|
|
|
381 |
// For the case where all dates are within the same month
|
|
|
382 |
// we want to make sure we have at least two ticks on the scale
|
|
|
383 |
// since the scale want work properly otherwise
|
|
|
384 |
if($this->startmonth == $this->endmonth && $this->startyear == $this->endyear && $aType==1 ) {
|
|
|
385 |
$this->tickPositions[$i++] = mktime(0 ,0 ,0, $this->startmonth + 1, 1, $this->startyear);
|
|
|
386 |
}
|
|
|
387 |
|
|
|
388 |
return array($this->tickPositions,$this->minTickPositions);
|
|
|
389 |
}
|
|
|
390 |
|
|
|
391 |
function GetTicks($aData,$aType=1,$aMinor=false,$aEndPoints=false) {
|
|
|
392 |
$n = count($aData);
|
|
|
393 |
return $this->GetTicksFromMinMax($aData[0],$aData[$n-1],$aType,$aMinor,$aEndPoints);
|
|
|
394 |
}
|
|
|
395 |
|
|
|
396 |
function GetAutoTicks($aMin,$aMax,$aMaxTicks=10,$aMinor=false) {
|
|
|
397 |
$diff = $aMax - $aMin;
|
|
|
398 |
$spd = 3600*24;
|
|
|
399 |
$spw = $spd*7;
|
|
|
400 |
$spm = $spd*30;
|
|
|
401 |
$spy = $spd*352;
|
|
|
402 |
|
|
|
403 |
if( $this->iUseWeeks )
|
|
|
404 |
$w = 'W';
|
|
|
405 |
else
|
|
|
406 |
$w = 'd M';
|
|
|
407 |
|
|
|
408 |
// Decision table for suitable scales
|
|
|
409 |
// First value: Main decision point
|
|
|
410 |
// Second value: Array of formatting depending on divisor for wanted max number of ticks. <divisor><formatting><format-string>,..
|
|
|
411 |
$tt = array(
|
|
|
412 |
array($spw, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',-1,DSUTILS_DAY4,'d M')),
|
|
|
413 |
array($spm, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',
|
|
|
414 |
7,DSUTILS_WEEK1,$w,-1,DSUTILS_WEEK2,$w)),
|
|
|
415 |
array($spy, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',
|
|
|
416 |
7,DSUTILS_WEEK1,$w,14,DSUTILS_WEEK2,$w,
|
|
|
417 |
30,DSUTILS_MONTH1,'M',60,DSUTILS_MONTH2,'M',-1,DSUTILS_MONTH3,'M')),
|
|
|
418 |
array(-1, array(30,DSUTILS_MONTH1,'M-Y',60,DSUTILS_MONTH2,'M-Y',90,DSUTILS_MONTH3,'M-Y',
|
|
|
419 |
180,DSUTILS_MONTH6,'M-Y',352,DSUTILS_YEAR1,'Y',704,DSUTILS_YEAR2,'Y',-1,DSUTILS_YEAR5,'Y')));
|
|
|
420 |
|
|
|
421 |
$ntt = count($tt);
|
|
|
422 |
$nd = floor($diff/$spd);
|
|
|
423 |
for($i=0; $i < $ntt; ++$i ) {
|
|
|
424 |
if( $diff <= $tt[$i][0] || $i==$ntt-1) {
|
|
|
425 |
$t = $tt[$i][1];
|
|
|
426 |
$n = count($t)/3;
|
|
|
427 |
for( $j=0; $j < $n; ++$j ) {
|
|
|
428 |
if( $nd/$t[3*$j] <= $aMaxTicks || $j==$n-1) {
|
|
|
429 |
$type = $t[3*$j+1];
|
|
|
430 |
$fs = $t[3*$j+2];
|
|
|
431 |
list($tickPositions,$minTickPositions) = $this->GetTicksFromMinMax($aMin,$aMax,$type,$aMinor);
|
|
|
432 |
return array($fs,$tickPositions,$minTickPositions,$type);
|
|
|
433 |
}
|
|
|
434 |
}
|
|
|
435 |
}
|
|
|
436 |
}
|
|
|
437 |
}
|
|
|
438 |
|
|
|
439 |
function GetTicksFromMinMax($aMin,$aMax,$aType,$aMinor=false,$aEndPoints=false) {
|
|
|
440 |
$this->starthour = date('G',$aMin);
|
|
|
441 |
$this->startmonth = date('n',$aMin);
|
|
|
442 |
$this->startday = date('j',$aMin);
|
|
|
443 |
$this->startyear = date('Y',$aMin);
|
|
|
444 |
$this->endmonth = date('n',$aMax);
|
|
|
445 |
$this->endyear = date('Y',$aMax);
|
|
|
446 |
$this->endday = date('j',$aMax);
|
|
|
447 |
$this->iMin = $aMin;
|
|
|
448 |
$this->iMax = $aMax;
|
|
|
449 |
|
|
|
450 |
if( $aType <= DSUTILS_MONTH6 ) {
|
|
|
451 |
$this->doMonthly($aType,$aMinor);
|
|
|
452 |
}
|
|
|
453 |
elseif( $aType <= DSUTILS_WEEK4 ) {
|
|
|
454 |
$this->doWeekly($aType,$aMinor);
|
|
|
455 |
}
|
|
|
456 |
elseif( $aType <= DSUTILS_DAY4 ) {
|
|
|
457 |
$this->doDaily($aType,$aMinor);
|
|
|
458 |
}
|
|
|
459 |
elseif( $aType <= DSUTILS_YEAR5 ) {
|
|
|
460 |
$this->doYearly($aType,$aMinor);
|
|
|
461 |
}
|
|
|
462 |
else {
|
|
|
463 |
JpGraphError::RaiseL(24003);
|
|
|
464 |
}
|
|
|
465 |
// put a label at the very left data pos
|
|
|
466 |
if( $aEndPoints ) {
|
|
|
467 |
$tickPositions[$i++] = $aData[0];
|
|
|
468 |
}
|
|
|
469 |
|
|
|
470 |
// put a label at the very right data pos
|
|
|
471 |
if( $aEndPoints ) {
|
|
|
472 |
$tickPositions[$i] = $aData[$n-1];
|
|
|
473 |
}
|
|
|
474 |
|
|
|
475 |
return array($this->tickPositions,$this->minTickPositions);
|
|
|
476 |
}
|
|
|
477 |
|
|
|
478 |
}
|
|
|
479 |
|
|
|
480 |
//=============================================================================
|
|
|
481 |
// Class ReadFileData
|
|
|
482 |
//=============================================================================
|
|
|
483 |
Class ReadFileData {
|
|
|
484 |
|
|
|
485 |
//----------------------------------------------------------------------------
|
|
|
486 |
// Desciption:
|
|
|
487 |
// Read numeric data from a file.
|
|
|
488 |
// Each value should be separated by either a new line or by a specified
|
|
|
489 |
// separator character (default is ',').
|
|
|
490 |
// Before returning the data each value is converted to a proper float
|
|
|
491 |
// value. The routine is robust in the sense that non numeric data in the
|
|
|
492 |
// file will be discarded.
|
|
|
493 |
//
|
|
|
494 |
// Returns:
|
|
|
495 |
// The number of data values read on success, FALSE on failure
|
|
|
496 |
//----------------------------------------------------------------------------
|
|
|
497 |
function FromCSV($aFile,&$aData,$aSepChar=',',$aMaxLineLength=1024) {
|
|
|
498 |
$rh = fopen($aFile,'r');
|
|
|
499 |
if( $rh === false )
|
|
|
500 |
return false;
|
|
|
501 |
$tmp = array();
|
|
|
502 |
$lineofdata = fgetcsv($rh, 1000, ',');
|
|
|
503 |
while ( $lineofdata !== FALSE) {
|
|
|
504 |
$tmp = array_merge($tmp,$lineofdata);
|
|
|
505 |
$lineofdata = fgetcsv($rh, $aMaxLineLength, $aSepChar);
|
|
|
506 |
}
|
|
|
507 |
fclose($rh);
|
|
|
508 |
|
|
|
509 |
// Now make sure that all data is numeric. By default
|
|
|
510 |
// all data is read as strings
|
|
|
511 |
$n = count($tmp);
|
|
|
512 |
$aData = array();
|
|
|
513 |
$cnt=0;
|
|
|
514 |
for($i=0; $i < $n; ++$i) {
|
|
|
515 |
if( $tmp[$i] !== "" ) {
|
|
|
516 |
$aData[$cnt++] = floatval($tmp[$i]);
|
|
|
517 |
}
|
|
|
518 |
}
|
|
|
519 |
return $cnt;
|
|
|
520 |
}
|
|
|
521 |
}
|
|
|
522 |
|
|
|
523 |
?>
|