summaryrefslogtreecommitdiff
path: root/html/jpgraph/jpgraph_log.php
diff options
context:
space:
mode:
Diffstat (limited to 'html/jpgraph/jpgraph_log.php')
-rw-r--r--html/jpgraph/jpgraph_log.php305
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 */
+?>