2011-09-12 10:51:50 +00:00
< ? php
2016-08-15 13:16:10 -05:00
/**
* jpgraph_log . php
*
* - Description -
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
*
* @ package LibreNMS
* @ link http :// librenms . org
* @ copyright 2016 Tony Murray
* @ author Tony Murray < murraytony @ gmail . com >
*/
2011-09-12 10:51:50 +00:00
/*=======================================================================
// 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) 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 __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
2016-08-26 00:35:09 -05:00
function __construct () {
2011-09-12 10:51:50 +00:00
}
//---------------
// 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 */
?>