[ Index ]
 

Code source de jpGraph 2.2

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/src/ -> jpgraph_utils.inc.php (source)

   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 781 2006-10-08 08:07:47Z 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      private $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      static function Get($aSymb,$aCapital=FALSE) {
  56          $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  
  99      $n = count($iSymbols);
 100      $i=0;
 101      $found = false;
 102      $aSymb = strtolower($aSymb);
 103      while( $i < $n && !$found ) {
 104          $found = $aSymb === $iSymbols[$i++][0];
 105      }
 106      if( $found ) {
 107          $ca = $iSymbols[--$i];
 108          if( $aCapital && count($ca)==3 ) 
 109          $s = $ca[2];
 110          else
 111          $s = $ca[1];
 112          return sprintf('&#%04d;',hexdec($s));
 113      }
 114      else
 115          return '';
 116      }
 117  }
 118  
 119  
 120  //=============================================================================
 121  // CLASS DateScaleUtils
 122  // Description: Help to create a manual date scale
 123  //=============================================================================
 124  DEFINE('DSUTILS_MONTH',1); // Major and minor ticks on a monthly basis
 125  DEFINE('DSUTILS_MONTH1',1); // Major and minor ticks on a monthly basis
 126  DEFINE('DSUTILS_MONTH2',2); // Major ticks on a bi-monthly basis
 127  DEFINE('DSUTILS_MONTH3',3); // Major icks on a tri-monthly basis
 128  DEFINE('DSUTILS_MONTH6',4); // Major on a six-monthly basis
 129  DEFINE('DSUTILS_WEEK1',5); // Major ticks on a weekly basis
 130  DEFINE('DSUTILS_WEEK2',6); // Major ticks on a bi-weekly basis
 131  DEFINE('DSUTILS_WEEK4',7); // Major ticks on a quod-weekly basis
 132  DEFINE('DSUTILS_DAY1',8); // Major ticks on a daily basis
 133  DEFINE('DSUTILS_DAY2',9); // Major ticks on a bi-daily basis
 134  DEFINE('DSUTILS_DAY4',10); // Major ticks on a qoud-daily basis
 135  DEFINE('DSUTILS_YEAR1',11); // Major ticks on a yearly basis
 136  DEFINE('DSUTILS_YEAR2',12); // Major ticks on a bi-yearly basis
 137  DEFINE('DSUTILS_YEAR5',13); // Major ticks on a five-yearly basis
 138  
 139  
 140  class DateScaleUtils {
 141      private $starthour,$startmonth, $startday, $startyear;
 142      private $endmonth, $endyear, $endday;
 143      private $tickPositions=array(),$minTickPositions=array();
 144      private $iUseWeeks = true;
 145  
 146      function UseWeekFormat($aFlg) {
 147      $this->iUseWeeks = $aFlg;
 148      }
 149  
 150      function doYearly($aType,$aMinor=false) {
 151      $i=0; $j=0;
 152      $m = $this->startmonth;
 153      $y = $this->startyear;
 154  
 155      if( $this->startday == 1 ) {
 156          $this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
 157      }
 158      ++$m;
 159  
 160  
 161      switch( $aType ) {
 162          case DSUTILS_YEAR1:
 163          for($y=$this->startyear; $y <= $this->endyear; ++$y ) {
 164              if( $aMinor ) {
 165              while( $m <= 12 ) {
 166                  if( !($y == $this->endyear && $m > $this->endmonth) ) {
 167                  $this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
 168                  }
 169                  ++$m;
 170              }
 171              $m=1;
 172              }
 173              $this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);    
 174          }
 175          break;
 176          case DSUTILS_YEAR2:
 177          $y=$this->startyear; 
 178          while( $y <= $this->endyear ) {
 179              $this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);    
 180              for($k=0; $k < 1; ++$k ) { 
 181              ++$y;
 182              if( $aMinor ) {
 183                  $this->minTickPositions[$j++] = mktime(0,0,0,1,1,$y);
 184              }
 185              }
 186              ++$y;
 187          }
 188          break;
 189          case DSUTILS_YEAR5:
 190          $y=$this->startyear; 
 191          while( $y <= $this->endyear ) {
 192              $this->tickPositions[$i++] = mktime(0,0,0,1,1,$y);    
 193              for($k=0; $k < 4; ++$k ) { 
 194              ++$y;
 195              if( $aMinor ) {
 196                  $this->minTickPositions[$j++] = mktime(0,0,0,1,1,$y);
 197              }
 198              }
 199              ++$y;
 200          }
 201          break;
 202      }
 203      }
 204  
 205      function doDaily($aType,$aMinor=false) {
 206      $m = $this->startmonth;
 207      $y = $this->startyear;
 208      $d = $this->startday;
 209      $h = $this->starthour;
 210      $i=0;$j=0;
 211  
 212      if( $h == 0 ) {
 213          $this->tickPositions[$i++] = mktime(0,0,0,$m,$d,$y);
 214          $t = mktime(0,0,0,$m,$d,$y);        
 215      }
 216      else {
 217          $t = mktime(0,0,0,$m,$d,$y);        
 218      }
 219      switch($aType) {
 220          case DSUTILS_DAY1:
 221          while( $t <= $this->iMax ) {
 222              $t += 3600*24;
 223              $this->tickPositions[$i++] = $t;
 224          }
 225          break;
 226          case DSUTILS_DAY2:
 227          while( $t <= $this->iMax ) {
 228              $t += 3600*24;
 229              if( $aMinor ) {
 230              $this->minTickPositions[$j++] = $t;
 231              }
 232              $t += 3600*24;
 233              $this->tickPositions[$i++] = $t;
 234          }
 235          break;
 236          case DSUTILS_DAY4:
 237          while( $t <= $this->iMax ) {
 238              for($k=0; $k < 3; ++$k ) {
 239              $t += 3600*24;
 240              if( $aMinor ) {
 241                  $this->minTickPositions[$j++] = $t;
 242              }
 243              }
 244              $t += 3600*24;
 245              $this->tickPositions[$i++] = $t;
 246          }
 247          break;
 248      }
 249      }
 250  
 251      function doWeekly($aType,$aMinor=false) {
 252      $hpd = 3600*24;
 253      $hpw = 3600*24*7;
 254      // Find out week number of min date
 255      $thursday = $this->iMin + $hpd * (3 - (date('w', $this->iMin) + 6) % 7);
 256      $week = 1 + (date('z', $thursday) - (11 - date('w', mktime(0, 0, 0, 1, 1, date('Y', $thursday)))) % 7) / 7;
 257      $daynumber = date('w',$this->iMin);
 258      if( $daynumber == 0 ) $daynumber = 7;
 259      $m = $this->startmonth;
 260      $y = $this->startyear;
 261      $d = $this->startday;
 262      $i=0;$j=0;
 263      // The assumption is that the weeks start on Monday. If the first day
 264      // is later in the week then the first week tick has to be on the following
 265      // week.
 266      if( $daynumber == 1 ) {
 267          $this->tickPositions[$i++] = mktime(0,0,0,$m,$d,$y);
 268          $t = mktime(0,0,0,$m,$d,$y) + $hpw;
 269      }
 270      else {
 271          $t = mktime(0,0,0,$m,$d,$y) + $hpd*(8-$daynumber);
 272      }
 273  
 274      switch($aType) {
 275          case DSUTILS_WEEK1:
 276          $cnt=0;
 277          break;
 278          case DSUTILS_WEEK2:
 279          $cnt=1;
 280          break;
 281          case DSUTILS_WEEK4:
 282          $cnt=3;
 283          break;
 284      }
 285      while( $t <= $this->iMax ) {
 286          $this->tickPositions[$i++] = $t;
 287          for($k=0; $k < $cnt; ++$k ) {
 288          $t += $hpw;
 289          if( $aMinor ) {
 290              $this->minTickPositions[$j++] = $t;
 291          }
 292          }
 293          $t += $hpw;
 294      }
 295      }
 296  
 297      function doMonthly($aType,$aMinor=false) {
 298      $monthcount=0;
 299      $m = $this->startmonth;
 300      $y = $this->startyear;
 301      $i=0; $j=0;
 302  
 303      // Skip the first month label if it is before the startdate
 304      if( $this->startday == 1 ) {
 305          $this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
 306          $monthcount=1;
 307      }
 308      if( $aType == 1 ) {
 309          if( $this->startday < 15 ) {
 310          $this->minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
 311          }
 312      }
 313      ++$m;
 314  
 315      // Loop through all the years included in the scale
 316      for($y=$this->startyear; $y <= $this->endyear; ++$y ) {
 317          // Loop through all the months. There are three cases to consider:
 318          // 1. We are in the first year and must start with the startmonth
 319          // 2. We are in the end year and we must stop at last month of the scale
 320          // 3. A year in between where we run through all the 12 months
 321          $stopmonth = $y == $this->endyear ? $this->endmonth : 12;
 322          while( $m <= $stopmonth ) {
 323          switch( $aType ) {
 324              case DSUTILS_MONTH1: 
 325              // Set minor tick at the middle of the month
 326              if( $aMinor ) {
 327                  if( $m <= $stopmonth ) {
 328                  if( !($y==$this->endyear && $m==$stopmonth && $this->endday < 15) ) 
 329                  $this->minTickPositions[$j++] = mktime(0,0,0,$m,15,$y);
 330                  }
 331              }
 332              // Major at month 
 333              // Get timestamp of first hour of first day in each month
 334              $this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
 335  
 336              break;
 337              case DSUTILS_MONTH2: 
 338              if( $aMinor ) {
 339                  // Set minor tick at start of each month
 340                  $this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
 341              }
 342  
 343              // Major at every second month 
 344              // Get timestamp of first hour of first day in each month
 345              if( $monthcount % 2 == 0 ) {
 346                  $this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
 347              }
 348              break;
 349              case DSUTILS_MONTH3: 
 350              if( $aMinor ) {
 351                  // Set minor tick at start of each month
 352                  $this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
 353              }
 354                  // Major at every third month 
 355              // Get timestamp of first hour of first day in each month
 356              if( $monthcount % 3 == 0 ) {
 357                  $this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
 358              }
 359              break;
 360              case DSUTILS_MONTH6: 
 361              if( $aMinor ) {
 362                  // Set minor tick at start of each month
 363                  $this->minTickPositions[$j++] = mktime(0,0,0,$m,1,$y);
 364              }
 365              // Major at every third month 
 366              // Get timestamp of first hour of first day in each month
 367              if( $monthcount % 6 == 0 ) {
 368                  $this->tickPositions[$i++] = mktime(0,0,0,$m,1,$y);
 369              }
 370              break;
 371          }
 372          ++$m;
 373          ++$monthcount;
 374          }
 375          $m=1;
 376      }
 377  
 378      // For the case where all dates are within the same month
 379      // we want to make sure we have at least two ticks on the scale
 380      // since the scale want work properly otherwise
 381      if($this->startmonth == $this->endmonth && $this->startyear == $this->endyear && $aType==1 ) {
 382          $this->tickPositions[$i++] = mktime(0 ,0 ,0, $this->startmonth + 1, 1, $this->startyear);
 383      } 
 384  
 385      return array($this->tickPositions,$this->minTickPositions);
 386      }
 387  
 388      function GetTicks($aData,$aType=1,$aMinor=false,$aEndPoints=false) {
 389      $n = count($aData);
 390      return $this->GetTicksFromMinMax($aData[0],$aData[$n-1],$aType,$aMinor,$aEndPoints);
 391      }
 392  
 393      function GetAutoTicks($aMin,$aMax,$aMaxTicks=10,$aMinor=false) {
 394      $diff = $aMax - $aMin;
 395      $spd = 3600*24;
 396      $spw = $spd*7;
 397      $spm = $spd*30;
 398      $spy = $spd*352;
 399  
 400      if( $this->iUseWeeks )
 401          $w = 'W';
 402      else
 403          $w = 'd M';
 404  
 405      // Decision table for suitable scales
 406      // First value: Main decision point
 407      // Second value: Array of formatting depending on divisor for wanted max number of ticks. <divisor><formatting><format-string>,..
 408      $tt = array( 
 409          array($spw, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',-1,DSUTILS_DAY4,'d M')),
 410          array($spm, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',
 411                    7,DSUTILS_WEEK1,$w,-1,DSUTILS_WEEK2,$w)),
 412          array($spy, array(1,DSUTILS_DAY1,'d M',2,DSUTILS_DAY2,'d M',4,DSUTILS_DAY4,'d M',
 413                    7,DSUTILS_WEEK1,$w,14,DSUTILS_WEEK2,$w,
 414                    30,DSUTILS_MONTH1,'M',60,DSUTILS_MONTH2,'M',-1,DSUTILS_MONTH3,'M')),
 415          array(-1, array(30,DSUTILS_MONTH1,'M-Y',60,DSUTILS_MONTH2,'M-Y',90,DSUTILS_MONTH3,'M-Y',
 416                  180,DSUTILS_MONTH6,'M-Y',352,DSUTILS_YEAR1,'Y',704,DSUTILS_YEAR2,'Y',-1,DSUTILS_YEAR5,'Y')));
 417  
 418      $ntt = count($tt);
 419      $nd = floor($diff/$spd);
 420      for($i=0; $i < $ntt; ++$i ) {
 421          if( $diff <= $tt[$i][0] || $i==$ntt-1) {
 422          $t = $tt[$i][1];
 423          $n = count($t)/3;
 424          for( $j=0; $j < $n; ++$j ) {
 425              if( $nd/$t[3*$j] <= $aMaxTicks || $j==$n-1) {
 426              $type = $t[3*$j+1];
 427              $fs = $t[3*$j+2];
 428              list($tickPositions,$minTickPositions) = $this->GetTicksFromMinMax($aMin,$aMax,$type,$aMinor);
 429              return array($fs,$tickPositions,$minTickPositions,$type);
 430              }
 431          }
 432          }
 433      }
 434      }
 435  
 436      function GetTicksFromMinMax($aMin,$aMax,$aType,$aMinor=false,$aEndPoints=false) {
 437      $this->starthour = date('G',$aMin);
 438      $this->startmonth = date('n',$aMin);
 439      $this->startday = date('j',$aMin);
 440      $this->startyear = date('Y',$aMin);
 441      $this->endmonth = date('n',$aMax);
 442      $this->endyear = date('Y',$aMax);
 443      $this->endday = date('j',$aMax);
 444      $this->iMin = $aMin;
 445      $this->iMax = $aMax;
 446  
 447      if( $aType <= DSUTILS_MONTH6 ) {
 448          $this->doMonthly($aType,$aMinor);
 449      }
 450      elseif( $aType <= DSUTILS_WEEK4 ) {
 451          $this->doWeekly($aType,$aMinor);
 452      }
 453      elseif( $aType <= DSUTILS_DAY4 ) {
 454          $this->doDaily($aType,$aMinor);
 455      }
 456      elseif( $aType <= DSUTILS_YEAR5 ) {
 457          $this->doYearly($aType,$aMinor);
 458      }
 459      else {
 460          JpGraphError::RaiseL(24003);
 461      }
 462      // put a label at the very left data pos
 463      if( $aEndPoints ) {
 464          $tickPositions[$i++] = $aData[0];
 465      }
 466  
 467      // put a label at the very right data pos
 468      if( $aEndPoints ) {
 469          $tickPositions[$i] = $aData[$n-1];
 470      }
 471  
 472      return array($this->tickPositions,$this->minTickPositions);
 473      }
 474  
 475  }
 476  
 477  //=============================================================================
 478  // Class ReadFileData
 479  //=============================================================================
 480  Class ReadFileData {
 481  
 482      //----------------------------------------------------------------------------
 483      // Desciption:
 484      // Read numeric data from a file. 
 485      // Each value should be separated by either a new line or by a specified 
 486      // separator character (default is ',').
 487      // Before returning the data each value is converted to a proper float 
 488      // value. The routine is robust in the sense that non numeric data in the 
 489      // file will be discarded.
 490      //
 491      // Returns: 
 492      // The number of data values read on success, FALSE on failure
 493      //----------------------------------------------------------------------------
 494      static function FromCSV($aFile,&$aData,$aSepChar=',',$aMaxLineLength=1024) {
 495      $rh = fopen($aFile,'r');
 496      if( $rh === false )
 497          return false;
 498      $tmp = array();
 499      $lineofdata = fgetcsv($rh, 1000, ',');
 500      while ( $lineofdata !== FALSE) {
 501          $tmp = array_merge($tmp,$lineofdata);
 502          $lineofdata = fgetcsv($rh, $aMaxLineLength, $aSepChar);
 503      }
 504      fclose($rh);
 505  
 506      // Now make sure that all data is numeric. By default
 507      // all data is read as strings
 508      $n = count($tmp);
 509      $aData = array();
 510      $cnt=0;
 511      for($i=0; $i < $n; ++$i) {
 512          if( $tmp[$i] !== "" ) {
 513          $aData[$cnt++] = floatval($tmp[$i]);
 514          }
 515      }
 516      return $cnt;
 517      }
 518  }
 519  
 520  ?>


Généré le : Sat Nov 24 09:27:55 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics