diff options
Diffstat (limited to 'html/jpgraph/jpgraph_log.php')
-rw-r--r-- | html/jpgraph/jpgraph_log.php | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/html/jpgraph/jpgraph_log.php b/html/jpgraph/jpgraph_log.php new file mode 100644 index 0000000..d5146ec --- /dev/null +++ b/html/jpgraph/jpgraph_log.php @@ -0,0 +1,305 @@ +<?php +/*======================================================================= + // File: JPGRAPH_LOG.PHP + // Description: Log scale plot extension for JpGraph + // Created: 2001-01-08 + // Ver: $Id: jpgraph_log.php 1106 2009-02-22 20:16:35Z ljp $ + // + // Copyright (c) Asial Corporation. All rights reserved. + //======================================================================== + */ + +DEFINE('LOGLABELS_PLAIN',0); +DEFINE('LOGLABELS_MAGNITUDE',1); + +//=================================================== +// CLASS LogScale +// Description: Logarithmic scale between world and screen +//=================================================== +class LogScale extends LinearScale { + //--------------- + // CONSTRUCTOR + + // Log scale is specified using the log of min and max + function __construct($min,$max,$type="y") { + parent::__construct($min,$max,$type); + $this->ticks = new LogTicks(); + $this->name = 'log'; + } + + //---------------- + // PUBLIC METHODS + + // Translate between world and screen + function Translate($a) { + if( !is_numeric($a) ) { + if( $a != '' && $a != '-' && $a != 'x' ) { + JpGraphError::RaiseL(11001); + // ('Your data contains non-numeric values.'); + } + return 1; + } + if( $a < 0 ) { + JpGraphError::RaiseL(11002); + //("Negative data values can not be used in a log scale."); + exit(1); + } + if( $a==0 ) $a=1; + $a=log10($a); + return ceil($this->off + ($a*1.0 - $this->scale[0]) * $this->scale_factor); + } + + // Relative translate (don't include offset) usefull when we just want + // to know the relative position (in pixels) on the axis + function RelTranslate($a) { + if( !is_numeric($a) ) { + if( $a != '' && $a != '-' && $a != 'x' ) { + JpGraphError::RaiseL(11001); + //('Your data contains non-numeric values.'); + } + return 1; + } + if( $a==0 ) { + $a=1; + } + $a=log10($a); + return round(($a*1.0 - $this->scale[0]) * $this->scale_factor); + } + + // Use bcpow() for increased precision + function GetMinVal() { + if( function_exists("bcpow") ) { + return round(bcpow(10,$this->scale[0],15),14); + } + else { + return round(pow(10,$this->scale[0]),14); + } + } + + function GetMaxVal() { + if( function_exists("bcpow") ) { + return round(bcpow(10,$this->scale[1],15),14); + } + else { + return round(pow(10,$this->scale[1]),14); + } + } + + // Logarithmic autoscaling is much simplier since we just + // set the min and max to logs of the min and max values. + // Note that for log autoscale the "maxstep" the fourth argument + // isn't used. This is just included to give the method the same + // signature as the linear counterpart. + function AutoScale($img,$min,$max,$maxsteps,$majend=true) { + if( $min==0 ) $min=1; + + if( $max <= 0 ) { + JpGraphError::RaiseL(11004); + //('Scale error for logarithmic scale. You have a problem with your data values. The max value must be greater than 0. It is mathematically impossible to have 0 in a logarithmic scale.'); + } + if( is_numeric($this->autoscale_min) ) { + $smin = round($this->autoscale_min); + $smax = ceil(log10($max)); + if( $min >= $max ) { + JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); + } + } + else { + $smin = floor(log10($min)); + if( is_numeric($this->autoscale_max) ) { + $smax = round($this->autoscale_max); + if( $smin >= $smax ) { + JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); + } + } + else + $smax = ceil(log10($max)); + } + + $this->Update($img,$smin,$smax); + } + //--------------- + // PRIVATE METHODS +} // Class + +//=================================================== +// CLASS LogTicks +// Description: +//=================================================== +class LogTicks extends Ticks{ + private $label_logtype=LOGLABELS_MAGNITUDE; + private $ticklabels_pos = array(); + //--------------- + // CONSTRUCTOR + function LogTicks() { + } + //--------------- + // PUBLIC METHODS + function IsSpecified() { + return true; + } + + function SetLabelLogType($aType) { + $this->label_logtype = $aType; + } + + // For log scale it's meaningless to speak about a major step + // We just return -1 to make the framework happy (specifically + // StrokeLabels() ) + function GetMajor() { + return -1; + } + + function SetTextLabelStart($aStart) { + JpGraphError::RaiseL(11005); + //('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.'); + } + + function SetXLabelOffset($dummy) { + // For log scales we dont care about XLabel offset + } + + // Draw ticks on image "img" using scale "scale". The axis absolute + // position in the image is specified in pos, i.e. for an x-axis + // it specifies the absolute y-coord and for Y-ticks it specified the + // absolute x-position. + function Stroke($img,$scale,$pos) { + $start = $scale->GetMinVal(); + $limit = $scale->GetMaxVal(); + $nextMajor = 10*$start; + $step = $nextMajor / 10.0; + + + $img->SetLineWeight($this->weight); + + if( $scale->type == "y" ) { + // member direction specified if the ticks should be on + // left or right side. + $a=$pos + $this->direction*$this->GetMinTickAbsSize(); + $a2=$pos + $this->direction*$this->GetMajTickAbsSize(); + + $count=1; + $this->maj_ticks_pos[0]=$scale->Translate($start); + $this->maj_ticklabels_pos[0]=$scale->Translate($start); + if( $this->supress_first ) + $this->maj_ticks_label[0]=""; + else { + if( $this->label_formfunc != '' ) { + $f = $this->label_formfunc; + $this->maj_ticks_label[0]=call_user_func($f,$start); + } + elseif( $this->label_logtype == LOGLABELS_PLAIN ) { + $this->maj_ticks_label[0]=$start; + } + else { + $this->maj_ticks_label[0]='10^'.round(log10($start)); + } + } + $i=1; + for($y=$start; $y<=$limit; $y+=$step,++$count ) { + $ys=$scale->Translate($y); + $this->ticks_pos[]=$ys; + $this->ticklabels_pos[]=$ys; + if( $count % 10 == 0 ) { + if( !$this->supress_tickmarks ) { + if( $this->majcolor!="" ) { + $img->PushColor($this->majcolor); + $img->Line($pos,$ys,$a2,$ys); + $img->PopColor(); + } + else { + $img->Line($pos,$ys,$a2,$ys); + } + } + + $this->maj_ticks_pos[$i]=$ys; + $this->maj_ticklabels_pos[$i]=$ys; + + if( $this->label_formfunc != '' ) { + $f = $this->label_formfunc; + $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor); + } + elseif( $this->label_logtype == 0 ) { + $this->maj_ticks_label[$i]=$nextMajor; + } + else { + $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor)); + } + ++$i; + $nextMajor *= 10; + $step *= 10; + $count=1; + } + else { + if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { + if( $this->mincolor!="" ) { + $img->PushColor($this->mincolor); + } + $img->Line($pos,$ys,$a,$ys); + if( $this->mincolor!="" ) { + $img->PopColor(); + } + } + } + } + } + else { + $a=$pos - $this->direction*$this->GetMinTickAbsSize(); + $a2=$pos - $this->direction*$this->GetMajTickAbsSize(); + $count=1; + $this->maj_ticks_pos[0]=$scale->Translate($start); + $this->maj_ticklabels_pos[0]=$scale->Translate($start); + if( $this->supress_first ) { + $this->maj_ticks_label[0]=""; + } + else { + if( $this->label_formfunc != '' ) { + $f = $this->label_formfunc; + $this->maj_ticks_label[0]=call_user_func($f,$start); + } + elseif( $this->label_logtype == 0 ) { + $this->maj_ticks_label[0]=$start; + } + else { + $this->maj_ticks_label[0]='10^'.round(log10($start)); + } + } + $i=1; + for($x=$start; $x<=$limit; $x+=$step,++$count ) { + $xs=$scale->Translate($x); + $this->ticks_pos[]=$xs; + $this->ticklabels_pos[]=$xs; + if( $count % 10 == 0 ) { + if( !$this->supress_tickmarks ) { + $img->Line($xs,$pos,$xs,$a2); + } + $this->maj_ticks_pos[$i]=$xs; + $this->maj_ticklabels_pos[$i]=$xs; + + if( $this->label_formfunc != '' ) { + $f = $this->label_formfunc; + $this->maj_ticks_label[$i]=call_user_func($f,$nextMajor); + } + elseif( $this->label_logtype == 0 ) { + $this->maj_ticks_label[$i]=$nextMajor; + } + else { + $this->maj_ticks_label[$i]='10^'.round(log10($nextMajor)); + } + ++$i; + $nextMajor *= 10; + $step *= 10; + $count=1; + } + else { + if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { + $img->Line($xs,$pos,$xs,$a); + } + } + } + } + return true; + } +} // Class +/* EOF */ +?> |