<?php
/*=======================================================================
// File: 	JPGRAPH_LOG.PHP
// Description:	Log scale plot extension for JpGraph
// Created: 	2001-01-08
// Author:	Johan Persson (johanp@aditus.nu)
// Ver:		$Id$
//
// 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 */
?>