Code: Select all
<?php
/*
A 100% CSS, XHTML 1.1 Compliant Bar Graphing tool
-- No need to use GD, Renders quickly, Interactive charts,
-- - Very customizable.
Compatibility: PHP >= 5.0
This class is not licensed, do with it what you will
(But please give the author credit where due)
Author: d11wtq (Chris Corbyn)
Date: 2005-10-06
*/
class BarGraph
{
//Title
private $ShowTitle = false; //Show the graph title
private $TitleText = 'New Bar Graph'; //Graph title
private $TitleFontColor = '#000000'; //Graph title color
private $TitleFontWeight = 'bold'; //Graph title font weight
private $TitleFontStyle = 'normal'; //Graph title font style
private $TitleTextDecoration = 'underline'; //Graph title text decoration
private $TitleFontFamily = 'arial,sans-serif'; //Graph title font family
private $TitleFontSize = '1.0em'; //Graph title font size
private $TitleAlign = 'center'; //Title left, right or center
private $ShowTitleBackground = false; //Show graph title background
private $TitleBackgroundColor = '#CCCCFF'; //Graph title background color
//General
private $XDimension = 0; //Width
private $YDimension = 0; //Height
private $ShowBorder = false; //Show graph border
private $LBorderColor = '#CCCCCC'; //Graph left-border color
private $RBorderColor = '#CCCCCC'; //Graph right-border color
private $TBorderColor = '#CCCCCC'; //Graph top-border color
private $BBorderColor = '#CCCCCC'; //Graph bottom-border color
private $LBorderStyle = 'solid'; //Graph left-border style
private $RBorderStyle = 'solid'; //Graph right-border style
private $TBorderStyle = 'solid'; //Graph top-border style
private $BBorderStyle = 'solid'; //Graph bottom-border style
private $LBorderWidth = '1px'; //Graph left-border width
private $RBorderWidth = '1px'; //Graph right-border width
private $TBorderWidth = '1px'; //Graph top-border width
private $BBorderWidth = '1px'; //Graph bottom-border width
private $ShowBackground = false; //Show Graph background
private $BackgroundColor = '#F4F4F4'; //Graph background color
private $BackgroundImage = ''; //Graph background Image
private $BackgroundRepeat = ''; //Background repeat (x, y, no-repeat)
private $BackgroundPosition = ''; //Background position
private $BarDirection = 'v'; //Vertical or horizontal bars
//Bars
private $ShowBars = true;
private $BarBackgroundColor = '#DDDDDD'; //Bar background color
private $BarBorderColor = '#000000'; //Bar border color
private $BarBorderWidth = '1px'; //Bar border width
private $BarBorderStyle = 'solid'; //Bar border style
private $Bars = array();
//Axes
private $ShowXAxis = true; //Show X-axis
private $XAxisColor = '#BBBBBB'; //X-axis color
private $XAxisWidth = '1px'; //X-axis width
private $XAxisStyle = 'solid'; //X-axis style
private $ShowAxisLabels = true; //Show X-axis labels
private $AxisLabels = array();
private $AxisLabelFontColor = '#000000'; //X-axis font color
private $AxisLabelFontWeight = 'normal'; //X-axis font weight
private $AxisLabelFontStyle = 'normal'; //X-axis font style
private $AxisLabelTextDecoration = 'none'; //X-axis text decoration
private $AxisLabelFontFamily = 'arial,sans-serif'; //X-axis font family
private $AxisLabelFontSize = '0.8em'; //X-axis font size
private $ShowXAxisLegend = false; //Show legend on X-axis
private $XAxisLegendText = 'X Axis'; //X-axis legend text
private $XAxisLegendFontColor = '#000000'; //X-axis legend font color
private $XAxisLegendFontWeight = 'normal'; //X-axis legend font weight
private $XAxisLegendFontStyle = 'italic'; //X-axis legend font style
private $XAxisLegendTextDecoration = 'none'; //X-axis legend text decoration
private $XAxisLegendFontFamily = 'arial,sans-serif'; //X-axis legend font family
private $XAxisLegendFontSize = '0.8em'; //X-axis legend font size
private $XAxisLegendPosition = 'right';
/* ----------------- */
private $ShowYAxis = true; //Show Y-axis
private $YAxisColor = '#BBBBBB'; //See X-axis comment
private $YAxisWidth = '1px'; //See X-axis comment
private $YAxisStyle = 'solid'; //See X-axis comment
private $ShowAxisValues = false; //Show Y-axis labels
private $AxisValuesFontColor = '#000000'; //See X-axis comment
private $AxisValuesFontWeight = 'normal'; //See X-axis comment
private $AxisValuesFontStyle = 'normal'; //See X-axis comment
private $AxisValuesTextDecoration = 'none'; //See X-axis comment
private $AxisValuesFontFamily = 'arial,sans-serif'; //See X-axis comment
private $AxisValuesFontSize = '0.8em'; //See X-axis comment
private $ShowYAxisLegend = false; //See X-axis comment
private $YAxisLegendText = 'Y Axis'; //See X-axis comment
private $YAxisLegendFontColor = '#000000'; //See X-axis comment
private $YAxisLegendFontWeight = 'normal'; //See X-axis comment
private $YAxisLegendFontStyle = 'italic'; //See X-axis comment
private $YAxisLegendTextDecoration = 'none'; //See X-axis comment
private $YAxisLegendFontFamily = 'arial,sans-serif'; //See X-axis comment
private $YAxisLegendFontSize = '0.8em'; //See X-axis comment
//Stacks
private $Vals = array();
private $BarLengths = array();
//Other graph related propeties
private $XAxisSize = 0;
private $YAxisSize = 0;
private $BarWidth = 'auto';
private $FFSize;
private $IESize;
function __construct($w, $h)
{
if (is_integer($w)) $this->XDimension = $w;
else exit('Parameter 1 in object constructor must be an integer: '.gettype($w).' given');
if (is_integer($h)) $this->YDimension = $h;
else exit('Parameter 2 in object constructor must be an integer: '.gettype($h).' given');
}
//Overloading to cut down on setters - it does sanity check though
function __call($method, $args)
{
if (isset($this->{$method})
&& gettype($this->{$method}) != 'boolean'
&& gettype ($this->{$method}) != 'array') //We only want to apply to our string/numeric properties
{
if (sizeof($args) == 1) //All of our methods only set one property
{
$this->CheckError($args[0], __CLASS__.'::'.$method); //Sanity check (is string or number)
$this->{$method} = $args[0];
}
else
{
exit('Wrong parameter count given for '.__CLASS__.'::'.$method.': Expecting 1: '.count($args).' given');
}
}
else
{
exit ('Undefined method '.__CLASS__.'::'.$method.' Requested');
}
}
private function ThrowError($f, $t) //(Method, value)
{
exit('<b>Invlaid argument given</b> in '.$f.'. <b>Parameter must be a string or numeric:</b> '.gettype($t).' given');
}
private function CheckError($x, $y) //(Value, method)
{
if (!is_string($x) && !is_numeric($x)) $this->ThrowError($y, $x);
}
//Some real setters
public function ShowTitle($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowTitleBackground($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowBorder($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function BorderColor($t)
{
$this->CheckError($t, __METHOD__);
$this->LBorderColor = $t;
$this->RBorderColor = $t;
$this->TBorderColor = $t;
$this->BBorderColor = $t;
}
public function BorderWidth($t)
{
$this->CheckError($t, __METHOD__);
$this->LBorderWidth = $t;
$this->RBorderWidth = $t;
$this->TBorderWidth = $t;
$this->BBorderWidth = $t;
}
public function BorderStyle($t)
{
$this->CheckError($t, __METHOD__);
$this->LBorderStyle = $t;
$this->RBorderStyle = $t;
$this->TBorderStyle = $t;
$this->BBorderStyle = $t;
}
public function ShowBackground($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowBars($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowAxes($x=true)
{
$this->ShowXAxis($x);
$this->ShowYAxis($x);
}
public function AxisColor($t)
{
$this->CheckError($t, __METHOD__);
$this->XAxisColor = $t;
$this->YAxisColor = $t;
}
public function ShowXAxis($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowAxisLabels($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowXAxisLegend($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowYAxis($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowAxisValues($x=true)
{
$this->{__FUNCTION__} = $x;
}
public function ShowYAxisLegend($x=true)
{
$this->{__FUNCTION__} = $x;
}
//Graphing methods
/*
Add some data to the graph
*/
public function PushValues($x, $assoc=false) //Arrays to insert
{
if (is_array($x)) //Sanity check
{
foreach ($x as $k => $val)
{
if ($assoc) $this->Vals[$k] = $val;
else array_push($this->Vals, $val);
}
}
else exit('Invalid parameter 1 given in '.__METHOD__.'. Expecting array: '.gettype($x).' given');
}
//Labels for the bar points
public function PushLabels($x, $assoc=false)
{
if (is_array($x))
{
foreach ($x as $k => $val)
{
if ($assoc) $this->AxisLabels[$k] = $val;
else array_push($this->AxisLabels, $val);
}
}
else exit('Invalid argument given in '.__METHOD__.'. Expecting array: '.gettype($x).' given');
}
public function PushBarBackgroundColors($x, $a=false)
{
if (is_array($x))
{
foreach ($x as $k => $val)
{
if ($a)
{
if (!is_array($this->Bars[$k])) $this->Bars[$k] = array();
$this->Bars[$k]['BackgroundColor'] = $val;
}
else array_push($this->Bars, array('BackgroundColor' => $val));
}
}
else exit('Invalid argument given in '.__METHOD__.'. Expecting array: '.gettype($x).' given');
}
public function PushBarBorderWidths($x, $a=false)
{
if (is_array($x))
{
foreach ($x as $k => $val)
{
if ($a)
{
if (!is_array($this->Bars[$k])) $this->Bars[$k] = array();
$this->Bars[$k]['BorderWidth'] = $val;
}
else array_push($this->Bars, array('BorderWidth' => $val));
}
}
else exit('Invalid argument given in '.__METHOD__.'. Expecting array: '.gettype($x).' given');
}
public function PushBarBorderStyles($x, $a=false)
{
if (is_array($x))
{
foreach ($x as $k => $val)
{
if ($a)
{
if (!is_array($this->Bars[$k])) $this->Bars[$k] = array();
$this->Bars[$k]['BorderStyle'] = $val;
}
else array_push($this->Bars, array('BorderStyle' => $val));
}
}
else exit('Invalid argument given in '.__METHOD__.'. Expecting array: '.gettype($x).' given');
}
public function PushBarBorderColors($x, $a=false)
{
if (is_array($x))
{
foreach ($x as $k => $val)
{
if ($a)
{
if (!is_array($this->Bars[$k])) $this->Bars[$k] = array();
$this->Bars[$k]['BorderColor'] = $val;
}
else array_push($this->Bars, array('BorderStyle' => $val));
}
}
else exit('Invalid argument given in '.__METHOD__.'. Expecting array: '.gettype($x).' given');
}
//Takes a multidimensional associative array "attribute => value"
// e.g. PushBarAttributes(array('onclick' => 'alert("Foo")'), array('style' => 'opacity: 0.5', 'onmouseover' => 'foo()'), array('id' => 'some_element'))
// or .. PushBarAttributes(3 => array('onclick' => 'alert("Foo")'), 7 => array('style' => 'opacity: 0.5', 'onmouseover' => 'foo()')) .. for known indices
public function PushBarAttributes($x, $a=false)
{
if (is_array($x))
{
foreach ($x as $k => $arr)
{
if (!is_array($arr)) exit('Invalid argument given in '.__METHOD__.'. Expecting 2D array: '.gettype($k).' given for element '.$k);
if ($a)
{
if (!is_array($this->Bars[$k])) $this->Bars[$k] = array();
if (!is_array($this->Bars[$k]['Attributes'])) $this->Bars[$k]['Attributes'] = array();
foreach ($arr as $at => $val)
{
$this->Bars[$k]['Attributes'][$at] = $val;
}
}
else
{
array_push($this->Bars, array('Attributes' => $arr));
}
}
}
else exit('Invalid argument given in '.__METHOD__.'. Expecting array: '.gettype($x).' given');
}
private function GetBarWidth($d)
{
if ($d === 0)
{
//if (empty($this->XAxisLabels)) $this->XAxisLabels = $this->XVals;
if (count($this->Vals) > 0)
{
$count = count($this->Vals);
$virtBars = $count + (($count+1)/2); //Imaginary bars
$width = floor(($this->XAxisSize*0.98)/$virtBars); //The 0.98 is an IE safeguard for floating divs stying in place
return $width;
}
else return false;
}
elseif($d === 1)
{
if (count($this->Vals) > 0)
{
$count = count($this->Vals);
$virtBars = $count + (($count+1)/2); //Imaginary bars
$height = floor($this->YAxisSize*0.92/$virtBars);
return $height;
}
else return false;
}
}
public function Create($ret=false) //Return or echo the graph
{
if (empty($this->Vals)) exit('Cannot render graph without any data. Use '.__CLASS__.'::PushValues to insert data');
if (strtolower($this->BarDirection) == 'v'
|| strtolower($this->BarDirection) == 'vertical'
|| $this->BarDirection === 0)
{
if ($ret) return $this->RenderVertical();
else echo $this->RenderVertical();
}
elseif (strtolower($this->BarDirection) == 'h'
|| strtolower($this->BarDirection) == 'horizontal'
|| $this->BarDirection === 1)
{
if ($ret) return $this->RenderHorizontal();
else echo $this->RenderHorizontal();
}
else
{
exit('Cannot render graph. BarDirection must be one of "v", "vertical", 0 or "h", "horizontal", 1');
}
}
private function RenderHorizontal()
{
$Graph = '<div style="overflow: hidden; text-align: left; width: '.$this->XDimension.'px; height: '.$this->YDimension.'px;';
if ($this->ShowBorder) $Graph .= $this->GraphBorder();
$Graph .= '">'."\n"; //Finish opening outer <div> tag
if ($this->ShowTitle) $Graph .= $this->GraphTitle();
$Graph .= $this->SetAxis();
if ($this->ShowAxisLabels) $Graph .= $this->BuildYAxisLabels();
if ($this->ShowBars
&& (strtolower($this->BarWidth) == 'auto'
|| (count($this->Vals) + ((count($this->Vals)+1)/2)) * $this->BarWidth * 0.9 > $this->YAxisSize)) $this->BarWidth = $this->GetBarWidth(1);
if (!$this->BarWidth) $this->ShowBars = false; //Bars either 0 width or no data to show
if ($this->ShowBars) $Graph .= $this->BuildHBars(); //The bars
if ($this->ShowAxisValues)
{
$Graph .= '<div style="font-size: 0; height: 0; clear: both;"> </div>'."\n";
$Graph .= $this->BuildXAxisValues();
}
if ($this->ShowXAxisLegend)
{
$Graph .= '<div style="font-size: 0; height: 0; clear: both;"> </div>'."\n";
$Graph .= $this->SetXLegend(1);
}
$Graph .= '</div>'."\n"; //Close outer div
return $Graph;
}
private function RenderVertical()
{
$Graph = '<div style="overflow: hidden; text-align: left; width: '.$this->XDimension.'px; height: '.$this->YDimension.'px;';
if ($this->ShowBorder) $Graph .= $this->GraphBorder();
$Graph .= '">'."\n"; //Finish opening outer <div> tag
if ($this->ShowTitle) $Graph .= $this->GraphTitle();
$Graph .= $this->SetAxis();
if ($this->ShowAxisValues) $Graph .= $this->BuildYAxisValues();
//Container for the bars (underneath the axis)
$Graph .= '<div style="width: '.$this->GetAxisWidth().'px; height: 0; float: right; clear: both;">'."\n";
if ($this->ShowBars
&& (strtolower($this->BarWidth) == 'auto'
|| (count($this->Vals) + ((count($this->Vals)+1)/2)) * $this->BarWidth * 0.9 > $this->XAxisSize)) $this->BarWidth = $this->GetBarWidth(0);
if (!$this->BarWidth) $this->ShowBars = false; //Bars either 0 width or no data to show
if ($this->ShowBars) $Graph .= $this->BuildVBars(); //The bars
if ($this->ShowAxisLabels)
{
$Graph .= '<div style="font-size: 0; height: 0; clear: both;"> </div>'."\n";
$Graph .= $this->BuildXLabels(); //The labels
}
if ($this->ShowXAxisLegend)
{
$Graph .= '<div style="font-size: 0; height: 0; clear: both;"> </div>'."\n";
$Graph .= $this->SetXLegend();
}
$Graph .= '</div>'."\n"; //Close bar holder (underneath X axis - yes it really is!)
$Graph .= '</div>'."\n"; //Close outer div
return $Graph;
}
private function BuildYAxisLabels()
{
$FFSize = 0;
$IESize = 0;
$bars = array();
foreach ($this->Vals as $k => $v)
{
//Browser specific dimensions - we need to shift by these amounts soon
$IESize += ($this->GetBarWidth(1) + floor($this->GetBarWidth(1)/2));
$FFSize += ($this->GetBarWidth(1) + floor($this->GetBarWidth(1)/2));
$FFSize += ((isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth)*2);
$temp = &$bars[];
$temp = '<div style="height: '.$this->GetBarWidth(1).'px; border: '.
(isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth).' solid transparent'.
'; _border: '.
(isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth).' solid none'.
'; border-left-width: 0; clear: both;">'.(isset($this->AxisLabels[$k]) ? $this->AxisLabels[$k] : ' ').'</div>'."\n";
$temp .= '<div style="font-size: 0; clear: both; height: '.(floor($this->GetBarWidth(1)/2)).'px;"> </div>'."\n";
}
$bars = array_reverse($bars);
$html = '<div style="text-align: right; width: 6%; overflow: hidden; float: left;'.
' font-size: '.$this->AxisValuesFontSize.';'.
' color: '.$this->AxisValuesFontColor.';'.
' font-weight: '.$this->AxisValuesFontWeight.
' font-style: '.$this->AxisValuesFontStyle.
' text-decoration: '.$this->AxisValuesTextDecoration.';'.
' font-family: '.$this->AxisValuesFontFamily.';'.
'">'."\n";
$html .= '<div style="font-size: 0; clear: both; height: '.(floor($this->GetAxisHeight() - $FFSize)).'px; _height: '.(floor($this->GetAxisHeight() - $IESize)).'px;"> </div>'."\n";
foreach ($bars as $bar)
{
$html .= $bar;
}
$html .= '</div>'."\n";
return $html;
}
private function BuildXAxisValues()
{
$top = max($this->Vals);
if ($top >= 1 && $v < 10) $t1 = round($top, 1);
else $t1 = round($top, -1);
$t2 = $t1/2;
if ($t2 >= 1 && $v < 10) $t2 = round($t2, 1);
else $t2 = round($t2, -1);
$html = '<div style="width: '.$this->GetAxisWidth().'px; float: right; position: relative; bottom: '.$this->FFSize.'px; _bottom: '.$this->IESize.'px;'.
' font-size: '.$this->AxisValuesFontSize.';'.
' color: '.$this->AxisValuesFontColor.';'.
' font-weight: '.$this->AxisValuesFontWeight.
' font-style: '.$this->AxisValuesFontStyle.
' text-decoration: '.$this->AxisValuesTextDecoration.';'.
' font-family: '.$this->AxisValuesFontFamily.';'.
' text-align: right;">'."\n";
$bw = round($this->XAxisSize * 0.9, 1);
$html .= '<div style="float: left; width: '.$bw.'px; text-align: right;">'."\n";
$html .= '<div style="float: left; width: '.(floor($bw/2)).'px; text-align: right;">'.$t2.'</div>'."\n";
$html .= $t1."\n".'</div>'."\n";
$html .= '→ </div>'."\n";
return $html;
}
private function BuildHBars()
{
$top = max($this->Vals);
$this->FFSize = &$FFSize;
$this->IESize = &$IESize;
$FFSize = 0;
$IESize = 0;
$bars = array();
foreach ($this->Vals as $k => $v)
{
//Browser specific dimensions - we need to shift by these amounts soon
$IESize += ($this->GetBarWidth(1) + floor($this->GetBarWidth(1)/2));
$FFSize += ($this->GetBarWidth(1) + floor($this->GetBarWidth(1)/2));
$FFSize += ((isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth)*2);
if (is_numeric($this->Vals[$k]))
{
$this->BarLengths[$k] = $height = round(($this->Vals[$k]/$top) * 0.9 * $this->XAxisSize, 1); //90% of axis height
}
else $this->BarLengths[$k] = $height = 0;
$temp = &$bars[];
$temp = '<div style="font-size: 0; width: '.$this->BarLengths[$k].'px; height: '.$this->GetBarWidth(1).'px; background-color: '.
(isset($this->Bars[$k]['BackgroundColor']) ? $this->Bars[$k]['BackgroundColor'] : $this->BarBackgroundColor).
'; border: '.
(isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth).' '.
(isset($this->Bars[$k]['BorderStyle']) ? $this->Bars[$k]['BorderStyle'] : $this->BarBorderStyle).' '.
(isset($this->Bars[$k]['BorderColor']) ? $this->Bars[$k]['BorderColor'] : $this->BarBorderColor).'; border-left-width: 0; float: left;'; //Think of a cleaner way than leaving the quote open for a while? **
if (isset($this->Bars[$k]['Attributes'])) $temp .= $this->SetBarAttributes($k);
else $temp .= '"';
$temp .= '> </div>'."\n";
$temp .= '<div style="font-size: 0; clear: both; height: '.(floor($this->GetBarWidth(1)/2)).'px;"> </div>'."\n";
}
$bars = array_reverse($bars);
$html = '<div style="height: '.$FFSize.'px; _height: '.$IESize.'px; width: '.$this->GetAxisWidth().'px; position: relative; float: right; bottom: '.$FFSize.'px; _bottom: '.$IESize.'px; _left: '.$this->YAxisWidth.';">'."\n";
foreach ($bars as $bar)
{
$html .= $bar;
}
$html .= '</div>'."\n";
return $html;
}
private function BuildYAxisValues()
{
$top = max($this->Vals);
if ($top >= 1 && $v < 10) $t1 = round($top, 1);
else $t1 = round($top, -1);
$t2 = $t1/2;
if ($t2 >= 1 && $v < 10) $t2 = round($t2, 1);
else $t2 = round($t2, -1);
$bw = (int) $this->BarBorderWidth;
$html = '<div style="text-align: right; z-index: 2; overflow: visible; float: right; position: relative; right: '.($bw*2).'px; height: '.$this->GetAxisHeight().'px;'.
' font-size: '.$this->AxisValuesFontSize.';'.
' color: '.$this->AxisValuesFontColor.';'.
' font-weight: '.$this->AxisValuesFontWeight.
' font-style: '.$this->AxisValuesFontStyle.
' text-decoration: '.$this->AxisValuesTextDecoration.';'.
' font-family: '.$this->AxisValuesFontFamily.';'.
'">'."\n";
$bh = $this->GetAxisHeight() - round(0.9 * $this->YAxisSize, 1);
$html .= '<div style="height: '.$bh.'px; clear: both;"> </div>'."\n";
$html .= '<div style="height: '.(floor(($this->GetAxisHeight()-$bh)/2)).'px;">↑ '.$t1.'</div>'."\n";
$html .= '<div style="clear: both;">'.$t2.'</div>'."\n";
$html .= '</div>'."\n";
return $html;
}
private function SetXLegend($hor=false)
{
if (!$hor) $bot = ' bottom: '.max($this->BarLengths).'px;';
else $bot = ' bottom: '.$this->FFSize.'px; _bottom: '.$this->IESize.'px;';
$html = '<div style="width: '.$this->XAxisSize.'px;'.
' font-weight: '.$this->XAxisLegendFontWeight.';'.
' font-size: '.$this->XAxisLegendFontSize.';'.
' color: '.$this->XAxisLegendFontColor.';'.
' font-family: '.$this->XAxisLegendFontFamily.';'.
' font-style: '.$this->XAxisLegendFontStyle.';'.
' position: relative;'.
$bot.
' text-align: '.$this->XAxisLegendPosition.';'.
' float: right;">'.
' '.$this->XAxisLegendText.' '.
'</div>'."\n";
return $html;
}
private function BuildXLabels()
{
$d = max($this->BarLengths);
$html = '';
foreach ($this->Vals as $k => $v)
{
$text = (isset($this->AxisLabels[$k]) ? $this->AxisLabels[$k] : ' ');
$html .= '<div style="font-size; 0; width: '.(floor($this->GetBarWidth(0)/2)).'px; float: left;"> </div>';
$html .= '<div style="font-size: '.$this->AxisLabelFontSize.
'; font-family: '.$this->AxisLabelFontFamily.
'; color: '.$this->AxisLabelFontColor.
'; font-weight: '.$this->AxisLabelFontWeight.
'; font-style: '.$this->AxisLabelFontStyle.
'; text-decoration; '.$this->AxisLabelTextDecoration.
'; width: '.$this->BarWidth.'px'.
'; text-align: center; float: left; overflow: visible; position: relative; bottom: '.$d.'px; border: '.(isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth).' solid transparent; _border: '.(isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth).' solid none;">';
$html .= $text;
$html .= '</div>'."\n";
}
return $html;
}
private function BuildVBars()
{
$html = '';
$top = max($this->Vals);
//Get the bar heights
foreach ($this->Vals as $k => $v)
{
if (is_numeric($this->Vals[$k]))
{
$this->BarLengths[$k] = $height = round(($this->Vals[$k]/$top) * 0.9 * $this->YAxisSize, 1); //90% of axis height
}
else $this->BarLengths[$k] = $height = 0;
$html .= '<div style="font-size; 0; width: '.(floor($this->BarWidth/2)).'px; float: left;"> </div>'."\n";
$html .= '<div style="font-size: 0; width: '.$this->BarWidth.'px; height: '.$height.'px; background-color: '.
(isset($this->Bars[$k]['BackgroundColor']) ? $this->Bars[$k]['BackgroundColor'] : $this->BarBackgroundColor).
'; border: '.
(isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth).' '.
(isset($this->Bars[$k]['BorderStyle']) ? $this->Bars[$k]['BorderStyle'] : $this->BarBorderStyle).' '.
(isset($this->Bars[$k]['BorderColor']) ? $this->Bars[$k]['BorderColor'] : $this->BarBorderColor).'; border-bottom-width: 0; float: left; position: relative; bottom: '.($height+(isset($this->Bars[$k]['BorderWidth']) ? $this->Bars[$k]['BorderWidth'] : $this->BarBorderWidth)+$this->XAxisWidth).'px; _bottom: '.($height+$this->XAxisWidth).'px;'; //Think of a cleaner way than leaving the quote open for a while? **
if (isset($this->Bars[$k]['Attributes'])) $html .= $this->SetBarAttributes($k);
else $html .= '"';
$html .= '> </div>'."\n";
}
return $html;
}
private function SetBarAttributes($n)
{
$html = '';
$st = false;
foreach ($this->Bars[$n]['Attributes'] as $at => $val)
{
if (strtolower($at) == 'style' && !$st) //** quote was left open
{
$html = ' '.$val.';"'.$html;
$st = true;
}
else $html .= ' '.$at.'="'.$val.'"';
}
return ($st ? '' : '"').$html; //Prepend the closing style quote
}
private function SetAxis()
{
$html = '<div style="font-size: 0; width: '.$this->GetAxisWidth().'px;'.
' height: '.$this->GetAxisHeight().'px;';
if ($this->ShowBackground) $html .= $this->GraphBackground();
if ($this->ShowXAxis) $html .= " border-bottom: {$this->XAxisWidth} {$this->XAxisStyle} {$this->XAxisColor};";
if ($this->ShowYAxis) $html .= " border-left: {$this->YAxisWidth} {$this->YAxisStyle} {$this->YAxisColor};";
$html .= ' float: right;"> </div>';
return $html;
}
private function GetAxisHeight()
{
if ($this->YAxisSize === 0)
{
//This was all trial and error - there's no science here
$h = $this->YDimension * 0.97 - 16;
if ($this->ShowTitle) $h = $h * 0.97 - 16;
if ($this->ShowXAxisLegend) $h = $h * 0.97 - 16;
return $this->YAxisSize = $h;
}
else
{
return $this->YAxisSize;
}
}
private function GetAxisWidth()
{
if ($this->XAxisSize === 0)
{
return $this->XAxisSize = $this->XDimension * 0.93;
}
else
{
return $this->XAxisSize;
}
}
private function GraphBorder()
{
$css = " border-left: {$this->LBorderWidth} {$this->LBorderStyle} {$this->LBorderColor};".
" border-right: {$this->RBorderWidth} {$this->RBorderStyle} {$this->RBorderColor};".
" border-top: {$this->TBorderWidth} {$this->TBorderStyle} {$this->TBorderColor};".
" border-bottom: {$this->BBorderWidth} {$this->BBorderStyle} {$this->BBorderColor};";
return $css;
}
private function GraphBackground()
{
$css = " background-color: {$this->BackgroundColor};";
if ($this->BackgroundImage != '') $css .= " background-image: url({$this->BackgroundImage});";
if ($this->BackgroundRepeat != '') $css .= " background-repeat: {$this->BackgroundRepeat};";
if ($this->BackgroundPosition != '') $css .= " background-position: {$this->BackgroundPosition};";
return $css;
}
private function GraphTitle()
{
$html = '<div style="color: '.$this->TitleFontColor.
'; font-size: '.$this->TitleFontSize.
'; font-weight: '.$this->TitleFontWeight.
'; font-style: '.$this->TitleFontStyle.
'; font-family: '.$this->TitleFontFamily.
'; text-decoration: '.$this->TitleTextDecoration.
'; text-align: '.$this->TitleAlign.';';
if ($this->ShowTitleBackground) $html .= ' background-color: '.$this->TitleBackgroundColor.';';
$html .= ' padding: 1px; overflow: hidden; white-space: nowrap;">'."\n"; //Finish opening title <div>
$html .= $this->TitleText."\n";
$html .= '</div>'."\n";
return $html;
}
}
?>