<?php |
<?php |
/*======================================================================= |
/*======================================================================= |
// File: JPGRAPH_UTILS.INC |
// File: JPGRAPH_UTILS.INC |
// Description: Collection of non-essential "nice to have" utilities |
// Description: Collection of non-essential "nice to have" utilities |
// Created: 2005-11-20 |
// Created: 2005-11-20 |
// Ver: $Id: jpgraph_utils.inc.php 1777 2009-08-23 17:34:36Z ljp $ |
// Ver: $Id: jpgraph_utils.inc.php 1777 2009-08-23 17:34:36Z ljp $ |
// |
// |
// Copyright (c) Aditus Consulting. All rights reserved. |
// Copyright (c) Aditus Consulting. All rights reserved. |
//======================================================================== |
//======================================================================== |
*/ |
*/ |
|
|
//=================================================== |
//=================================================== |
// CLASS FuncGenerator |
// CLASS FuncGenerator |
// Description: Utility class to help generate data for function plots. |
// Description: Utility class to help generate data for function plots. |
// The class supports both parametric and regular functions. |
// The class supports both parametric and regular functions. |
//=================================================== |
//=================================================== |
class FuncGenerator { |
class FuncGenerator { |
private $iFunc='',$iXFunc='',$iMin,$iMax,$iStepSize; |
private $iFunc='',$iXFunc='',$iMin,$iMax,$iStepSize; |
|
|
function __construct($aFunc,$aXFunc='') { |
function __construct($aFunc,$aXFunc='') { |
$this->iFunc = $aFunc; |
$this->iFunc = $aFunc; |
$this->iXFunc = $aXFunc; |
$this->iXFunc = $aXFunc; |
} |
} |
|
|
function E($aXMin,$aXMax,$aSteps=50) { |
function E($aXMin,$aXMax,$aSteps=50) { |
$this->iMin = $aXMin; |
$this->iMin = $aXMin; |
$this->iMax = $aXMax; |
$this->iMax = $aXMax; |
$this->iStepSize = ($aXMax-$aXMin)/$aSteps; |
$this->iStepSize = ($aXMax-$aXMin)/$aSteps; |
|
|
if( $this->iXFunc != '' ) |
if( $this->iXFunc != '' ) |
$t = 'for($i='.$aXMin.'; $i<='.$aXMax.'; $i += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]='.$this->iXFunc.';}'; |
$t = 'for($i='.$aXMin.'; $i<='.$aXMax.'; $i += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]='.$this->iXFunc.';}'; |
elseif( $this->iFunc != '' ) |
elseif( $this->iFunc != '' ) |
$t = 'for($x='.$aXMin.'; $x<='.$aXMax.'; $x += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]=$x;} $x='.$aXMax.';$ya[]='.$this->iFunc.';$xa[]=$x;'; |
$t = 'for($x='.$aXMin.'; $x<='.$aXMax.'; $x += '.$this->iStepSize.') {$ya[]='.$this->iFunc.';$xa[]=$x;} $x='.$aXMax.';$ya[]='.$this->iFunc.';$xa[]=$x;'; |
else |
else |
JpGraphError::RaiseL(24001);//('FuncGenerator : No function specified. '); |
JpGraphError::RaiseL(24001);//('FuncGenerator : No function specified. '); |
|
|
@eval($t); |
@eval($t); |
|
|
// If there is an error in the function specifcation this is the only |
// If there is an error in the function specifcation this is the only |
// way we can discover that. |
// way we can discover that. |
if( empty($xa) || empty($ya) ) |
if( empty($xa) || empty($ya) ) |
JpGraphError::RaiseL(24002);//('FuncGenerator : Syntax error in function specification '); |
JpGraphError::RaiseL(24002);//('FuncGenerator : Syntax error in function specification '); |
|
|
return array($xa,$ya); |
return array($xa,$ya); |
} |
} |
} |
} |
|
|
|
|
//============================================================================= |
//============================================================================= |
// CLASS DateScaleUtils |
// CLASS DateScaleUtils |
// Description: Help to create a manual date scale |
// Description: Help to create a manual date scale |
//============================================================================= |
//============================================================================= |
define('DSUTILS_MONTH',1); // Major and minor ticks on a monthly basis |
define('DSUTILS_MONTH',1); // Major and minor ticks on a monthly basis |
define('DSUTILS_MONTH1',1); // Major and minor ticks on a monthly basis |
define('DSUTILS_MONTH1',1); // Major and minor ticks on a monthly basis |
define('DSUTILS_MONTH2',2); // Major ticks on a bi-monthly basis |
define('DSUTILS_MONTH2',2); // Major ticks on a bi-monthly basis |
define('DSUTILS_MONTH3',3); // Major icks on a tri-monthly basis |
define('DSUTILS_MONTH3',3); // Major icks on a tri-monthly basis |
define('DSUTILS_MONTH6',4); // Major on a six-monthly basis |
define('DSUTILS_MONTH6',4); // Major on a six-monthly basis |
define('DSUTILS_WEEK1',5); // Major ticks on a weekly basis |
define('DSUTILS_WEEK1',5); // Major ticks on a weekly basis |
define('DSUTILS_WEEK2',6); // Major ticks on a bi-weekly basis |
define('DSUTILS_WEEK2',6); // Major ticks on a bi-weekly basis |
define('DSUTILS_WEEK4',7); // Major ticks on a quod-weekly basis |
define('DSUTILS_WEEK4',7); // Major ticks on a quod-weekly basis |
define('DSUTILS_DAY1',8); // Major ticks on a daily basis |
define('DSUTILS_DAY1',8); // Major ticks on a daily basis |
define('DSUTILS_DAY2',9); // Major ticks on a bi-daily basis |
define('DSUTILS_DAY2',9); // Major ticks on a bi-daily basis |
define('DSUTILS_DAY4',10); // Major ticks on a qoud-daily basis |
define('DSUTILS_DAY4',10); // Major ticks on a qoud-daily basis |
define('DSUTILS_YEAR1',11); // Major ticks on a yearly basis |
define('DSUTILS_YEAR1',11); // Major ticks on a yearly basis |
define('DSUTILS_YEAR2',12); // Major ticks on a bi-yearly basis |
define('DSUTILS_YEAR2',12); // Major ticks on a bi-yearly basis |
define('DSUTILS_YEAR5',13); // Major ticks on a five-yearly basis |
define('DSUTILS_YEAR5',13); // Major ticks on a five-yearly basis |
|
|
|
|
class DateScaleUtils { |
class DateScaleUtils { |
public static $iMin=0, $iMax=0; |
public static $iMin=0, $iMax=0; |
|
|
private static $starthour,$startmonth, $startday, $startyear; |
private static $starthour,$startmonth, $startday, $startyear; |
private static $endmonth, $endyear, $endday; |
private static $endmonth, $endyear, $endday; |
private static $tickPositions=array(),$minTickPositions=array(); |
private static $tickPositions=array(),$minTickPositions=array(); |
private static $iUseWeeks = true; |
private static $iUseWeeks = true; |
|
|
static function UseWeekFormat($aFlg) { |
static function UseWeekFormat($aFlg) { |
self::$iUseWeeks = $aFlg; |
self::$iUseWeeks = $aFlg; |
} |
} |
|
|
static function doYearly($aType,$aMinor=false) { |
static function doYearly($aType,$aMinor=false) { |
$i=0; $j=0; |
$i=0; $j=0; |
$m = self::$startmonth; |
$m = self::$startmonth; |
$y = self::$startyear; |
$y = self::$startyear; |
|
|
if( self::$startday == 1 ) { |
if( self::$startday == 1 ) { |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
} |
} |
++$m; |
++$m; |
|
|
|
|
switch( $aType ) { |
switch( $aType ) { |
case DSUTILS_YEAR1: |
case DSUTILS_YEAR1: |
for($y=self::$startyear; $y <= self::$endyear; ++$y ) { |
for($y=self::$startyear; $y <= self::$endyear; ++$y ) { |
if( $aMinor ) { |
if( $aMinor ) { |
while( $m <= 12 ) { |
while( $m <= 12 ) { |
if( !($y == self::$endyear && $m > self::$endmonth) ) { |
if( !($y == self::$endyear && $m > self::$endmonth) ) { |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
} |
} |
++$m; |
++$m; |
} |
} |
$m=1; |
$m=1; |
} |
} |
self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); |
} |
} |
break; |
break; |
case DSUTILS_YEAR2: |
case DSUTILS_YEAR2: |
$y=self::$startyear; |
$y=self::$startyear; |
while( $y <= self::$endyear ) { |
while( $y <= self::$endyear ) { |
self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); |
for($k=0; $k < 1; ++$k ) { |
for($k=0; $k < 1; ++$k ) { |
++$y; |
++$y; |
if( $aMinor ) { |
if( $aMinor ) { |
self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); |
} |
} |
} |
} |
++$y; |
++$y; |
} |
} |
break; |
break; |
case DSUTILS_YEAR5: |
case DSUTILS_YEAR5: |
$y=self::$startyear; |
$y=self::$startyear; |
while( $y <= self::$endyear ) { |
while( $y <= self::$endyear ) { |
self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,1,1,$y); |
for($k=0; $k < 4; ++$k ) { |
for($k=0; $k < 4; ++$k ) { |
++$y; |
++$y; |
if( $aMinor ) { |
if( $aMinor ) { |
self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,1,1,$y); |
} |
} |
} |
} |
++$y; |
++$y; |
} |
} |
break; |
break; |
} |
} |
} |
} |
|
|
static function doDaily($aType,$aMinor=false) { |
static function doDaily($aType,$aMinor=false) { |
$m = self::$startmonth; |
$m = self::$startmonth; |
$y = self::$startyear; |
$y = self::$startyear; |
$d = self::$startday; |
$d = self::$startday; |
$h = self::$starthour; |
$h = self::$starthour; |
$i=0;$j=0; |
$i=0;$j=0; |
|
|
if( $h == 0 ) { |
if( $h == 0 ) { |
self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); |
} |
} |
$t = mktime(0,0,0,$m,$d,$y); |
$t = mktime(0,0,0,$m,$d,$y); |
|
|
switch($aType) { |
switch($aType) { |
case DSUTILS_DAY1: |
case DSUTILS_DAY1: |
while( $t <= self::$iMax ) { |
while( $t <= self::$iMax ) { |
$t = strtotime('+1 day',$t); |
$t = strtotime('+1 day',$t); |
self::$tickPositions[$i++] = $t; |
self::$tickPositions[$i++] = $t; |
if( $aMinor ) { |
if( $aMinor ) { |
self::$minTickPositions[$j++] = strtotime('+12 hours',$t); |
self::$minTickPositions[$j++] = strtotime('+12 hours',$t); |
} |
} |
} |
} |
break; |
break; |
case DSUTILS_DAY2: |
case DSUTILS_DAY2: |
while( $t <= self::$iMax ) { |
while( $t <= self::$iMax ) { |
$t = strtotime('+1 day',$t); |
$t = strtotime('+1 day',$t); |
if( $aMinor ) { |
if( $aMinor ) { |
self::$minTickPositions[$j++] = $t; |
self::$minTickPositions[$j++] = $t; |
} |
} |
$t = strtotime('+1 day',$t); |
$t = strtotime('+1 day',$t); |
self::$tickPositions[$i++] = $t; |
self::$tickPositions[$i++] = $t; |
} |
} |
break; |
break; |
case DSUTILS_DAY4: |
case DSUTILS_DAY4: |
while( $t <= self::$iMax ) { |
while( $t <= self::$iMax ) { |
for($k=0; $k < 3; ++$k ) { |
for($k=0; $k < 3; ++$k ) { |
$t = strtotime('+1 day',$t); |
$t = strtotime('+1 day',$t); |
if( $aMinor ) { |
if( $aMinor ) { |
self::$minTickPositions[$j++] = $t; |
self::$minTickPositions[$j++] = $t; |
} |
} |
} |
} |
$t = strtotime('+1 day',$t); |
$t = strtotime('+1 day',$t); |
self::$tickPositions[$i++] = $t; |
self::$tickPositions[$i++] = $t; |
} |
} |
break; |
break; |
} |
} |
} |
} |
|
|
static function doWeekly($aType,$aMinor=false) { |
static function doWeekly($aType,$aMinor=false) { |
$hpd = 3600*24; |
$hpd = 3600*24; |
$hpw = 3600*24*7; |
$hpw = 3600*24*7; |
// Find out week number of min date |
// Find out week number of min date |
$thursday = self::$iMin + $hpd * (3 - (date('w', self::$iMin) + 6) % 7); |
$thursday = self::$iMin + $hpd * (3 - (date('w', self::$iMin) + 6) % 7); |
$week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7; |
$week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7; |
$daynumber = date('w',self::$iMin); |
$daynumber = date('w',self::$iMin); |
if( $daynumber == 0 ) $daynumber = 7; |
if( $daynumber == 0 ) $daynumber = 7; |
$m = self::$startmonth; |
$m = self::$startmonth; |
$y = self::$startyear; |
$y = self::$startyear; |
$d = self::$startday; |
$d = self::$startday; |
$i=0;$j=0; |
$i=0;$j=0; |
// The assumption is that the weeks start on Monday. If the first day |
// The assumption is that the weeks start on Monday. If the first day |
// is later in the week then the first week tick has to be on the following |
// is later in the week then the first week tick has to be on the following |
// week. |
// week. |
if( $daynumber == 1 ) { |
if( $daynumber == 1 ) { |
self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,$d,$y); |
$t = mktime(0,0,0,$m,$d,$y) + $hpw; |
$t = mktime(0,0,0,$m,$d,$y) + $hpw; |
} |
} |
else { |
else { |
$t = mktime(0,0,0,$m,$d,$y) + $hpd*(8-$daynumber); |
$t = mktime(0,0,0,$m,$d,$y) + $hpd*(8-$daynumber); |
} |
} |
|
|
switch($aType) { |
switch($aType) { |
case DSUTILS_WEEK1: |
case DSUTILS_WEEK1: |
$cnt=0; |
$cnt=0; |
break; |
break; |
case DSUTILS_WEEK2: |
case DSUTILS_WEEK2: |
$cnt=1; |
$cnt=1; |
break; |
break; |
case DSUTILS_WEEK4: |
case DSUTILS_WEEK4: |
$cnt=3; |
$cnt=3; |
break; |
break; |
} |
} |
while( $t <= self::$iMax ) { |
while( $t <= self::$iMax ) { |
self::$tickPositions[$i++] = $t; |
self::$tickPositions[$i++] = $t; |
for($k=0; $k < $cnt; ++$k ) { |
for($k=0; $k < $cnt; ++$k ) { |
$t += $hpw; |
$t += $hpw; |
if( $aMinor ) { |
if( $aMinor ) { |
self::$minTickPositions[$j++] = $t; |
self::$minTickPositions[$j++] = $t; |
} |
} |
} |
} |
$t += $hpw; |
$t += $hpw; |
} |
} |
} |
} |
|
|
static function doMonthly($aType,$aMinor=false) { |
static function doMonthly($aType,$aMinor=false) { |
$monthcount=0; |
$monthcount=0; |
$m = self::$startmonth; |
$m = self::$startmonth; |
$y = self::$startyear; |
$y = self::$startyear; |
$i=0; $j=0; |
$i=0; $j=0; |
|
|
// Skip the first month label if it is before the startdate |
// Skip the first month label if it is before the startdate |
if( self::$startday == 1 ) { |
if( self::$startday == 1 ) { |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
$monthcount=1; |
$monthcount=1; |
} |
} |
if( $aType == 1 ) { |
if( $aType == 1 ) { |
if( self::$startday < 15 ) { |
if( self::$startday < 15 ) { |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); |
} |
} |
} |
} |
++$m; |
++$m; |
|
|
// Loop through all the years included in the scale |
// Loop through all the years included in the scale |
for($y=self::$startyear; $y <= self::$endyear; ++$y ) { |
for($y=self::$startyear; $y <= self::$endyear; ++$y ) { |
// Loop through all the months. There are three cases to consider: |
// Loop through all the months. There are three cases to consider: |
// 1. We are in the first year and must start with the startmonth |
// 1. We are in the first year and must start with the startmonth |
// 2. We are in the end year and we must stop at last month of the scale |
// 2. We are in the end year and we must stop at last month of the scale |
// 3. A year in between where we run through all the 12 months |
// 3. A year in between where we run through all the 12 months |
$stopmonth = $y == self::$endyear ? self::$endmonth : 12; |
$stopmonth = $y == self::$endyear ? self::$endmonth : 12; |
while( $m <= $stopmonth ) { |
while( $m <= $stopmonth ) { |
switch( $aType ) { |
switch( $aType ) { |
case DSUTILS_MONTH1: |
case DSUTILS_MONTH1: |
// Set minor tick at the middle of the month |
// Set minor tick at the middle of the month |
if( $aMinor ) { |
if( $aMinor ) { |
if( $m <= $stopmonth ) { |
if( $m <= $stopmonth ) { |
if( !($y==self::$endyear && $m==$stopmonth && self::$endday < 15) ) |
if( !($y==self::$endyear && $m==$stopmonth && self::$endday < 15) ) |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); |
} |
} |
} |
} |
// Major at month |
// Major at month |
// Get timestamp of first hour of first day in each month |
// Get timestamp of first hour of first day in each month |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
|
|
break; |
break; |
case DSUTILS_MONTH2: |
case DSUTILS_MONTH2: |
if( $aMinor ) { |
if( $aMinor ) { |
// Set minor tick at start of each month |
// Set minor tick at start of each month |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
} |
} |
|
|
// Major at every second month |
// Major at every second month |
// Get timestamp of first hour of first day in each month |
// Get timestamp of first hour of first day in each month |
if( $monthcount % 2 == 0 ) { |
if( $monthcount % 2 == 0 ) { |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
} |
} |
break; |
break; |
case DSUTILS_MONTH3: |
case DSUTILS_MONTH3: |
if( $aMinor ) { |
if( $aMinor ) { |
// Set minor tick at start of each month |
// Set minor tick at start of each month |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
} |
} |
// Major at every third month |
// Major at every third month |
// Get timestamp of first hour of first day in each month |
// Get timestamp of first hour of first day in each month |
if( $monthcount % 3 == 0 ) { |
if( $monthcount % 3 == 0 ) { |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
} |
} |
break; |
break; |
case DSUTILS_MONTH6: |
case DSUTILS_MONTH6: |
if( $aMinor ) { |
if( $aMinor ) { |
// Set minor tick at start of each month |
// Set minor tick at start of each month |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
self::$minTickPositions[$j++] = mktime(0,0,0,$m,1,$y); |
} |
} |
// Major at every third month |
// Major at every third month |
// Get timestamp of first hour of first day in each month |
// Get timestamp of first hour of first day in each month |
if( $monthcount % 6 == 0 ) { |
if( $monthcount % 6 == 0 ) { |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
self::$tickPositions[$i++] = mktime(0,0,0,$m,1,$y); |
} |
} |
break; |
break; |
} |
} |
++$m; |
++$m; |
++$monthcount; |
++$monthcount; |
} |
} |
$m=1; |
$m=1; |
} |
} |
|
|
// For the case where all dates are within the same month |
// For the case where all dates are within the same month |
// we want to make sure we have at least two ticks on the scale |
// we want to make sure we have at least two ticks on the scale |
// since the scale want work properly otherwise |
// since the scale want work properly otherwise |
if(self::$startmonth == self::$endmonth && self::$startyear == self::$endyear && $aType==1 ) { |
if(self::$startmonth == self::$endmonth && self::$startyear == self::$endyear && $aType==1 ) { |
self::$tickPositions[$i++] = mktime(0 ,0 ,0, self::$startmonth + 1, 1, self::$startyear); |
self::$tickPositions[$i++] = mktime(0 ,0 ,0, self::$startmonth + 1, 1, self::$startyear); |
} |
} |
|
|
return array(self::$tickPositions,self::$minTickPositions); |
return array(self::$tickPositions,self::$minTickPositions); |
} |
} |
|
|
static function GetTicks($aData,$aType=1,$aMinor=false,$aEndPoints=false) { |
static function GetTicks($aData,$aType=1,$aMinor=false,$aEndPoints=false) { |
$n = count($aData); |
$n = count($aData); |
return self::GetTicksFromMinMax($aData[0],$aData[$n-1],$aType,$aMinor,$aEndPoints); |
return self::GetTicksFromMinMax($aData[0],$aData[$n-1],$aType,$aMinor,$aEndPoints); |
} |
} |
|
|
static function GetAutoTicks($aMin,$aMax,$aMaxTicks=10,$aMinor=false) { |
static function GetAutoTicks($aMin,$aMax,$aMaxTicks=10,$aMinor=false) { |
$diff = $aMax - $aMin; |
$diff = $aMax - $aMin; |
$spd = 3600*24; |
$spd = 3600*24; |
$spw = $spd*7; |
$spw = $spd*7; |
$spm = $spd*30; |
$spm = $spd*30; |
$spy = $spd*352; |
$spy = $spd*352; |
|
|
if( self::$iUseWeeks ) |
if( self::$iUseWeeks ) |
$w = 'W'; |
$w = 'W'; |
else |
else |
$w = 'd M'; |
$w = 'd M'; |
|
|