home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / dotproject / lib / jpgraph / src / jpgraph_log.php < prev    next >
PHP Script  |  2002-12-11  |  7KB  |  224 lines

  1. <?php
  2. /*=======================================================================
  3. // File:     JPGRAPH_LOG.PHP
  4. // Description:    Log scale plot extension for JpGraph
  5. // Created:     2001-01-08
  6. // Author:    Johan Persson (johanp@aditus.nu)
  7. // Ver:        $Id: jpgraph_log.php,v 1.1 2002/12/11 09:41:58 kripper Exp $
  8. //
  9. // License:    This code is released under QPL
  10. // Copyright (C) 2001,2002 Johan Persson
  11. //========================================================================
  12. */
  13.  
  14.  
  15. DEFINE('LOGLABELS_PLAIN',0);
  16. DEFINE('LOGLABELS_MAGNITUDE',1);
  17.  
  18. //===================================================
  19. // CLASS LogScale
  20. // Description: Logarithmic scale between world and screen
  21. //===================================================
  22. class LogScale extends LinearScale {
  23. //---------------
  24. // CONSTRUCTOR
  25.  
  26.     // Log scale is specified using the log of min and max
  27.     function LogScale($min,$max,$type="y") {
  28.     $this->LinearScale($min,$max,$type);
  29.     $this->ticks = new LogTicks();
  30.     }
  31.  
  32. //----------------
  33. // PUBLIC METHODS    
  34.  
  35.     // Translate between world and screen
  36.     function    Translate($a) {
  37.     if( $a < 0 ) {
  38.         JpGraphError::Raise("Negative data values can not be used in a log scale.");
  39.         exit(1);
  40.     }
  41.     if( $a==0 ) $a=1;
  42.     $a=log10($a);
  43.     return floor($this->off + ($a*1.0 - $this->scale[0]) * $this->scale_factor); 
  44.     }
  45.  
  46.     // Relative translate (don't include offset) usefull when we just want
  47.     // to know the relative position (in pixels) on the axis    
  48.     function RelTranslate($a) {
  49.     if( $a==0 ) $a=1;
  50.     $a=log10($a);
  51.     return ($a*1.0 - $this->scale[0]) * $this->scale_factor; 
  52.     }
  53.         
  54.     // Use bcpow() for increased precision
  55.     function GetMinVal() {
  56.     if( function_exists("bcpow") )
  57.         return round(bcpow(10,$this->scale[0],15),14);
  58.     else
  59.         return round(pow(10,$this->scale[0]));
  60.     }
  61.     
  62.     function GetMaxVal() {
  63.     if( function_exists("bcpow") )
  64.         return round(bcpow(10,$this->scale[1],15),14);
  65.     else
  66.         return round(pow(10,$this->scale[1]));
  67.     }
  68.     
  69.     // Logarithmic autoscaling is much simplier since we just
  70.     // set the min and max to logs of the min and max values.
  71.     // Note that for log autoscale the "maxstep" the fourth argument
  72.     // isn't used. This is just included to give the method the same
  73.     // signature as the linear counterpart.
  74.     function AutoScale(&$img,$min,$max,$dummy) {
  75.     if( $min==0 ) $min=1;
  76.     assert($max>0);        
  77.     $smin = floor(log10($min));
  78.     $smax = ceil(log10($max));
  79.     $this->Update($img,$smin,$smax);                    
  80.     }
  81. //---------------
  82. // PRIVATE METHODS    
  83. } // Class
  84.  
  85. //===================================================
  86. // CLASS LogTicks
  87. // Description: 
  88. //===================================================
  89. class LogTicks extends Ticks{
  90.     var $label_logtype=LOGLABELS_MAGNITUDE;
  91. //---------------
  92. // CONSTRUCTOR
  93.     function LogTicks() {
  94.     }
  95. //---------------
  96. // PUBLIC METHODS    
  97.     function IsSpecified() {
  98.     return true;
  99.     }
  100.  
  101.     function SetLabelLogType($aType) {
  102.     $this->label_logtype = $aType;
  103.     }
  104.     
  105.     // For log scale it's meaningless to speak about a major step
  106.     // We just return -1 to make the framework happy (specifically
  107.     // StrokeLabels() )
  108.     function GetMajor() {
  109.     return -1;
  110.     }
  111.  
  112.     function SetTextLabelStart($aStart) {
  113.     JpGraphError::Raise('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.');
  114.     }
  115.  
  116.     function SetXLabelOffset($dummy) {
  117.     // For log scales we dont care about XLabel offset
  118.     }
  119.  
  120.     // Draw ticks on image "img" using scale "scale". The axis absolute
  121.     // position in the image is specified in pos, i.e. for an x-axis
  122.     // it specifies the absolute y-coord and for Y-ticks it specified the
  123.     // absolute x-position.
  124.     function Stroke(&$img,&$scale,$pos) {
  125.     $start = $scale->GetMinVal();
  126.     $limit = $scale->GetMaxVal();
  127.     $nextMajor = 10*$start;
  128.     $step = $nextMajor / 10.0;
  129.         
  130.         
  131.     $img->SetLineWeight($this->weight);            
  132.         
  133.     if( $scale->type == "y" ) {
  134.         // member direction specified if the ticks should be on
  135.         // left or right side.
  136.         $a=$pos + $this->direction*$this->GetMinTickAbsSize();
  137.         $a2=$pos + $this->direction*$this->GetMajTickAbsSize();    
  138.             
  139.         $count=1; 
  140.         $this->maj_ticks_pos[0]=$scale->Translate($start);
  141.         $this->maj_ticklabels_pos[0]=$scale->Translate($start);
  142.         if( $this->supress_first )
  143.         $this->maj_ticks_label[0]="";
  144.         else {
  145.         if( $this->label_formfunc != '' ) {
  146.             $f = $this->label_formfunc;
  147.             $this->maj_ticks_label[0]=$f($start);    
  148.         }
  149.         elseif( $this->label_logtype == LOGLABELS_PLAIN )
  150.             $this->maj_ticks_label[0]=$start;    
  151.         else
  152.             $this->maj_ticks_label[0]='10^'.round(log10($start));
  153.         }
  154.         $i=1;
  155.         for($y=$start; $y<=$limit; $y+=$step,++$count  ) {
  156.         $ys=$scale->Translate($y);    
  157.         $this->ticks_pos[]=$ys;
  158.         $this->ticklabels_pos[]=$ys;
  159.         if( $count % 10 == 0 ) {
  160.             if( $this->majcolor!="" ) {
  161.             $img->PushColor($this->majcolor);
  162.             $img->Line($pos,$ys,$a2,$ys);
  163.             $img->PopColor();
  164.             }
  165.             else
  166.             $img->Line($pos,$ys,$a2,$ys);
  167.  
  168.             $this->maj_ticks_pos[$i]=$ys;
  169.             $this->maj_ticklabels_pos[$i]=$ys;
  170.             
  171.             if( $this->label_formfunc != '' ) {
  172.             $f = $this->label_formfunc;
  173.             $this->maj_ticks_label[$i]=$f($nextMajor);    
  174.             }
  175.             elseif( $this->label_logtype == 0 )
  176.             $this->maj_ticks_label[$i]=$nextMajor;    
  177.             else
  178.             $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor));
  179.             ++$i;                        
  180.             $nextMajor *= 10;
  181.             $step *= 10;    
  182.             $count=1;                 
  183.         }
  184.         else {
  185.             if( $this->mincolor!="" ) $img->PushColor($this->mincolor);
  186.             $img->Line($pos,$ys,$a,$ys);        
  187.             if( $this->mincolor!="" ) $img->PopCOlor();
  188.         }
  189.         }        
  190.     }
  191.     else {
  192.         $a=$pos - $this->direction*$this->GetMinTickAbsSize();
  193.         $a2=$pos - $this->direction*$this->GetMajTickAbsSize();    
  194.         $count=1; 
  195.         $this->maj_ticks_pos[0]=$scale->Translate($start);
  196.         $this->maj_ticklabels_pos[0]=$scale->Translate($start);
  197.         if( $this->supress_first )
  198.         $this->maj_ticks_label[0]="";
  199.         else
  200.         $this->maj_ticks_label[0]=$start;    
  201.         $i=1;            
  202.         for($x=$start; $x<=$limit; $x+=$step,++$count  ) {
  203.         $xs=$scale->Translate($x);    
  204.         $this->ticks_pos[]=$xs;
  205.         $this->ticklabels_pos[]=$xs;
  206.         if( $count % 10 == 0 ) {
  207.             $img->Line($xs,$pos,$xs,$a2);
  208.             $this->maj_ticks_pos[$i]=$xs;
  209.             $this->maj_ticklabels_pos[$i]=$xs;
  210.             $this->maj_ticks_label[$i]=$nextMajor;    
  211.             ++$i;                                
  212.             $nextMajor *= 10;
  213.             $step *= 10;    
  214.             $count=1;                 
  215.         }
  216.         else
  217.             $img->Line($xs,$pos,$xs,$a);        
  218.         }        
  219.     }
  220.     return true;
  221.     }
  222. } // Class
  223. /* EOF */
  224. ?>