mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-12-21 08:28:44 +00:00
267 lines
8 KiB
PHP
267 lines
8 KiB
PHP
|
<?php
|
||
|
/*=======================================================================
|
||
|
// File: JPGRAPH_LOG.PHP
|
||
|
// Description: Log scale plot extension for JpGraph
|
||
|
// Created: 2001-01-08
|
||
|
// Author: Johan Persson (johanp@aditus.nu)
|
||
|
// Ver: $Id: jpgraph_log.php,v 1.1 2006/07/07 13:37:14 powles Exp $
|
||
|
//
|
||
|
// Copyright (c) Aditus Consulting. 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 LogScale($min,$max,$type="y") {
|
||
|
$this->LinearScale($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,$dummy) {
|
||
|
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.');
|
||
|
}
|
||
|
$smin = floor(log10($min));
|
||
|
$smax = ceil(log10($max));
|
||
|
$this->Update($img,$smin,$smax);
|
||
|
}
|
||
|
//---------------
|
||
|
// PRIVATE METHODS
|
||
|
} // Class
|
||
|
|
||
|
//===================================================
|
||
|
// CLASS LogTicks
|
||
|
// Description:
|
||
|
//===================================================
|
||
|
class LogTicks extends Ticks{
|
||
|
var $label_logtype=LOGLABELS_MAGNITUDE;
|
||
|
//---------------
|
||
|
// 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 */
|
||
|
?>
|