2019-07-17 20:08:50 +00:00
< ? php
/*=======================================================================
2019-07-17 20:31:04 +00:00
// File: JPGRAPH_BAR.PHP
// Description: Bar plot extension for JpGraph
// Created: 2001-01-08
// Ver: $Id: jpgraph_bar.php 1782 2009-08-25 09:38:45Z ljp $
//
// Copyright (c) Aditus Consulting. All rights reserved.
//========================================================================
*/
2019-07-17 20:08:50 +00:00
require_once ( 'jpgraph_plotband.php' );
// Pattern for Bars
DEFINE ( 'PATTERN_DIAG1' , 1 );
DEFINE ( 'PATTERN_DIAG2' , 2 );
DEFINE ( 'PATTERN_DIAG3' , 3 );
DEFINE ( 'PATTERN_DIAG4' , 4 );
DEFINE ( 'PATTERN_CROSS1' , 5 );
DEFINE ( 'PATTERN_CROSS2' , 6 );
DEFINE ( 'PATTERN_CROSS3' , 7 );
DEFINE ( 'PATTERN_CROSS4' , 8 );
DEFINE ( 'PATTERN_STRIPE1' , 9 );
DEFINE ( 'PATTERN_STRIPE2' , 10 );
//===================================================
// CLASS BarPlot
2019-07-17 20:31:04 +00:00
// Description: Main code to produce a bar plot
2019-07-17 20:08:50 +00:00
//===================================================
class BarPlot extends Plot {
public $fill = false , $fill_color = " lightblue " ; // Default is to fill with light blue
public $iPattern =- 1 , $iPatternDensity = 80 , $iPatternColor = 'black' ;
public $valuepos = 'top' ;
public $grad = false , $grad_style = 1 ;
public $grad_fromcolor = array ( 50 , 50 , 200 ), $grad_tocolor = array ( 255 , 255 , 255 );
public $ymin = 0 ;
protected $width = 0.4 ; // in percent of major ticks
protected $abswidth =- 1 ; // Width in absolute pixels
2019-07-17 20:31:04 +00:00
protected $ybase = 0 ; // Bars start at 0
2019-07-17 20:08:50 +00:00
protected $align = " center " ;
protected $bar_shadow = false ;
protected $bar_shadow_color = " black " ;
2019-07-17 20:31:04 +00:00
protected $bar_shadow_hsize = 3 , $bar_shadow_vsize = 3 ;
//---------------
// CONSTRUCTOR
function __construct ( $datay , $datax = false ) {
parent :: __construct ( $datay , $datax );
++ $this -> numpoints ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
//---------------
// PUBLIC METHODS
2019-07-17 20:08:50 +00:00
// Set a drop shadow for the bar (or rather an "up-right" shadow)
2019-07-17 20:31:04 +00:00
function SetShadow ( $aColor = " black " , $aHSize = 3 , $aVSize = 3 , $aShow = true ) {
$this -> bar_shadow = $aShow ;
$this -> bar_shadow_color = $aColor ;
$this -> bar_shadow_vsize = $aVSize ;
$this -> bar_shadow_hsize = $aHSize ;
// Adjust the value margin to compensate for shadow
$this -> value -> margin += $aVSize ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
// DEPRECATED use SetYBase instead
function SetYMin ( $aYStartValue ) {
2019-07-17 20:31:04 +00:00
//die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead.");
$this -> ybase = $aYStartValue ;
2019-07-17 20:08:50 +00:00
}
// Specify the base value for the bars
function SetYBase ( $aYStartValue ) {
2019-07-17 20:31:04 +00:00
$this -> ybase = $aYStartValue ;
}
// The method will take the specified pattern anre
// return a pattern index that corresponds to the original
// patterm being rotated 90 degreees. This is needed when plottin
// Horizontal bars
function RotatePattern ( $aPat , $aRotate = true ) {
$rotate = array ( 1 => 2 , 2 => 1 , 3 => 3 , 4 => 5 , 5 => 4 , 6 => 6 , 7 => 7 , 8 => 8 );
if ( $aRotate ) {
return $rotate [ $aPat ];
}
else {
return $aPat ;
}
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function Legend ( $graph ) {
2019-07-17 20:31:04 +00:00
if ( $this -> grad && $this -> legend != " " && ! $this -> fill ) {
$color = array ( $this -> grad_fromcolor , $this -> grad_tocolor );
// In order to differentiate between gradients and cooors specified as an RGB triple
$graph -> legend -> Add ( $this -> legend , $color , " " , - $this -> grad_style ,
$this -> legendcsimtarget , $this -> legendcsimalt , $this -> legendcsimwintarget );
}
elseif ( $this -> legend != " " && ( $this -> iPattern > - 1 || is_array ( $this -> iPattern )) ) {
if ( is_array ( $this -> iPattern ) ) {
$p1 = $this -> RotatePattern ( $this -> iPattern [ 0 ], $graph -> img -> a == 90 );
$p2 = $this -> iPatternColor [ 0 ];
$p3 = $this -> iPatternDensity [ 0 ];
}
else {
$p1 = $this -> RotatePattern ( $this -> iPattern , $graph -> img -> a == 90 );
$p2 = $this -> iPatternColor ;
$p3 = $this -> iPatternDensity ;
}
if ( $p3 < 90 ) $p3 += 5 ;
$color = array ( $p1 , $p2 , $p3 , $this -> fill_color );
// A kludge: Too mark that we add a pattern we use a type value of < 100
$graph -> legend -> Add ( $this -> legend , $color , " " , - 101 ,
$this -> legendcsimtarget , $this -> legendcsimalt , $this -> legendcsimwintarget );
}
elseif ( $this -> fill_color && $this -> legend != " " ) {
if ( is_array ( $this -> fill_color ) ) {
$graph -> legend -> Add ( $this -> legend , $this -> fill_color [ 0 ], " " , 0 ,
$this -> legendcsimtarget , $this -> legendcsimalt , $this -> legendcsimwintarget );
}
else {
$graph -> legend -> Add ( $this -> legend , $this -> fill_color , " " , 0 ,
$this -> legendcsimtarget , $this -> legendcsimalt , $this -> legendcsimwintarget );
}
}
2019-07-17 20:08:50 +00:00
}
// Gets called before any axis are stroked
function PreStrokeAdjust ( $graph ) {
2019-07-17 20:31:04 +00:00
parent :: PreStrokeAdjust ( $graph );
// If we are using a log Y-scale we want the base to be at the
// minimum Y-value unless the user have specifically set some other
// value than the default.
if ( substr ( $graph -> axtype , - 3 , 3 ) == " log " && $this -> ybase == 0 )
$this -> ybase = $graph -> yaxis -> scale -> GetMinVal ();
// For a "text" X-axis scale we will adjust the
// display of the bars a little bit.
if ( substr ( $graph -> axtype , 0 , 3 ) == " tex " ) {
// Position the ticks between the bars
$graph -> xaxis -> scale -> ticks -> SetXLabelOffset ( 0.5 , 0 );
// Center the bars
if ( $this -> abswidth > - 1 ) {
$graph -> SetTextScaleAbsCenterOff ( $this -> abswidth );
}
else {
if ( $this -> align == " center " )
$graph -> SetTextScaleOff ( 0.5 - $this -> width / 2 );
elseif ( $this -> align == " right " )
$graph -> SetTextScaleOff ( 1 - $this -> width );
}
}
elseif ( ( $this instanceof AccBarPlot ) || ( $this instanceof GroupBarPlot ) ) {
// We only set an absolute width for linear and int scale
// for text scale the width will be set to a fraction of
// the majstep width.
if ( $this -> abswidth == - 1 ) {
2019-07-17 20:08:50 +00:00
// Not set
2019-07-17 20:31:04 +00:00
// set width to a visuable sensible default
$this -> abswidth = $graph -> img -> plotwidth / ( 2 * $this -> numpoints );
}
}
2019-07-17 20:08:50 +00:00
}
function Min () {
2019-07-17 20:31:04 +00:00
$m = parent :: Min ();
if ( $m [ 1 ] >= $this -> ybase ) $m [ 1 ] = $this -> ybase ;
return $m ;
2019-07-17 20:08:50 +00:00
}
function Max () {
2019-07-17 20:31:04 +00:00
$m = parent :: Max ();
if ( $m [ 1 ] <= $this -> ybase ) $m [ 1 ] = $this -> ybase ;
return $m ;
}
2019-07-17 20:08:50 +00:00
// Specify width as fractions of the major stepo size
function SetWidth ( $aWidth ) {
2019-07-17 20:31:04 +00:00
if ( $aWidth > 1 ) {
// Interpret this as absolute width
$this -> abswidth = $aWidth ;
}
else {
$this -> width = $aWidth ;
}
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
// Specify width in absolute pixels. If specified this
// overrides SetWidth()
function SetAbsWidth ( $aWidth ) {
2019-07-17 20:31:04 +00:00
$this -> abswidth = $aWidth ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function SetAlign ( $aAlign ) {
2019-07-17 20:31:04 +00:00
$this -> align = $aAlign ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function SetNoFill () {
2019-07-17 20:31:04 +00:00
$this -> grad = false ;
$this -> fill_color = false ;
$this -> fill = false ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function SetFillColor ( $aColor ) {
2019-07-17 20:31:04 +00:00
// Do an extra error check if the color is specified as an RG array triple
// In that case convert it to a hex string since it will otherwise be
// interpretated as an array of colors for each individual bar.
$aColor = RGB :: tryHexConversion ( $aColor );
$this -> fill = true ;
$this -> fill_color = $aColor ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function SetFillGradient ( $aFromColor , $aToColor = null , $aStyle = null ) {
2019-07-17 20:31:04 +00:00
$this -> grad = true ;
$this -> grad_fromcolor = $aFromColor ;
$this -> grad_tocolor = $aToColor ;
$this -> grad_style = $aStyle ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function SetValuePos ( $aPos ) {
2019-07-17 20:31:04 +00:00
$this -> valuepos = $aPos ;
2019-07-17 20:08:50 +00:00
}
function SetPattern ( $aPattern , $aColor = 'black' ){
2019-07-17 20:31:04 +00:00
if ( is_array ( $aPattern ) ) {
$n = count ( $aPattern );
$this -> iPattern = array ();
$this -> iPatternDensity = array ();
if ( is_array ( $aColor ) ) {
$this -> iPatternColor = array ();
if ( count ( $aColor ) != $n ) {
JpGraphError :: RaiseL ( 2001 ); //('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()');
}
}
else {
$this -> iPatternColor = $aColor ;
}
for ( $i = 0 ; $i < $n ; ++ $i ) {
$this -> _SetPatternHelper ( $aPattern [ $i ], $this -> iPattern [ $i ], $this -> iPatternDensity [ $i ]);
if ( is_array ( $aColor ) ) {
$this -> iPatternColor [ $i ] = $aColor [ $i ];
}
}
}
else {
$this -> _SetPatternHelper ( $aPattern , $this -> iPattern , $this -> iPatternDensity );
$this -> iPatternColor = $aColor ;
}
2019-07-17 20:08:50 +00:00
}
function _SetPatternHelper ( $aPattern , & $aPatternValue , & $aDensity ){
2019-07-17 20:31:04 +00:00
switch ( $aPattern ) {
case PATTERN_DIAG1 :
$aPatternValue = 1 ;
$aDensity = 92 ;
break ;
case PATTERN_DIAG2 :
$aPatternValue = 1 ;
$aDensity = 78 ;
break ;
case PATTERN_DIAG3 :
$aPatternValue = 2 ;
$aDensity = 92 ;
break ;
case PATTERN_DIAG4 :
$aPatternValue = 2 ;
$aDensity = 78 ;
break ;
case PATTERN_CROSS1 :
$aPatternValue = 8 ;
$aDensity = 90 ;
break ;
case PATTERN_CROSS2 :
$aPatternValue = 8 ;
$aDensity = 78 ;
break ;
case PATTERN_CROSS3 :
$aPatternValue = 8 ;
$aDensity = 65 ;
break ;
case PATTERN_CROSS4 :
$aPatternValue = 7 ;
$aDensity = 90 ;
break ;
case PATTERN_STRIPE1 :
$aPatternValue = 5 ;
$aDensity = 94 ;
break ;
case PATTERN_STRIPE2 :
$aPatternValue = 5 ;
$aDensity = 85 ;
break ;
default :
JpGraphError :: RaiseL ( 2002 );
//('Unknown pattern specified in call to BarPlot::SetPattern()');
}
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
function Stroke ( $img , $xscale , $yscale ) {
$numpoints = count ( $this -> coords [ 0 ]);
if ( isset ( $this -> coords [ 1 ]) ) {
if ( count ( $this -> coords [ 1 ]) != $numpoints ) {
JpGraphError :: RaiseL ( 2003 , count ( $this -> coords [ 1 ]), $numpoints );
//"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints");
}
else {
$exist_x = true ;
}
}
else {
$exist_x = false ;
}
$numbars = count ( $this -> coords [ 0 ]);
// Use GetMinVal() instead of scale[0] directly since in the case
// of log scale we get a correct value. Log scales will have negative
// values for values < 1 while still not representing negative numbers.
if ( $yscale -> GetMinVal () >= 0 )
$zp = $yscale -> scale_abs [ 0 ];
else {
$zp = $yscale -> Translate ( 0 );
}
if ( $this -> abswidth > - 1 ) {
$abswidth = $this -> abswidth ;
}
else {
$abswidth = round ( $this -> width * $xscale -> scale_factor , 0 );
}
// Count pontetial pattern array to avoid doing the count for each iteration
if ( is_array ( $this -> iPattern ) ) {
$np = count ( $this -> iPattern );
}
$grad = null ;
for ( $i = 0 ; $i < $numbars ; ++ $i ) {
// If value is NULL, or 0 then don't draw a bar at all
if ( $this -> coords [ 0 ][ $i ] === null || $this -> coords [ 0 ][ $i ] === '' )
continue ;
if ( $exist_x ) {
$x = $this -> coords [ 1 ][ $i ];
}
else {
$x = $i ;
}
$x = $xscale -> Translate ( $x );
// Comment Note: This confuses the positioning when using acc together with
// grouped bars. Workaround for fixing #191
/*
if ( ! $xscale -> textscale ) {
if ( $this -> align == " center " )
$x -= $abswidth / 2 ;
elseif ( $this -> align == " right " )
$x -= $abswidth ;
}
*/
// Stroke fill color and fill gradient
$pts = array (
$x , $zp ,
$x , $yscale -> Translate ( $this -> coords [ 0 ][ $i ]),
$x + $abswidth , $yscale -> Translate ( $this -> coords [ 0 ][ $i ]),
$x + $abswidth , $zp );
if ( $this -> grad ) {
if ( $grad === null ) {
$grad = new Gradient ( $img );
}
if ( is_array ( $this -> grad_fromcolor ) ) {
// The first argument (grad_fromcolor) can be either an array or a single color. If it is an array
// then we have two choices. It can either a) be a single color specified as an RGB triple or it can be
// an array to specify both (from, to style) for each individual bar. The way to know the difference is
// to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB
// triple.
$ng = count ( $this -> grad_fromcolor );
if ( $ng === 3 ) {
if ( is_numeric ( $this -> grad_fromcolor [ 0 ]) && $this -> grad_fromcolor [ 0 ] > 0 && $this -> grad_fromcolor [ 0 ] < 256 ) {
// RGB Triple
$fromcolor = $this -> grad_fromcolor ;
$tocolor = $this -> grad_tocolor ;
$style = $this -> grad_style ;
}
else {
$fromcolor = $this -> grad_fromcolor [ $i % $ng ][ 0 ];
$tocolor = $this -> grad_fromcolor [ $i % $ng ][ 1 ];
$style = $this -> grad_fromcolor [ $i % $ng ][ 2 ];
}
}
else {
$fromcolor = $this -> grad_fromcolor [ $i % $ng ][ 0 ];
$tocolor = $this -> grad_fromcolor [ $i % $ng ][ 1 ];
$style = $this -> grad_fromcolor [ $i % $ng ][ 2 ];
}
$grad -> FilledRectangle ( $pts [ 2 ], $pts [ 3 ],
$pts [ 6 ], $pts [ 7 ],
$fromcolor , $tocolor , $style );
}
else {
$grad -> FilledRectangle ( $pts [ 2 ], $pts [ 3 ],
$pts [ 6 ], $pts [ 7 ],
$this -> grad_fromcolor , $this -> grad_tocolor , $this -> grad_style );
}
}
elseif ( ! empty ( $this -> fill_color ) ) {
if ( is_array ( $this -> fill_color )) {
$img -> PushColor ( $this -> fill_color [ $i % count ( $this -> fill_color )]);
} else {
$img -> PushColor ( $this -> fill_color );
}
$img -> FilledPolygon ( $pts );
$img -> PopColor ();
}
// Remember value of this bar
$val = $this -> coords [ 0 ][ $i ];
if ( ! empty ( $val ) && ! is_numeric ( $val ) ) {
JpGraphError :: RaiseL ( 2004 , $i , $val );
//'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\'');
}
// Determine the shadow
if ( $this -> bar_shadow && $val != 0 ) {
$ssh = $this -> bar_shadow_hsize ;
$ssv = $this -> bar_shadow_vsize ;
// Create points to create a "upper-right" shadow
if ( $val > 0 ) {
$sp [ 0 ] = $pts [ 6 ]; $sp [ 1 ] = $pts [ 7 ];
$sp [ 2 ] = $pts [ 4 ]; $sp [ 3 ] = $pts [ 5 ];
$sp [ 4 ] = $pts [ 2 ]; $sp [ 5 ] = $pts [ 3 ];
$sp [ 6 ] = $pts [ 2 ] + $ssh ; $sp [ 7 ] = $pts [ 3 ] - $ssv ;
$sp [ 8 ] = $pts [ 4 ] + $ssh ; $sp [ 9 ] = $pts [ 5 ] - $ssv ;
$sp [ 10 ] = $pts [ 6 ] + $ssh ; $sp [ 11 ] = $pts [ 7 ] - $ssv ;
}
elseif ( $val < 0 ) {
$sp [ 0 ] = $pts [ 4 ]; $sp [ 1 ] = $pts [ 5 ];
$sp [ 2 ] = $pts [ 6 ]; $sp [ 3 ] = $pts [ 7 ];
$sp [ 4 ] = $pts [ 0 ]; $sp [ 5 ] = $pts [ 1 ];
$sp [ 6 ] = $pts [ 0 ] + $ssh ; $sp [ 7 ] = $pts [ 1 ] - $ssv ;
$sp [ 8 ] = $pts [ 6 ] + $ssh ; $sp [ 9 ] = $pts [ 7 ] - $ssv ;
$sp [ 10 ] = $pts [ 4 ] + $ssh ; $sp [ 11 ] = $pts [ 5 ] - $ssv ;
}
if ( is_array ( $this -> bar_shadow_color ) ) {
$numcolors = count ( $this -> bar_shadow_color );
if ( $numcolors == 0 ) {
JpGraphError :: RaiseL ( 2005 ); //('You have specified an empty array for shadow colors in the bar plot.');
}
$img -> PushColor ( $this -> bar_shadow_color [ $i % $numcolors ]);
}
else {
$img -> PushColor ( $this -> bar_shadow_color );
}
$img -> FilledPolygon ( $sp );
$img -> PopColor ();
}
// Stroke the pattern
if ( is_array ( $this -> iPattern ) ) {
$f = new RectPatternFactory ();
if ( is_array ( $this -> iPatternColor ) ) {
$pcolor = $this -> iPatternColor [ $i % $np ];
}
else {
$pcolor = $this -> iPatternColor ;
}
$prect = $f -> Create ( $this -> iPattern [ $i % $np ], $pcolor , 1 );
$prect -> SetDensity ( $this -> iPatternDensity [ $i % $np ]);
if ( $val < 0 ) {
$rx = $pts [ 0 ];
$ry = $pts [ 1 ];
}
else {
$rx = $pts [ 2 ];
$ry = $pts [ 3 ];
}
$width = abs ( $pts [ 4 ] - $pts [ 0 ]) + 1 ;
$height = abs ( $pts [ 1 ] - $pts [ 3 ]) + 1 ;
$prect -> SetPos ( new Rectangle ( $rx , $ry , $width , $height ));
$prect -> Stroke ( $img );
}
else {
if ( $this -> iPattern > - 1 ) {
$f = new RectPatternFactory ();
$prect = $f -> Create ( $this -> iPattern , $this -> iPatternColor , 1 );
$prect -> SetDensity ( $this -> iPatternDensity );
if ( $val < 0 ) {
$rx = $pts [ 0 ];
$ry = $pts [ 1 ];
}
else {
$rx = $pts [ 2 ];
$ry = $pts [ 3 ];
}
$width = abs ( $pts [ 4 ] - $pts [ 0 ]) + 1 ;
$height = abs ( $pts [ 1 ] - $pts [ 3 ]) + 1 ;
$prect -> SetPos ( new Rectangle ( $rx , $ry , $width , $height ));
$prect -> Stroke ( $img );
}
}
// Stroke the outline of the bar
if ( is_array ( $this -> color ) ) {
$img -> SetColor ( $this -> color [ $i % count ( $this -> color )]);
}
else {
$img -> SetColor ( $this -> color );
}
$pts [] = $pts [ 0 ];
$pts [] = $pts [ 1 ];
if ( $this -> weight > 0 ) {
$img -> SetLineWeight ( $this -> weight );
$img -> Polygon ( $pts );
}
// Determine how to best position the values of the individual bars
$x = $pts [ 2 ] + ( $pts [ 4 ] - $pts [ 2 ]) / 2 ;
$this -> value -> SetMargin ( 5 );
if ( $this -> valuepos == 'top' ) {
$y = $pts [ 3 ];
if ( $img -> a === 90 ) {
if ( $val < 0 ) {
$this -> value -> SetAlign ( 'right' , 'center' );
}
else {
$this -> value -> SetAlign ( 'left' , 'center' );
}
}
else {
if ( $val < 0 ) {
$this -> value -> SetMargin ( - 5 );
$y = $pts [ 1 ];
$this -> value -> SetAlign ( 'center' , 'bottom' );
}
else {
$this -> value -> SetAlign ( 'center' , 'bottom' );
}
}
$this -> value -> Stroke ( $img , $val , $x , $y );
}
elseif ( $this -> valuepos == 'max' ) {
$y = $pts [ 3 ];
if ( $img -> a === 90 ) {
if ( $val < 0 )
$this -> value -> SetAlign ( 'left' , 'center' );
else
$this -> value -> SetAlign ( 'right' , 'center' );
}
else {
if ( $val < 0 ) {
$this -> value -> SetAlign ( 'center' , 'bottom' );
}
else {
$this -> value -> SetAlign ( 'center' , 'top' );
}
}
$this -> value -> SetMargin ( - 5 );
$this -> value -> Stroke ( $img , $val , $x , $y );
}
elseif ( $this -> valuepos == 'center' ) {
$y = ( $pts [ 3 ] + $pts [ 1 ]) / 2 ;
$this -> value -> SetAlign ( 'center' , 'center' );
$this -> value -> SetMargin ( 0 );
$this -> value -> Stroke ( $img , $val , $x , $y );
}
elseif ( $this -> valuepos == 'bottom' || $this -> valuepos == 'min' ) {
$y = $pts [ 1 ];
if ( $img -> a === 90 ) {
if ( $val < 0 )
$this -> value -> SetAlign ( 'right' , 'center' );
else
$this -> value -> SetAlign ( 'left' , 'center' );
}
$this -> value -> SetMargin ( 3 );
$this -> value -> Stroke ( $img , $val , $x , $y );
}
else {
JpGraphError :: RaiseL ( 2006 , $this -> valuepos );
//'Unknown position for values on bars :'.$this->valuepos);
}
// Create the client side image map
$rpts = $img -> ArrRotate ( $pts );
$csimcoord = round ( $rpts [ 0 ]) . " , " . round ( $rpts [ 1 ]);
for ( $j = 1 ; $j < 4 ; ++ $j ){
$csimcoord .= " , " . round ( $rpts [ 2 * $j ]) . " , " . round ( $rpts [ 2 * $j + 1 ]);
}
if ( ! empty ( $this -> csimtargets [ $i ]) ) {
$this -> csimareas .= '<area shape="poly" coords="' . $csimcoord . '" ' ;
$this -> csimareas .= " href= \" " . htmlentities ( $this -> csimtargets [ $i ]) . " \" " ;
if ( ! empty ( $this -> csimwintargets [ $i ]) ) {
$this -> csimareas .= " target= \" " . $this -> csimwintargets [ $i ] . " \" " ;
}
$sval = '' ;
if ( ! empty ( $this -> csimalts [ $i ]) ) {
$sval = sprintf ( $this -> csimalts [ $i ], $this -> coords [ 0 ][ $i ]);
$this -> csimareas .= " title= \" $sval\ " alt = \ " $sval\ " " ;
}
$this -> csimareas .= " /> \n " ;
}
}
return true ;
2019-07-17 20:08:50 +00:00
}
} // Class
//===================================================
// CLASS GroupBarPlot
// Description: Produce grouped bar plots
//===================================================
class GroupBarPlot extends BarPlot {
private $plots , $nbrplots = 0 ;
2019-07-17 20:31:04 +00:00
//---------------
// CONSTRUCTOR
2019-07-17 20:08:50 +00:00
function GroupBarPlot ( $plots ) {
2019-07-17 20:31:04 +00:00
$this -> width = 0.7 ;
$this -> plots = $plots ;
$this -> nbrplots = count ( $plots );
if ( $this -> nbrplots < 1 ) {
JpGraphError :: RaiseL ( 2007 ); //('Cannot create GroupBarPlot from empty plot array.');
}
for ( $i = 0 ; $i < $this -> nbrplots ; ++ $i ) {
if ( empty ( $this -> plots [ $i ]) || ! isset ( $this -> plots [ $i ]) ) {
JpGraphError :: RaiseL ( 2008 , $i ); //("Group bar plot element nbr $i is undefined or empty.");
}
}
$this -> numpoints = $plots [ 0 ] -> numpoints ;
$this -> width = 0.7 ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
//---------------
// PUBLIC METHODS
2019-07-17 20:08:50 +00:00
function Legend ( $graph ) {
2019-07-17 20:31:04 +00:00
$n = count ( $this -> plots );
for ( $i = 0 ; $i < $n ; ++ $i ) {
$c = get_class ( $this -> plots [ $i ]);
if ( ! ( $this -> plots [ $i ] instanceof BarPlot ) ) {
JpGraphError :: RaiseL ( 2009 , $c );
//('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')');
}
$this -> plots [ $i ] -> DoLegend ( $graph );
}
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function Min () {
2019-07-17 20:31:04 +00:00
list ( $xmin , $ymin ) = $this -> plots [ 0 ] -> Min ();
$n = count ( $this -> plots );
for ( $i = 0 ; $i < $n ; ++ $i ) {
list ( $xm , $ym ) = $this -> plots [ $i ] -> Min ();
$xmin = max ( $xmin , $xm );
$ymin = min ( $ymin , $ym );
}
return array ( $xmin , $ymin );
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function Max () {
2019-07-17 20:31:04 +00:00
list ( $xmax , $ymax ) = $this -> plots [ 0 ] -> Max ();
$n = count ( $this -> plots );
for ( $i = 0 ; $i < $n ; ++ $i ) {
list ( $xm , $ym ) = $this -> plots [ $i ] -> Max ();
$xmax = max ( $xmax , $xm );
$ymax = max ( $ymax , $ym );
}
return array ( $xmax , $ymax );
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
function GetCSIMareas () {
2019-07-17 20:31:04 +00:00
$n = count ( $this -> plots );
$csimareas = '' ;
for ( $i = 0 ; $i < $n ; ++ $i ) {
$csimareas .= $this -> plots [ $i ] -> csimareas ;
}
return $csimareas ;
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
2019-07-17 20:08:50 +00:00
// Stroke all the bars next to each other
2019-07-17 20:31:04 +00:00
function Stroke ( $img , $xscale , $yscale ) {
$tmp = $xscale -> off ;
$n = count ( $this -> plots );
$subwidth = $this -> width / $this -> nbrplots ;
for ( $i = 0 ; $i < $n ; ++ $i ) {
$this -> plots [ $i ] -> ymin = $this -> ybase ;
$this -> plots [ $i ] -> SetWidth ( $subwidth );
// If the client have used SetTextTickInterval() then
// major_step will be > 1 and the positioning will fail.
// If we assume it is always one the positioning will work
// fine with a text scale but this will not work with
// arbitrary linear scale
$xscale -> off = $tmp + $i * round ( $xscale -> scale_factor * $subwidth );
$this -> plots [ $i ] -> Stroke ( $img , $xscale , $yscale );
}
$xscale -> off = $tmp ;
2019-07-17 20:08:50 +00:00
}
} // Class
//===================================================
// CLASS AccBarPlot
// Description: Produce accumulated bar plots
//===================================================
class AccBarPlot extends BarPlot {
private $plots = null , $nbrplots = 0 ;
2019-07-17 20:31:04 +00:00
//---------------
// CONSTRUCTOR
function __construct ( $plots ) {
$this -> plots = $plots ;
$this -> nbrplots = count ( $plots );
if ( $this -> nbrplots < 1 ) {
JpGraphError :: RaiseL ( 2010 ); //('Cannot create AccBarPlot from empty plot array.');
}
for ( $i = 0 ; $i < $this -> nbrplots ; ++ $i ) {
if ( empty ( $this -> plots [ $i ]) || ! isset ( $this -> plots [ $i ]) ) {
JpGraphError :: RaiseL ( 2011 , $i ); //("Acc bar plot element nbr $i is undefined or empty.");
}
}
// We can only allow individual plost which do not have specified X-positions
for ( $i = 0 ; $i < $this -> nbrplots ; ++ $i ) {
if ( ! empty ( $this -> plots [ $i ] -> coords [ 1 ]) ) {
JpGraphError :: RaiseL ( 2015 );
//'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.');
}
}
// Use 0 weight by default which means that the individual bar
// weights will be used per part n the accumulated bar
$this -> SetWeight ( 0 );
$this -> numpoints = $plots [ 0 ] -> numpoints ;
$this -> value = new DisplayValue ();
2019-07-17 20:08:50 +00:00
}
2019-07-17 20:31:04 +00:00
//---------------
// PUBLIC METHODS
2019-07-17 20:08:50 +00:00
function Legend ( $graph ) {
2019-07-17 20:31:04 +00:00
$n = count ( $this -> plots );
for ( $i = $n - 1 ; $i >= 0 ; -- $i ) {
$c = get_class ( $this -> plots [ $i ]);
if ( ! ( $this -> plots [ $i ] instanceof BarPlot ) ) {
JpGraphError :: RaiseL ( 2012 , $c );
//('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')');
}
$this -> plots [ $i ] -> DoLegend ( $graph );
}
2019-07-17 20:08:50 +00:00
}
function Max () {
2019-07-17 20:31:04 +00:00
list ( $xmax ) = $this -> plots [ 0 ] -> Max ();
$nmax = 0 ;
for ( $i = 0 ; $i < count ( $this -> plots ); ++ $i ) {
$n = count ( $this -> plots [ $i ] -> coords [ 0 ]);
$nmax = max ( $nmax , $n );
list ( $x ) = $this -> plots [ $i ] -> Max ();
$xmax = max ( $xmax , $x );
}
for ( $i = 0 ; $i < $nmax ; $i ++ ) {
// Get y-value for bar $i by adding the
// individual bars from all the plots added.
// It would be wrong to just add the
// individual plots max y-value since that
// would in most cases give to large y-value.
$y = 0 ;
if ( ! isset ( $this -> plots [ 0 ] -> coords [ 0 ][ $i ]) ) {
JpGraphError :: RaiseL ( 2014 );
}
if ( $this -> plots [ 0 ] -> coords [ 0 ][ $i ] > 0 )
$y = $this -> plots [ 0 ] -> coords [ 0 ][ $i ];
for ( $j = 1 ; $j < $this -> nbrplots ; $j ++ ) {
if ( ! isset ( $this -> plots [ $j ] -> coords [ 0 ][ $i ]) ) {
JpGraphError :: RaiseL ( 2014 );
}
if ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] > 0 )
$y += $this -> plots [ $j ] -> coords [ 0 ][ $i ];
}
$ymax [ $i ] = $y ;
}
$ymax = max ( $ymax );
// Bar always start at baseline
if ( $ymax <= $this -> ybase )
$ymax = $this -> ybase ;
return array ( $xmax , $ymax );
2019-07-17 20:08:50 +00:00
}
function Min () {
2019-07-17 20:31:04 +00:00
$nmax = 0 ;
list ( $xmin , $ysetmin ) = $this -> plots [ 0 ] -> Min ();
for ( $i = 0 ; $i < count ( $this -> plots ); ++ $i ) {
$n = count ( $this -> plots [ $i ] -> coords [ 0 ]);
$nmax = max ( $nmax , $n );
list ( $x , $y ) = $this -> plots [ $i ] -> Min ();
$xmin = Min ( $xmin , $x );
$ysetmin = Min ( $y , $ysetmin );
}
for ( $i = 0 ; $i < $nmax ; $i ++ ) {
// Get y-value for bar $i by adding the
// individual bars from all the plots added.
// It would be wrong to just add the
// individual plots max y-value since that
// would in most cases give to large y-value.
$y = 0 ;
if ( $this -> plots [ 0 ] -> coords [ 0 ][ $i ] < 0 )
$y = $this -> plots [ 0 ] -> coords [ 0 ][ $i ];
for ( $j = 1 ; $j < $this -> nbrplots ; $j ++ ) {
if ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] < 0 )
$y += $this -> plots [ $j ] -> coords [ 0 ][ $i ];
}
$ymin [ $i ] = $y ;
}
$ymin = Min ( $ysetmin , Min ( $ymin ));
// Bar always start at baseline
if ( $ymin >= $this -> ybase )
$ymin = $this -> ybase ;
return array ( $xmin , $ymin );
2019-07-17 20:08:50 +00:00
}
// Stroke acc bar plot
function Stroke ( $img , $xscale , $yscale ) {
2019-07-17 20:31:04 +00:00
$pattern = NULL ;
$img -> SetLineWeight ( $this -> weight );
$grad = null ;
for ( $i = 0 ; $i < $this -> numpoints - 1 ; $i ++ ) {
$accy = 0 ;
$accy_neg = 0 ;
for ( $j = 0 ; $j < $this -> nbrplots ; ++ $j ) {
$img -> SetColor ( $this -> plots [ $j ] -> color );
if ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] >= 0 ) {
$yt = $yscale -> Translate ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] + $accy );
$accyt = $yscale -> Translate ( $accy );
$accy += $this -> plots [ $j ] -> coords [ 0 ][ $i ];
}
else {
//if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) {
$yt = $yscale -> Translate ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] + $accy_neg );
$accyt = $yscale -> Translate ( $accy_neg );
$accy_neg += $this -> plots [ $j ] -> coords [ 0 ][ $i ];
}
$xt = $xscale -> Translate ( $i );
if ( $this -> abswidth > - 1 ) {
$abswidth = $this -> abswidth ;
}
else {
$abswidth = round ( $this -> width * $xscale -> scale_factor , 0 );
}
$pts = array ( $xt , $accyt , $xt , $yt , $xt + $abswidth , $yt , $xt + $abswidth , $accyt );
if ( $this -> bar_shadow ) {
$ssh = $this -> bar_shadow_hsize ;
$ssv = $this -> bar_shadow_vsize ;
// We must also differ if we are a positive or negative bar.
if ( $j === 0 ) {
// This gets extra complicated since we have to
// see all plots to see if we are negative. It could
// for example be that all plots are 0 until the very
// last one. We therefore need to save the initial setup
// for both the negative and positive case
// In case the final bar is positive
$sp [ 0 ] = $pts [ 6 ] + 1 ; $sp [ 1 ] = $pts [ 7 ];
$sp [ 2 ] = $pts [ 6 ] + $ssh ; $sp [ 3 ] = $pts [ 7 ] - $ssv ;
// In case the final bar is negative
$nsp [ 0 ] = $pts [ 0 ]; $nsp [ 1 ] = $pts [ 1 ];
$nsp [ 2 ] = $pts [ 0 ] + $ssh ; $nsp [ 3 ] = $pts [ 1 ] - $ssv ;
$nsp [ 4 ] = $pts [ 6 ] + $ssh ; $nsp [ 5 ] = $pts [ 7 ] - $ssv ;
$nsp [ 10 ] = $pts [ 6 ] + 1 ; $nsp [ 11 ] = $pts [ 7 ];
}
if ( $j === $this -> nbrplots - 1 ) {
// If this is the last plot of the bar and
// the total value is larger than 0 then we
// add the shadow.
if ( is_array ( $this -> bar_shadow_color ) ) {
$numcolors = count ( $this -> bar_shadow_color );
if ( $numcolors == 0 ) {
JpGraphError :: RaiseL ( 2013 ); //('You have specified an empty array for shadow colors in the bar plot.');
}
$img -> PushColor ( $this -> bar_shadow_color [ $i % $numcolors ]);
}
else {
$img -> PushColor ( $this -> bar_shadow_color );
}
if ( $accy > 0 ) {
$sp [ 4 ] = $pts [ 4 ] + $ssh ; $sp [ 5 ] = $pts [ 5 ] - $ssv ;
$sp [ 6 ] = $pts [ 2 ] + $ssh ; $sp [ 7 ] = $pts [ 3 ] - $ssv ;
$sp [ 8 ] = $pts [ 2 ]; $sp [ 9 ] = $pts [ 3 ] - 1 ;
$sp [ 10 ] = $pts [ 4 ] + 1 ; $sp [ 11 ] = $pts [ 5 ];
$img -> FilledPolygon ( $sp , 4 );
}
elseif ( $accy_neg < 0 ) {
$nsp [ 6 ] = $pts [ 4 ] + $ssh ; $nsp [ 7 ] = $pts [ 5 ] - $ssv ;
$nsp [ 8 ] = $pts [ 4 ] + 1 ; $nsp [ 9 ] = $pts [ 5 ];
$img -> FilledPolygon ( $nsp , 4 );
}
$img -> PopColor ();
}
}
// If value is NULL or 0, then don't draw a bar at all
if ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] == 0 ) continue ;
if ( $this -> plots [ $j ] -> grad ) {
if ( $grad === null ) {
$grad = new Gradient ( $img );
}
if ( is_array ( $this -> plots [ $j ] -> grad_fromcolor ) ) {
// The first argument (grad_fromcolor) can be either an array or a single color. If it is an array
// then we have two choices. It can either a) be a single color specified as an RGB triple or it can be
// an array to specify both (from, to style) for each individual bar. The way to know the difference is
// to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB
// triple.
$ng = count ( $this -> plots [ $j ] -> grad_fromcolor );
if ( $ng === 3 ) {
if ( is_numeric ( $this -> plots [ $j ] -> grad_fromcolor [ 0 ]) && $this -> plots [ $j ] -> grad_fromcolor [ 0 ] > 0 &&
$this -> plots [ $j ] -> grad_fromcolor [ 0 ] < 256 ) {
// RGB Triple
$fromcolor = $this -> plots [ $j ] -> grad_fromcolor ;
$tocolor = $this -> plots [ $j ] -> grad_tocolor ;
$style = $this -> plots [ $j ] -> grad_style ;
}
else {
$fromcolor = $this -> plots [ $j ] -> grad_fromcolor [ $i % $ng ][ 0 ];
$tocolor = $this -> plots [ $j ] -> grad_fromcolor [ $i % $ng ][ 1 ];
$style = $this -> plots [ $j ] -> grad_fromcolor [ $i % $ng ][ 2 ];
}
}
else {
$fromcolor = $this -> plots [ $j ] -> grad_fromcolor [ $i % $ng ][ 0 ];
$tocolor = $this -> plots [ $j ] -> grad_fromcolor [ $i % $ng ][ 1 ];
$style = $this -> plots [ $j ] -> grad_fromcolor [ $i % $ng ][ 2 ];
}
$grad -> FilledRectangle ( $pts [ 2 ], $pts [ 3 ],
$pts [ 6 ], $pts [ 7 ],
$fromcolor , $tocolor , $style );
}
else {
$grad -> FilledRectangle ( $pts [ 2 ], $pts [ 3 ],
$pts [ 6 ], $pts [ 7 ],
$this -> plots [ $j ] -> grad_fromcolor ,
$this -> plots [ $j ] -> grad_tocolor ,
$this -> plots [ $j ] -> grad_style );
}
} else {
if ( is_array ( $this -> plots [ $j ] -> fill_color ) ) {
$numcolors = count ( $this -> plots [ $j ] -> fill_color );
$fillcolor = $this -> plots [ $j ] -> fill_color [ $i % $numcolors ];
// If the bar is specified to be non filled then the fill color is false
if ( $fillcolor !== false ) {
$img -> SetColor ( $this -> plots [ $j ] -> fill_color [ $i % $numcolors ]);
}
}
else {
$fillcolor = $this -> plots [ $j ] -> fill_color ;
if ( $fillcolor !== false ) {
$img -> SetColor ( $this -> plots [ $j ] -> fill_color );
}
}
if ( $fillcolor !== false ) {
$img -> FilledPolygon ( $pts );
}
}
$img -> SetColor ( $this -> plots [ $j ] -> color );
// Stroke the pattern
if ( $this -> plots [ $j ] -> iPattern > - 1 ) {
if ( $pattern === NULL ) {
$pattern = new RectPatternFactory ();
}
$prect = $pattern -> Create ( $this -> plots [ $j ] -> iPattern , $this -> plots [ $j ] -> iPatternColor , 1 );
$prect -> SetDensity ( $this -> plots [ $j ] -> iPatternDensity );
if ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] < 0 ) {
$rx = $pts [ 0 ];
$ry = $pts [ 1 ];
}
else {
$rx = $pts [ 2 ];
$ry = $pts [ 3 ];
}
$width = abs ( $pts [ 4 ] - $pts [ 0 ]) + 1 ;
$height = abs ( $pts [ 1 ] - $pts [ 3 ]) + 1 ;
$prect -> SetPos ( new Rectangle ( $rx , $ry , $width , $height ));
$prect -> Stroke ( $img );
}
// CSIM array
if ( $i < count ( $this -> plots [ $j ] -> csimtargets ) ) {
// Create the client side image map
$rpts = $img -> ArrRotate ( $pts );
$csimcoord = round ( $rpts [ 0 ]) . " , " . round ( $rpts [ 1 ]);
for ( $k = 1 ; $k < 4 ; ++ $k ){
$csimcoord .= " , " . round ( $rpts [ 2 * $k ]) . " , " . round ( $rpts [ 2 * $k + 1 ]);
}
if ( ! empty ( $this -> plots [ $j ] -> csimtargets [ $i ]) ) {
$this -> csimareas .= '<area shape="poly" coords="' . $csimcoord . '" ' ;
$this -> csimareas .= " href= \" " . $this -> plots [ $j ] -> csimtargets [ $i ] . " \" " ;
if ( ! empty ( $this -> plots [ $j ] -> csimwintargets [ $i ]) ) {
$this -> csimareas .= " target= \" " . $this -> plots [ $j ] -> csimwintargets [ $i ] . " \" " ;
}
$sval = '' ;
if ( ! empty ( $this -> plots [ $j ] -> csimalts [ $i ]) ) {
$sval = sprintf ( $this -> plots [ $j ] -> csimalts [ $i ], $this -> plots [ $j ] -> coords [ 0 ][ $i ]);
$this -> csimareas .= " title= \" $sval\ " " ;
}
$this -> csimareas .= " alt= \" $sval\ " /> \n " ;
}
}
$pts [] = $pts [ 0 ];
$pts [] = $pts [ 1 ];
$img -> SetLineWeight ( $this -> plots [ $j ] -> weight );
$img -> Polygon ( $pts );
$img -> SetLineWeight ( 1 );
}
// Daw potential bar around the entire accbar bar
if ( $this -> weight > 0 ) {
$y = $yscale -> Translate ( 0 );
$img -> SetColor ( $this -> color );
$img -> SetLineWeight ( $this -> weight );
$img -> Rectangle ( $pts [ 0 ], $y , $pts [ 6 ], $pts [ 5 ]);
}
// Draw labels for each acc.bar
$x = $pts [ 2 ] + ( $pts [ 4 ] - $pts [ 2 ]) / 2 ;
if ( $this -> bar_shadow ) $x += $ssh ;
// First stroke the accumulated value for the entire bar
// This value is always placed at the top/bottom of the bars
if ( $accy_neg < 0 ) {
$y = $yscale -> Translate ( $accy_neg );
$this -> value -> Stroke ( $img , $accy_neg , $x , $y );
}
else {
$y = $yscale -> Translate ( $accy );
$this -> value -> Stroke ( $img , $accy , $x , $y );
}
$accy = 0 ;
$accy_neg = 0 ;
for ( $j = 0 ; $j < $this -> nbrplots ; ++ $j ) {
// We don't print 0 values in an accumulated bar plot
if ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] == 0 ) continue ;
if ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] > 0 ) {
$yt = $yscale -> Translate ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] + $accy );
$accyt = $yscale -> Translate ( $accy );
if ( $this -> plots [ $j ] -> valuepos == 'center' ) {
$y = $accyt - ( $accyt - $yt ) / 2 ;
}
elseif ( $this -> plots [ $j ] -> valuepos == 'bottom' ) {
$y = $accyt ;
}
else { // top or max
$y = $accyt - ( $accyt - $yt );
}
$accy += $this -> plots [ $j ] -> coords [ 0 ][ $i ];
if ( $this -> plots [ $j ] -> valuepos == 'center' ) {
$this -> plots [ $j ] -> value -> SetAlign ( " center " , " center " );
$this -> plots [ $j ] -> value -> SetMargin ( 0 );
}
elseif ( $this -> plots [ $j ] -> valuepos == 'bottom' ) {
$this -> plots [ $j ] -> value -> SetAlign ( 'center' , 'bottom' );
$this -> plots [ $j ] -> value -> SetMargin ( 2 );
}
else {
$this -> plots [ $j ] -> value -> SetAlign ( 'center' , 'top' );
$this -> plots [ $j ] -> value -> SetMargin ( 1 );
}
} else {
$yt = $yscale -> Translate ( $this -> plots [ $j ] -> coords [ 0 ][ $i ] + $accy_neg );
$accyt = $yscale -> Translate ( $accy_neg );
$accy_neg += $this -> plots [ $j ] -> coords [ 0 ][ $i ];
if ( $this -> plots [ $j ] -> valuepos == 'center' ) {
$y = $accyt - ( $accyt - $yt ) / 2 ;
}
elseif ( $this -> plots [ $j ] -> valuepos == 'bottom' ) {
$y = $accyt ;
}
else {
$y = $accyt - ( $accyt - $yt );
}
if ( $this -> plots [ $j ] -> valuepos == 'center' ) {
$this -> plots [ $j ] -> value -> SetAlign ( " center " , " center " );
$this -> plots [ $j ] -> value -> SetMargin ( 0 );
}
elseif ( $this -> plots [ $j ] -> valuepos == 'bottom' ) {
$this -> plots [ $j ] -> value -> SetAlign ( 'center' , $j == 0 ? 'bottom' : 'top' );
$this -> plots [ $j ] -> value -> SetMargin ( - 2 );
}
else {
$this -> plots [ $j ] -> value -> SetAlign ( 'center' , 'bottom' );
$this -> plots [ $j ] -> value -> SetMargin ( - 1 );
}
}
$this -> plots [ $j ] -> value -> Stroke ( $img , $this -> plots [ $j ] -> coords [ 0 ][ $i ], $x , $y );
}
}
return true ;
2019-07-17 20:08:50 +00:00
}
} // Class
/* EOF */
?>