added the webui to the tarball

This commit is contained in:
SJ
2012-02-08 23:14:28 +01:00
parent 79cdeed1b6
commit 1211e9a39c
272 changed files with 26456 additions and 11 deletions

View File

@ -0,0 +1,130 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Automatic axis boundaries and ticks calibration
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class Axis {
private $min;
private $max;
private $guide;
private $delta;
private $magnitude;
private $displayMin;
private $displayMax;
private $tics;
/**
* Creates a new axis formatter.
*
* @param integer minimum value on the axis
* @param integer maximum value on the axis
*/
public function Axis($min, $max) {
$this->min = $min;
$this->max = $max;
$this->guide = 10;
}
/**
* Computes value between two ticks.
*/
public function quantizeTics() {
// Approximate number of decades, in [1..10[
$norm = $this->delta / $this->magnitude;
// Approximate number of tics per decade
$posns = $this->guide / $norm;
if ($posns > 20) {
$tics = 0.05; // e.g. 0, .05, .10, ...
} else if ($posns > 10) {
$tics = 0.2; // e.g. 0, .1, .2, ...
} else if ($posns > 5) {
$tics = 0.4; // e.g. 0, 0.2, 0.4, ...
} else if ($posns > 3) {
$tics = 0.5; // e.g. 0, 0.5, 1, ...
} else if ($posns > 2) {
$tics = 1; // e.g. 0, 1, 2, ...
} else if ($posns > 0.25) {
$tics = 2; // e.g. 0, 2, 4, 6
} else {
$tics = ceil($norm);
}
$this->tics = $tics * $this->magnitude;
}
/**
* Computes automatic boundaries on the axis
*/
public function computeBoundaries() {
// Range
$this->delta = abs($this->max - $this->min);
// Check for null distribution
if ($this->delta == 0)
$this->delta = 1;
// Order of magnitude of range
$this->magnitude = pow(10, floor(log10($this->delta)));
$this->quantizeTics();
$this->displayMin = floor($this->min / $this->tics) * $this->tics;
$this->displayMax = ceil($this->max / $this->tics) * $this->tics;
$this->displayDelta = $this->displayMax - $this->displayMin;
// Check for null distribution
if ($this->displayDelta == 0) {
$this->displayDelta = 1;
}
}
/**
* Get the lower boundary on the axis3
*
* @return integer lower boundary on the axis
*/
public function getLowerBoundary() {
return $this->displayMin;
}
/**
* Get the upper boundary on the axis3
*
* @return integer upper boundary on the axis
*/
public function getUpperBoundary() {
return $this->displayMax;
}
/**
* Get the value between two ticks3
*
* @return integer value between two ticks
*/
public function getTics() {
return $this->tics;
}
}
?>

View File

@ -0,0 +1,156 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Object representing the bounds of a dataset (its minimal and maximal values) on its vertical axis.
* The bounds are automatically calculated from a XYDataSet or XYSeriesDataSet.
* Default (calculated) bounds can be overriden using the setLowerBound() and setUpperBound() methods.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
* Created on 25 july 2007
*/
class Bound {
/**
* Manually set lower bound, overrides the value calculated by computeBound().
*/
private $lowerBound = null;
/**
* Manually set upper bound, overrides the value calculated by computeBound().
*/
private $upperBound = null;
/**
* Computed min bound.
*/
private $yMinValue = null;
/**
* Computed max bound.
*/
private $yMaxValue = null;
/**
* Compute the boundaries on the axis.
*
* @param dataSet The data set
*/
public function computeBound($dataSet) {
// Check if the data set is empty
$dataSetEmpty = true;
$serieList = null;
if ($dataSet instanceof XYDataSet) {
$pointList = $dataSet->getPointList();
$dataSetEmpty = count($pointList) == 0;
if (!$dataSetEmpty) {
// Process it as a serie
$serieList = array();
array_push($serieList, $dataSet);
}
} else if ($dataSet instanceof XYSeriesDataSet) {
$serieList = $dataSet->getSerieList();
if (count($serieList) > 0) {
$serie = current($serieList);
$dataSetEmpty = count($serie) == 0;
}
} else {
die("Error: unknown dataset type");
}
// If the dataset is empty, default some bounds
$yMin = 0;
$yMax = 1;
if (!$dataSetEmpty) {
// Compute lower and upper bound on the value axis
unset($yMin);
unset($yMax);
foreach ($serieList as $serie) {
foreach ($serie->getPointList() as $point) {
$y = $point->getY();
if (!isset($yMin)) {
$yMin = $y;
$yMax = $y;
} else {
if ($y < $yMin) {
$yMin = $y;
}
if ($y > $yMax) {
$yMax = $y;
}
}
}
}
}
// If user specified bounds and they are actually greater than computer bounds, override computed bounds
if (isset($this->lowerBound) && $this->lowerBound < $yMin) {
$this->yMinValue = $this->lowerBound;
} else {
$this->yMinValue = $yMin;
}
if (isset($this->upperBound) && $this->upperBound > $yMax) {
$this->yMaxValue = $this->upperBound;
} else {
$this->yMaxValue = $yMax;
}
}
/**
* Getter of yMinValue.
*
* @return min bound
*/
public function getYMinValue() {
return $this->yMinValue;
}
/**
* Getter of yMaxValue.
*
* @return max bound
*/
public function getYMaxValue() {
return $this->yMaxValue;
}
/**
* Set manually the lower boundary value (overrides the automatic formatting).
* Typical usage is to set the bars starting from zero.
*
* @param double lower boundary value
*/
public function setLowerBound($lowerBound) {
$this->lowerBound = $lowerBound;
}
/**
* Set manually the upper boundary value (overrides the automatic formatting).
*
* @param double upper boundary value
*/
public function setUpperBound($upperBound) {
$this->upperBound = $upperBound;
}
}
?>

View File

@ -0,0 +1,112 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Caption.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
* Created on 30 july 2007
*/
class Caption {
protected $labelBoxWidth;
protected $labelBoxHeight;
// Plot
protected $plot;
// Label list
protected $labelList;
// Color set
protected $colorSet;
/**
* Constructor of Caption
*/
public function Caption() {
$this->labelBoxWidth = 15;
$this->labelBoxHeight = 15;
}
/**
* Render the caption.
*/
public function render() {
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
$primitive = $this->plot->getPrimitive();
// Get the caption area
$captionArea = $this->plot->getCaptionArea();
// Get the pie color set
$colorSet = $this->colorSet;
$colorSet->reset();
$i = 0;
foreach ($this->labelList as $label) {
// Get the next color
$color = $colorSet->currentColor();
$colorSet->next();
$boxX1 = $captionArea->x1;
$boxX2 = $boxX1 + $this->labelBoxWidth;
$boxY1 = $captionArea->y1 + 5 + $i * ($this->labelBoxHeight + 5);
$boxY2 = $boxY1 + $this->labelBoxHeight;
$primitive->outlinedBox($boxX1, $boxY1, $boxX2, $boxY2, $palette->axisColor[0], $palette->axisColor[1]);
imagefilledrectangle($img, $boxX1 + 2, $boxY1 + 2, $boxX2 - 2, $boxY2 - 2, $color->getColor($img));
$text->printText($img, $boxX2 + 5, $boxY1 + $this->labelBoxHeight / 2, $this->plot->getTextColor(), $label, $text->fontCondensed, $text->VERTICAL_CENTER_ALIGN);
$i++;
}
}
/**
* Sets the plot.
*
* @param Plot The plot
*/
public function setPlot($plot) {
$this->plot = $plot;
}
/**
* Sets the label list.
*
* @param Array label list
*/
public function setLabelList($labelList) {
$this->labelList = $labelList;
}
/**
* Sets the color set.
*
* @param Array Color set
*/
public function setColorSet($colorSet) {
$this->colorSet = $colorSet;
}
}
?>

View File

@ -0,0 +1,183 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Base abstract class for rendering both horizontal and vertical bar charts.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
abstract class BarChart extends Chart {
protected $bound;
protected $axis;
protected $hasSeveralSerie;
/**
* Creates a new bar chart.
*
* @param integer width of the image
* @param integer height of the image
*/
protected function BarChart($width, $height) {
parent::Chart($width, $height);
// Initialize the bounds
$this->bound = new Bound();
$this->bound->setLowerBound(0);
}
/**
* Compute the axis.
*/
protected function computeAxis() {
$this->axis = new Axis($this->bound->getYMinValue(), $this->bound->getYMaxValue());
$this->axis->computeBoundaries();
}
/**
* Create the image.
*/
protected function createImage() {
parent::createImage();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
$primitive = $this->plot->getPrimitive();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
// Aqua-like background
for ($i = $graphArea->y1; $i < $graphArea->y2; $i++) {
$color = $palette->backgroundColor[($i + 3) % 4];
$primitive->line($graphArea->x1, $i, $graphArea->x2, $i, $color);
}
// Axis
imagerectangle($img, $graphArea->x1 - 1, $graphArea->y1, $graphArea->x1, $graphArea->y2, $palette->axisColor[0]->getColor($img));
imagerectangle($img, $graphArea->x1 - 1, $graphArea->y2, $graphArea->x2, $graphArea->y2 + 1, $palette->axisColor[0]->getColor($img));
}
/**
* Returns true if the data set has some data.
* @param minNumberOfPoint Minimum number of points (1 for bars, 2 for lines).
*
* @return true if data set empty
*/
protected function isEmptyDataSet($minNumberOfPoint) {
if ($this->dataSet instanceof XYDataSet) {
$pointList = $this->dataSet->getPointList();
$pointCount = count($pointList);
return $pointCount < $minNumberOfPoint;
} else if ($this->dataSet instanceof XYSeriesDataSet) {
$serieList = $this->dataSet->getSerieList();
reset($serieList);
if (count($serieList) > 0) {
$serie = current($serieList);
$pointList = $serie->getPointList();
$pointCount = count($pointList);
return $pointCount < $minNumberOfPoint;
}
} else {
die("Error: unknown dataset type");
}
}
/**
* Checks the data model before rendering the graph.
*/
protected function checkDataModel() {
// Check if a dataset was defined
if (!$this->dataSet) {
die("Error: No dataset defined.");
}
// Bar charts accept both XYDataSet and XYSeriesDataSet
if ($this->dataSet instanceof XYDataSet) {
// The dataset contains only one serie
$this->hasSeveralSerie = false;
} else if ($this->dataSet instanceof XYSeriesDataSet) {
// Check if each series has the same number of points
unset($lastPointCount);
$serieList = $this->dataSet->getSerieList();
for ($i = 0; $i < count($serieList); $i++) {
$serie = $serieList[$i];
$pointCount = count($serie->getPointList());
if (isset($lastPointCount) && $pointCount != $lastPointCount) {
die("Error: serie <" . $i . "> doesn't have the same number of points as last serie (last one: <" . $lastPointCount. ">, this one: <" . $pointCount. ">).");
}
$lastPointCount = $pointCount;
}
// The dataset contains several series
$this->hasSeveralSerie = true;
} else {
die("Error: Bar chart accept only XYDataSet and XYSeriesDataSet");
}
}
/**
* Return the data as a series list (for consistency).
*
* @return List of series
*/
protected function getDataAsSerieList() {
// Get the data as a series list
$serieList = null;
if ($this->dataSet instanceof XYSeriesDataSet) {
$serieList = $this->dataSet->getSerieList();
} else if ($this->dataSet instanceof XYDataSet) {
$serieList = array();
array_push($serieList, $this->dataSet);
}
return $serieList;
}
/**
* Return the first serie of the list, or the dataSet itself if there is no serie.
*
* @return XYDataSet
*/
protected function getFirstSerieOfList() {
$pointList = null;
if ($this->dataSet instanceof XYSeriesDataSet) {
// For a series dataset, print the legend from the first serie
$serieList = $this->dataSet->getSerieList();
reset($serieList);
$serie = current($serieList);
$pointList = $serie->getPointList();
} else if ($this->dataSet instanceof XYDataSet) {
$pointList = $this->dataSet->getPointList();
}
return $pointList;
}
/**
* Retourns the bound.
*
* @return bound Bound
*/
public function getBound() {
return $this->bound;
}
}
?>

View File

@ -0,0 +1,102 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/*! \mainpage Libchart
*
* This is the reference API, automatically compiled by <a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a>.
* You can find here information that is not covered by the <a href="../samplecode/">tutorial</a>.
*
*/
/**
* Base chart class.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
abstract class Chart {
/**
* The data set.
*/
protected $dataSet;
/**
* Plot (holds graphical attributes).
*/
protected $plot;
/**
* Abstract constructor of Chart.
*
* @param integer width of the image
* @param integer height of the image
*/
protected function Chart($width, $height) {
// Creates the plot
$this->plot = new Plot($width, $height);
$this->plot->setTitle("Untitled chart");
//$this->plot->setLogoFileName(dirname(__FILE__) . "/../../../images/PoweredBy.png");
}
/**
* Checks the data model before rendering the graph.
*/
protected function checkDataModel() {
// Check if a dataset was defined
if (!$this->dataSet) {
die("Error: No dataset defined.");
}
// Maybe no points are defined, but that's ok. This will yield and empty graph with default boundaries.
}
/**
* Create the image.
*/
protected function createImage() {
$this->plot->createImage();
}
/**
* Sets the data set.
*
* @param dataSet The data set
*/
public function setDataSet($dataSet) {
$this->dataSet = $dataSet;
}
/**
* Return the plot.
*
* @return plot
*/
public function getPlot() {
return $this->plot;
}
/**
* Sets the title.
*
* @param string New title
*/
public function setTitle($title) {
$this->plot->setTitle($title);
}
}
?>

View File

@ -0,0 +1,217 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Horizontal bar chart
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class HorizontalBarChart extends BarChart {
/**
* Ratio of empty space beside the bars.
*/
private $emptyToFullRatio;
/**
* Creates a new horizontal bar chart.
*
* @param integer width of the image
* @param integer height of the image
*/
public function HorizontalBarChart($width = 600, $height = 250) {
parent::BarChart($width, $height);
$this->emptyToFullRatio = 1 / 5;
$this->plot->setGraphPadding(new Padding(5, 30, 30, 50));
}
/**
* Computes the layout.
*/
protected function computeLayout() {
if ($this->hasSeveralSerie) {
$this->plot->setHasCaption(true);
}
$this->plot->computeLayout();
}
/**
* Print the axis.
*/
protected function printAxis() {
$minValue = $this->axis->getLowerBoundary();
$maxValue = $this->axis->getUpperBoundary();
$stepValue = $this->axis->getTics();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
// Horizontal axis
for ($value = $minValue; $value <= $maxValue; $value += $stepValue) {
$x = $graphArea->x1 + ($value - $minValue) * ($graphArea->x2 - $graphArea->x1) / ($this->axis->displayDelta);
imagerectangle($img, $x - 1, $graphArea->y2 + 2, $x, $graphArea->y2 + 3, $palette->axisColor[0]->getColor($img));
imagerectangle($img, $x - 1, $graphArea->y2, $x, $graphArea->y2 + 1, $palette->axisColor[1]->getColor($img));
$text->printText($img, $x, $graphArea->y2 + 5, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_CENTER_ALIGN);
}
// Get first serie of a list
$pointList = $this->getFirstSerieOfList();
// Vertical Axis
$pointCount = count($pointList);
reset($pointList);
$rowHeight = ($graphArea->y2 - $graphArea->y1) / $pointCount;
reset($pointList);
for ($i = 0; $i <= $pointCount; $i++) {
$y = $graphArea->y2 - $i * $rowHeight;
imagerectangle($img, $graphArea->x1 - 3, $y, $graphArea->x1 - 2, $y + 1, $palette->axisColor[0]->getColor($img));
imagerectangle($img, $graphArea->x1 - 1, $y, $graphArea->x1, $y + 1, $palette->axisColor[1]->getColor($img));
if ($i < $pointCount) {
$point = current($pointList);
next($pointList);
$label = $point->getX();
$text->printText($img, $graphArea->x1 - 5, $y - $rowHeight / 2, $this->plot->getTextColor(), $label, $text->fontCondensed, $text->HORIZONTAL_RIGHT_ALIGN | $text->VERTICAL_CENTER_ALIGN);
}
}
}
/**
* Print the bars.
*/
protected function printBar() {
// Get the data as a list of series for consistency
$serieList = $this->getDataAsSerieList();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
$minValue = $this->axis->getLowerBoundary();
$maxValue = $this->axis->getUpperBoundary();
$stepValue = $this->axis->getTics();
$barColorSet = $palette->barColorSet;
$barColorSet->reset();
$serieCount = count($serieList);
for ($j = 0; $j < $serieCount; $j++) {
$serie = $serieList[$j];
$pointList = $serie->getPointList();
$pointCount = count($pointList);
reset($pointList);
// Get the next color
$color = $barColorSet->currentColor();
$shadowColor = $barColorSet->currentShadowColor();
$barColorSet->next();
$rowHeight = ($graphArea->y2 - $graphArea->y1) / $pointCount;
for ($i = 0; $i < $pointCount; $i++) {
$y = $graphArea->y2 - $i * $rowHeight;
$point = current($pointList);
next($pointList);
$value = $point->getY();
$xmax = $graphArea->x1 + ($value - $minValue) * ($graphArea->x2 - $graphArea->x1) / ($this->axis->displayDelta);
// Bar dimensions
$yWithMargin = $y - $rowHeight * $this->emptyToFullRatio;
$rowWidthWithMargin = $rowHeight * (1 - $this->emptyToFullRatio * 2);
$barWidth = $rowWidthWithMargin / $serieCount;
$barOffset = $barWidth * $j;
$y1 = $yWithMargin - $barWidth - $barOffset;
$y2 = $yWithMargin - $barOffset - 1;
// Text
$text->printText($img, $xmax + 5, $y2 - $barWidth / 2, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->VERTICAL_CENTER_ALIGN);
imagefilledrectangle($img, $graphArea->x1 + 1, $y1, $xmax, $y2, $shadowColor->getColor($img));
// Prevents drawing a small box when x = 0
if ($graphArea->x1 != $xmax) {
imagefilledrectangle($img, $graphArea->x1 + 2, $y1 + 1, $xmax - 4, $y2, $color->getColor($img));
}
}
}
}
/**
* Renders the caption.
*/
protected function printCaption() {
// Get the list of labels
$labelList = $this->dataSet->getTitleList();
// Create the caption
$caption = new Caption();
$caption->setPlot($this->plot);
$caption->setLabelList($labelList);
$palette = $this->plot->getPalette();
$barColorSet = $palette->barColorSet;
$caption->setColorSet($barColorSet);
// Render the caption
$caption->render();
}
/**
* Render the chart image.
*
* @param string name of the file to render the image to (optional)
*/
public function render($fileName = null) {
// Check the data model
$this->checkDataModel();
$this->bound->computeBound($this->dataSet);
$this->computeAxis();
$this->computeLayout();
$this->createImage();
$this->plot->printLogo();
$this->plot->printTitle();
if (!$this->isEmptyDataSet(1)) {
$this->printAxis();
$this->printBar();
if ($this->hasSeveralSerie) {
$this->printCaption();
}
}
$this->plot->render($fileName);
}
}
?>

View File

@ -0,0 +1,200 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Line chart.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class LineChart extends BarChart {
/**
* Creates a new line chart.
* Line charts allow for XYDataSet and XYSeriesDataSet in order to plot several lines.
*
* @param integer width of the image
* @param integer height of the image
*/
public function LineChart($width = 600, $height = 250) {
parent::BarChart($width, $height);
$this->plot->setGraphPadding(new Padding(5, 30, 50, 50));
}
/**
* Computes the layout.
*/
protected function computeLayout() {
if ($this->hasSeveralSerie) {
$this->plot->setHasCaption(true);
}
$this->plot->computeLayout();
}
/**
* Print the axis.
*/
protected function printAxis() {
$minValue = $this->axis->getLowerBoundary();
$maxValue = $this->axis->getUpperBoundary();
$stepValue = $this->axis->getTics();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
// Vertical axis
for ($value = $minValue; $value <= $maxValue; $value += $stepValue) {
$y = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta);
imagerectangle($img, $graphArea->x1 - 3, $y, $graphArea->x1 - 2, $y + 1, $palette->axisColor[0]->getColor($img));
imagerectangle($img, $graphArea->x1 - 1, $y, $graphArea->x1, $y + 1, $palette->axisColor[1]->getColor($img));
$text->printText($img, $graphArea->x1 - 5, $y, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_RIGHT_ALIGN | $text->VERTICAL_CENTER_ALIGN);
}
// Get first serie of a list
$pointList = $this->getFirstSerieOfList();
// Horizontal Axis
$pointCount = count($pointList);
reset($pointList);
$columnWidth = ($graphArea->x2 - $graphArea->x1) / ($pointCount - 1);
for ($i = 0; $i < $pointCount; $i++) {
$x = $graphArea->x1 + $i * $columnWidth;
imagerectangle($img, $x - 1, $graphArea->y2 + 2, $x, $graphArea->y2 + 3, $palette->axisColor[0]->getColor($img));
imagerectangle($img, $x - 1, $graphArea->y2, $x, $graphArea->y2 + 1, $palette->axisColor[1]->getColor($img));
$point = current($pointList);
next($pointList);
$label = $point->getX();
$text->printDiagonal($img, $x - 5, $graphArea->y2 + 10, $this->plot->getTextColor(), $label);
}
}
/**
* Print the lines.
*/
protected function printLine() {
$minValue = $this->axis->getLowerBoundary();
$maxValue = $this->axis->getUpperBoundary();
// Get the data as a list of series for consistency
$serieList = $this->getDataAsSerieList();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
$primitive = $this->plot->getPrimitive();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
$lineColorSet = $palette->lineColorSet;
$lineColorSet->reset();
for ($j = 0; $j < count($serieList); $j++) {
$serie = $serieList[$j];
$pointList = $serie->getPointList();
$pointCount = count($pointList);
reset($pointList);
$columnWidth = ($graphArea->x2 - $graphArea->x1) / ($pointCount - 1);
$lineColor = $lineColorSet->currentColor();
$lineColorShadow = $lineColorSet->currentShadowColor();
$lineColorSet->next();
$x1 = null;
$y1 = null;
for ($i = 0; $i < $pointCount; $i++) {
$x2 = $graphArea->x1 + $i * $columnWidth;
$point = current($pointList);
next($pointList);
$value = $point->getY();
$y2 = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta);
// Draw line
if ($x1) {
$primitive->line($x1, $y1, $x2, $y2, $lineColor, 4);
$primitive->line($x1, $y1 - 1, $x2, $y2 - 1, $lineColorShadow, 2);
}
$x1 = $x2;
$y1 = $y2;
}
}
}
/**
* Renders the caption.
*/
protected function printCaption() {
// Get the list of labels
$labelList = $this->dataSet->getTitleList();
// Create the caption
$caption = new Caption();
$caption->setPlot($this->plot);
$caption->setLabelList($labelList);
$palette = $this->plot->getPalette();
$lineColorSet = $palette->lineColorSet;
$caption->setColorSet($lineColorSet);
// Render the caption
$caption->render();
}
/**
* Render the chart image.
*
* @param string name of the file to render the image to (optional)
*/
public function render($fileName = null) {
// Check the data model
$this->checkDataModel();
$this->bound->computeBound($this->dataSet);
$this->computeAxis();
$this->computeLayout();
$this->createImage();
$this->plot->printLogo();
$this->plot->printTitle();
if (!$this->isEmptyDataSet(2)) {
$this->printAxis();
$this->printLine();
if ($this->hasSeveralSerie) {
$this->printCaption();
}
}
$this->plot->render($fileName);
}
}
?>

View File

@ -0,0 +1,261 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Pie chart.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class PieChart extends Chart {
protected $pieCenterX;
protected $pieCenterY;
/**
* Constructor of a pie chart.
*
* @param integer width of the image
* @param integer height of the image
*/
public function PieChart($width = 600, $height = 250) {
parent::Chart($width, $height);
$this->plot->setGraphPadding(new Padding(15, 10, 30, 30));
}
/**
* Computes the layout.
*/
protected function computeLayout() {
$this->plot->setHasCaption(true);
$this->plot->computeLayout();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
// Compute the coordinates of the pie
$this->pieCenterX = $graphArea->x1 + ($graphArea->x2 - $graphArea->x1) / 2;
$this->pieCenterY = $graphArea->y1 + ($graphArea->y2 - $graphArea->y1) / 2;
$this->pieWidth = round(($graphArea->x2 - $graphArea->x1) * 4 / 5);
$this->pieHeight = round(($graphArea->y2 - $graphArea->y1) * 3.7 / 5);
$this->pieDepth = round($this->pieWidth * 0.05);
}
/**
* Compare two sampling point values, order from biggest to lowest value.
*
* @param double first value
* @param double second value
* @return integer result of the comparison
*/
protected function sortPie($v1, $v2) {
return $v1[0] == $v2[0] ? 0 :
$v1[0] > $v2[0] ? -1 :
1;
}
/**
* Compute pie values in percentage and sort them.
*/
protected function computePercent() {
$this->total = 0;
$this->percent = array();
$pointList = $this->dataSet->getPointList();
foreach ($pointList as $point) {
$this->total += $point->getY();
}
foreach ($pointList as $point) {
$percent = $this->total == 0 ? 0 : 100 * $point->getY() / $this->total;
array_push($this->percent, array($percent, $point));
}
usort($this->percent, array("PieChart", "sortPie"));
}
/**
* Creates the pie chart image.
*/
protected function createImage() {
parent::createImage();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$primitive = $this->plot->getPrimitive();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
// Legend box
$primitive->outlinedBox($graphArea->x1, $graphArea->y1, $graphArea->x2, $graphArea->y2, $palette->axisColor[0], $palette->axisColor[1]);
// Aqua-like background
for ($i = $graphArea->y1 + 2; $i < $graphArea->y2 - 1; $i++) {
$color = $palette->backgroundColor[($i + 3) % 4];
$primitive->line($graphArea->x1 + 2, $i, $graphArea->x2 - 2, $i, $color);
}
}
/**
* Renders the caption.
*/
protected function printCaption() {
// Create a list of labels
$labelList = array();
foreach($this->percent as $percent) {
list($percent, $point) = $percent;
$label = $point->getX();
array_push($labelList, $label);
}
// Create the caption
$caption = new Caption();
$caption->setPlot($this->plot);
$caption->setLabelList($labelList);
$palette = $this->plot->getPalette();
$pieColorSet = $palette->pieColorSet;
$caption->setColorSet($pieColorSet);
// Render the caption
$caption->render();
}
/**
* Draw a 2D disc.
*
* @param integer Center coordinate (y)
* @param array Colors for each portion
* @param bitfield Drawing mode
*/
protected function drawDisc($cy, $colorArray, $mode) {
// Get graphical obects
$img = $this->plot->getImg();
$i = 0;
$oldAngle = 0;
$percentTotal = 0;
foreach ($this->percent as $a) {
list ($percent, $point) = $a;
// If value is null, don't draw this arc
if ($percent <= 0) {
continue;
}
$color = $colorArray[$i % count($colorArray)];
$percentTotal += $percent;
$newAngle = $percentTotal * 360 / 100;
// imagefilledarc doesn't like null values (#1)
if ($newAngle - $oldAngle >= 1) {
imagefilledarc($img, $this->pieCenterX, $cy, $this->pieWidth, $this->pieHeight, $oldAngle, $newAngle, $color->getColor($img), $mode);
}
$oldAngle = $newAngle;
$i++;
}
}
/**
* Print the percentage text.
*/
protected function drawPercent() {
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
$primitive = $this->plot->getPrimitive();
$angle1 = 0;
$percentTotal = 0;
foreach ($this->percent as $a) {
list ($percent, $point) = $a;
// If value is null, the arc isn't drawn, no need to display percent
if ($percent <= 0) {
continue;
}
$percentTotal += $percent;
$angle2 = $percentTotal * 2 * M_PI / 100;
$angle = $angle1 + ($angle2 - $angle1) / 2;
$label = number_format($percent) . "%";
$x = cos($angle) * ($this->pieWidth + 35) / 2 + $this->pieCenterX;
$y = sin($angle) * ($this->pieHeight + 35) / 2 + $this->pieCenterY;
$text->printText($img, $x, $y, $this->plot->getTextColor(), $label, $text->fontCondensed, $text->HORIZONTAL_CENTER_ALIGN | $text->VERTICAL_CENTER_ALIGN);
$angle1 = $angle2;
}
}
/**
* Print the pie chart.
*/
protected function printPie() {
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
$primitive = $this->plot->getPrimitive();
// Get the pie color set
$pieColorSet = $palette->pieColorSet;
$pieColorSet->reset();
// Silhouette
for ($cy = $this->pieCenterY + $this->pieDepth / 2; $cy >= $this->pieCenterY - $this->pieDepth / 2; $cy--) {
$this->drawDisc($cy, $palette->pieColorSet->shadowColorList, IMG_ARC_EDGED);
}
// Top
$this->drawDisc($this->pieCenterY - $this->pieDepth / 2, $palette->pieColorSet->colorList, IMG_ARC_PIE);
// Top Outline
$this->drawPercent();
}
/**
* Render the chart image.
*
* @param string name of the file to render the image to (optional)
*/
public function render($fileName = null) {
$this->computePercent();
$this->computeLayout();
$this->createImage();
$this->plot->printLogo();
$this->plot->printTitle();
$this->printPie();
$this->printCaption();
$this->plot->render($fileName);
}
}
?>

View File

@ -0,0 +1,217 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Chart composed of vertical bars.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class VerticalBarChart extends BarChart {
/**
* Ratio of empty space beside the bars.
*/
private $emptyToFullRatio;
/**
* Creates a new vertical bar chart
*
* @param integer width of the image
* @param integer height of the image
*/
public function VerticalBarChart($width = 600, $height = 250) {
parent::BarChart($width, $height);
$this->emptyToFullRatio = 1 / 5;
$this->plot->setGraphPadding(new Padding(5, 30, 50, 50));
}
/**
* Computes the layout.
*/
protected function computeLayout() {
if ($this->hasSeveralSerie) {
$this->plot->setHasCaption(true);
}
$this->plot->computeLayout();
}
/**
* Print the horizontal and veritcal axis.
*/
protected function printAxis() {
$minValue = $this->axis->getLowerBoundary();
$maxValue = $this->axis->getUpperBoundary();
$stepValue = $this->axis->getTics();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
// Vertical axis
for ($value = $minValue; $value <= $maxValue; $value += $stepValue) {
$y = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta);
imagerectangle($img, $graphArea->x1 - 3, $y, $graphArea->x1 - 2, $y + 1, $palette->axisColor[0]->getColor($img));
imagerectangle($img, $graphArea->x1 - 1, $y, $graphArea->x1, $y + 1, $palette->axisColor[1]->getColor($img));
$text->printText($img, $graphArea->x1 - 5, $y, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_RIGHT_ALIGN | $text->VERTICAL_CENTER_ALIGN);
}
// Get first serie of a list
$pointList = $this->getFirstSerieOfList();
// Horizontal Axis
$pointCount = count($pointList);
reset($pointList);
$columnWidth = ($graphArea->x2 - $graphArea->x1) / $pointCount;
for ($i = 0; $i <= $pointCount; $i++) {
$x = $graphArea->x1 + $i * $columnWidth;
imagerectangle($img, $x - 1, $graphArea->y2 + 2, $x, $graphArea->y2 + 3, $palette->axisColor[0]->getColor($img));
imagerectangle($img, $x - 1, $graphArea->y2, $x, $graphArea->y2 + 1, $palette->axisColor[1]->getColor($img));
if ($i < $pointCount) {
$point = current($pointList);
next($pointList);
$label = $point->getX();
$text->printDiagonal($img, $x + $columnWidth * 1 / 3, $graphArea->y2 + 10, $this->plot->getTextColor(), $label);
}
}
}
/**
* Print the bars.
*/
protected function printBar() {
// Get the data as a list of series for consistency
$serieList = $this->getDataAsSerieList();
// Get graphical obects
$img = $this->plot->getImg();
$palette = $this->plot->getPalette();
$text = $this->plot->getText();
// Get the graph area
$graphArea = $this->plot->getGraphArea();
$barColorSet = $palette->barColorSet;
$barColorSet->reset();
$minValue = $this->axis->getLowerBoundary();
$maxValue = $this->axis->getUpperBoundary();
$stepValue = $this->axis->getTics();
$serieCount = count($serieList);
for ($j = 0; $j < $serieCount; $j++) {
$serie = $serieList[$j];
$pointList = $serie->getPointList();
$pointCount = count($pointList);
reset($pointList);
// Get the next color
$color = $barColorSet->currentColor();
$shadowColor = $barColorSet->currentShadowColor();
$barColorSet->next();
$columnWidth = ($graphArea->x2 - $graphArea->x1) / $pointCount;
for ($i = 0; $i < $pointCount; $i++) {
$x = $graphArea->x1 + $i * $columnWidth;
$point = current($pointList);
next($pointList);
$value = $point->getY();
$ymin = $graphArea->y2 - ($value - $minValue) * ($graphArea->y2 - $graphArea->y1) / ($this->axis->displayDelta);
// Bar dimensions
$xWithMargin = $x + $columnWidth * $this->emptyToFullRatio;
$columnWidthWithMargin = $columnWidth * (1 - $this->emptyToFullRatio * 2);
$barWidth = $columnWidthWithMargin / $serieCount;
$barOffset = $barWidth * $j;
$x1 = $xWithMargin + $barOffset;
$x2 = $xWithMargin + $barWidth + $barOffset - 1;
// Text
$text->printText($img, $x1 + $barWidth / 2 , $ymin - 5, $this->plot->getTextColor(), $value, $text->fontCondensed, $text->HORIZONTAL_CENTER_ALIGN | $text->VERTICAL_BOTTOM_ALIGN);
// Vertical bar
imagefilledrectangle($img, $x1, $ymin, $x2, $graphArea->y2 - 1, $shadowColor->getColor($img));
// Prevents drawing a small box when y = 0
if ($ymin != $graphArea->y2) {
imagefilledrectangle($img, $x1 + 1, $ymin + 1, $x2 - 4, $graphArea->y2 - 1, $color->getColor($img));
}
}
}
}
/**
* Renders the caption.
*/
protected function printCaption() {
// Get the list of labels
$labelList = $this->dataSet->getTitleList();
// Create the caption
$caption = new Caption();
$caption->setPlot($this->plot);
$caption->setLabelList($labelList);
$palette = $this->plot->getPalette();
$barColorSet = $palette->barColorSet;
$caption->setColorSet($barColorSet);
// Render the caption
$caption->render();
}
/**
* Render the chart image.
*
* @param string name of the file to render the image to (optional)
*/
public function render($fileName = null) {
// Check the data model
$this->checkDataModel();
$this->bound->computeBound($this->dataSet);
$this->computeAxis();
$this->computeLayout();
$this->createImage();
$this->plot->printLogo();
$this->plot->printTitle();
if (!$this->isEmptyDataSet(1)) {
$this->printAxis();
$this->printBar();
if ($this->hasSeveralSerie) {
$this->printCaption();
}
}
$this->plot->render($fileName);
}
}
?>

View File

@ -0,0 +1,99 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Color.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class Color {
private $red;
private $green;
private $blue;
private $alpha;
private $gdColor;
/**
* Creates a new color
*
* @param integer red [0..255]
* @param integer green [0..255]
* @param integer blue [0..255]
* @param integer alpha [0..255]
*/
public function Color($red, $green, $blue, $alpha = 0) {
$this->red = (int) $red;
$this->green = (int) $green;
$this->blue = (int) $blue;
$this->alpha = (int) round($alpha * 127.0 / 255);
$this->gdColor = null;
}
/**
* Get GD color.
*
* @param $img GD image resource
*/
public function getColor($img) {
// Checks if color has already been allocated
if (!$this->gdColor) {
if ($this->alpha == 0 || !function_exists('imagecolorallocatealpha')) {
$this->gdColor = imagecolorallocate($img, $this->red, $this->green, $this->blue);
} else {
$this->gdColor = imagecolorallocatealpha($img, $this->red, $this->green, $this->blue, $this->alpha);
}
}
// Returns GD color
return $this->gdColor;
}
/**
* Clip a color component in the interval [0..255]
*
* @param integer Component
* @return Clipped component
*/
public function clip($component) {
if ($component < 0) {
$component = 0;
} else if ($component > 255) {
$component = 255;
}
return $component;
}
/**
* Return a new color, which is a shadow of this one.
*
* @param double Multiplication factor
* @return Shadow color
*/
public function getShadowColor($shadowFactor) {
$red = $this->clip($this->red * $shadowFactor);
$green = $this->clip($this->green * $shadowFactor);
$blue = $this->clip($this->blue * $shadowFactor);
$shadowColor = new Color($red, $green, $blue);
return $shadowColor;
}
}
?>

View File

@ -0,0 +1,88 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* A set of colors, used for drawing series of data.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
* Created on 26 july 2007
*/
class ColorSet {
public $colorList;
public $shadowColorList;
/**
* ColorSet constructor.
*
* @param $shadowFactor Shadow factor
* @param $colorArray Colors as an array
*/
public function ColorSet($colorList, $shadowFactor) {
$this->colorList = $colorList;
$this->shadowColorList = array();
// Generate the shadow color set
foreach ($colorList as $color) {
$shadowColor = $color->getShadowColor($shadowFactor);
array_push($this->shadowColorList, $shadowColor);
}
}
/**
* Reset the iterator over the collections of colors.
*/
public function reset() {
reset($this->colorList);
reset($this->shadowColorList);
}
/**
* Iterate over the colors and shadow colors. When we go after the last one, loop over.
*
*/
public function next() {
$value = next($this->colorList);
next($this->shadowColorList);
// When we go after the last value, loop over.
if ($value == FALSE) {
$this->reset();
}
}
/**
* Returns the current color.
*
* @return Current color
*/
public function currentColor() {
return current($this->colorList);
}
/**
* Returns the current shadow color.
*
* @return Current shadow color
*/
public function currentShadowColor() {
return current($this->shadowColorList);
}
}
?>

View File

@ -0,0 +1,156 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Color palette shared by all chart types.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
* Created on 25 july 2007
*/
class Palette {
// Plot attributes
public $red;
public $axisColor;
public $backgroundColor;
// Specific chart attributes
public $barColorSet;
public $lineColorSet;
public $pieColorSet;
/**
* Palette constructor.
*/
public function Palette() {
$this->red = new Color(255, 0, 0);
// Set the colors for the horizontal and vertical axis
$this->setAxisColor(array(
new Color(201, 201, 201),
new Color(158, 158, 158)
));
// Set the colors for the background
$this->setBackgroundColor(array(
new Color(242, 242, 242),
new Color(231, 231, 231),
new Color(239, 239, 239),
new Color(253, 253, 253)
));
// Set the colors for the bars
$this->setBarColor(array(
new Color(42, 71, 181),
new Color(243, 198, 118),
new Color(128, 63, 35),
new Color(195, 45, 28),
new Color(224, 198, 165),
new Color(239, 238, 218),
new Color(40, 72, 59),
new Color(71, 112, 132),
new Color(167, 192, 199),
new Color(218, 233, 202)
));
// Set the colors for the lines
$this->setLineColor(array(
new Color(172, 172, 210),
new Color(2, 78, 0),
new Color(148, 170, 36),
new Color(233, 191, 49),
new Color(240, 127, 41),
new Color(243, 63, 34),
new Color(190, 71, 47),
new Color(135, 81, 60),
new Color(128, 78, 162),
new Color(121, 75, 255),
new Color(142, 165, 250),
new Color(162, 254, 239),
new Color(137, 240, 166),
new Color(104, 221, 71),
new Color(98, 174, 35),
new Color(93, 129, 1)
));
// Set the colors for the pie
$this->setPieColor(array(
new Color(2, 78, 0),
new Color(148, 170, 36),
new Color(233, 191, 49),
new Color(240, 127, 41),
new Color(243, 63, 34),
new Color(190, 71, 47),
new Color(135, 81, 60),
new Color(128, 78, 162),
new Color(121, 75, 255),
new Color(142, 165, 250),
new Color(162, 254, 239),
new Color(137, 240, 166),
new Color(104, 221, 71),
new Color(98, 174, 35),
new Color(93, 129, 1)
));
}
/**
* Set the colors for the axis.
*
* @param colors Array of Color
*/
public function setAxisColor($colors) {
$this->axisColor = $colors;
}
/**
* Set the colors for the background.
*
* @param colors Array of Color
*/
public function setBackgroundColor($colors) {
$this->backgroundColor = $colors;
}
/**
* Set the colors for the bar charts.
*
* @param colors Array of Color
*/
public function setBarColor($colors) {
$this->barColorSet = new ColorSet($colors, 0.75);
}
/**
* Set the colors for the line charts.
*
* @param colors Array of Color
*/
public function setLineColor($colors) {
$this->lineColorSet = new ColorSet($colors, 0.75);
}
/**
* Set the colors for the pie charts.
*
* @param colors Array of Color
*/
public function setPieColor($colors) {
$this->pieColorSet = new ColorSet($colors, 0.7);
}
}
?>

View File

@ -0,0 +1,443 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* The plot holds graphical attributes, and is responsible for computing the layout of the graph.
* The layout is quite simple right now, with 4 areas laid out like that:
* (of course this is subject to change in the future).
*
* output area------------------------------------------------|
* | (outer padding) |
* | image area--------------------------------------------| |
* | | (title padding) | |
* | | title area----------------------------------------| | |
* | | |-------------------------------------------------| | |
* | | | |
* | | (graph padding) (caption padding) | |
* | | graph area----------------| caption area---------| | |
* | | | | | | | |
* | | | | | | | |
* | | | | | | | |
* | | | | | | | |
* | | | | | | | |
* | | |-------------------------| |--------------------| | |
* | | | |
* | |-----------------------------------------------------| |
* | |
* |----------------------------------------------------------|
*
* All area dimensions are known in advance , and the optional logo is drawn in absolute coordinates.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
* Created on 27 july 2007
*/
class Plot {
// Style properties
protected $title;
/**
* Location of the logo. Can be overriden to your personalized logo.
*/
protected $logoFileName;
/**
* Outer area, whose dimension is the same as the PNG returned.
*/
protected $outputArea;
/**
* Outer padding surrounding the whole image, everything outside is blank.
*/
protected $outerPadding;
/**
* Coordinates of the area inside the outer padding.
*/
protected $imageArea;
/**
* Fixed title height in pixels.
*/
protected $titleHeight;
/**
* Padding of the title area.
*/
protected $titlePadding;
/**
* Coordinates of the title area.
*/
protected $titleArea;
/**
* True if the plot has a caption.
*/
protected $hasCaption;
/**
* Ratio of graph/caption in width.
*/
protected $graphCaptionRatio;
/**
* Padding of the graph area.
*/
protected $graphPadding;
/**
* Coordinates of the graph area.
*/
protected $graphArea;
/**
* Padding of the caption area.
*/
protected $captionPadding;
/**
* Coordinates of the caption area.
*/
protected $captionArea;
/**
* Text writer.
*/
protected $text;
/**
* Color palette.
*/
protected $palette;
/**
* GD image
*/
protected $img;
/**
* Drawing primitives
*/
protected $primitive;
protected $backGroundColor;
protected $textColor;
/**
* Constructor of Plot.
*
* @param integer width of the image
* @param integer height of the image
*/
public function Plot($width, $height) {
$this->width = $width;
$this->height = $height;
$this->text = new Text();
$this->palette = new Palette();
// Default layout
$this->outputArea = new Rectangle(0, 0, $width - 1, $height - 1);
$this->outerPadding = new Padding(5);
$this->titleHeight = 26;
$this->titlePadding = new Padding(5);
$this->hasCaption = false;
$this->graphCaptionRatio = 0.50;
$this->graphPadding = new Padding(50);
$this->captionPadding = new Padding(15);
}
/**
* Compute the area inside the outer padding (outside is white).
*/
private function computeImageArea() {
$this->imageArea = $this->outputArea->getPaddedRectangle($this->outerPadding);
}
/**
* Compute the title area.
*/
private function computeTitleArea() {
$titleUnpaddedBottom = $this->imageArea->y1 + $this->titleHeight + $this->titlePadding->top + $this->titlePadding->bottom;
$titleArea = new Rectangle(
$this->imageArea->x1,
$this->imageArea->y1,
$this->imageArea->x2,
$titleUnpaddedBottom - 1
);
$this->titleArea = $titleArea->getPaddedRectangle($this->titlePadding);
}
/**
* Compute the graph area.
*/
private function computeGraphArea() {
$titleUnpaddedBottom = $this->imageArea->y1 + $this->titleHeight + $this->titlePadding->top + $this->titlePadding->bottom;
$graphArea = null;
if ($this->hasCaption) {
$graphUnpaddedRight = $this->imageArea->x1 + ($this->imageArea->x2 - $this->imageArea->x1) * $this->graphCaptionRatio
+ $this->graphPadding->left + $this->graphPadding->right;
$graphArea = new Rectangle(
$this->imageArea->x1,
$titleUnpaddedBottom,
$graphUnpaddedRight - 1,
$this->imageArea->y2
);
} else {
$graphArea = new Rectangle(
$this->imageArea->x1+70,
$titleUnpaddedBottom,
$this->imageArea->x2,
$this->imageArea->y2
);
}
$this->graphArea = $graphArea->getPaddedRectangle($this->graphPadding);
}
/**
* Compute the caption area.
*/
private function computeCaptionArea() {
$graphUnpaddedRight = $this->imageArea->x1 + ($this->imageArea->x2 - $this->imageArea->x1) * $this->graphCaptionRatio
+ $this->graphPadding->left + $this->graphPadding->right;
$titleUnpaddedBottom = $this->imageArea->y1 + $this->titleHeight + $this->titlePadding->top + $this->titlePadding->bottom;
$captionArea = new Rectangle(
$graphUnpaddedRight,
$titleUnpaddedBottom,
$this->imageArea->x2,
$this->imageArea->y2
);
$this->captionArea = $captionArea->getPaddedRectangle($this->captionPadding);
}
/**
* Compute the layout of all areas of the graph.
*/
public function computeLayout() {
$this->computeImageArea();
$this->computeTitleArea();
$this->computeGraphArea();
if ($this->hasCaption) {
$this->computeCaptionArea();
}
}
/**
* Creates and initialize the image.
*/
public function createImage() {
$this->img = imagecreatetruecolor($this->width, $this->height);
$this->primitive = new Primitive($this->img);
$this->backGroundColor = new Color(255, 255, 255);
$this->textColor = new Color(0, 0, 0);
// White background
imagefilledrectangle($this->img, 0, 0, $this->width - 1, $this->height - 1, $this->backGroundColor->getColor($this->img));
//imagerectangle($this->img, $this->imageArea->x1, $this->imageArea->y1, $this->imageArea->x2, $this->imageArea->y2, $this->palette->red->getColor($this->img));
}
/**
* Print the title to the image.
*/
public function printTitle() {
$yCenter = $this->titleArea->y1 + ($this->titleArea->y2 - $this->titleArea->y1) / 2;
$this->text->printCentered($this->img, $yCenter, $this->textColor, $this->title, $this->text->fontCondensedBold);
}
/**
* Print the logo image to the image.
*/
public function printLogo() {
@$logoImage = imageCreateFromPNG($this->logoFileName);
if ($logoImage) {
imagecopymerge($this->img, $logoImage, 2 * $this->outerPadding->left, $this->outerPadding->top, 0, 0, imagesx($logoImage), imagesy($logoImage), 100);
}
}
/**
* Renders to a file or to standard output.
*
* @param fileName File name (optional)
*/
public function render($fileName) {
if (isset($fileName)) {
imagepng($this->img, $fileName);
} else {
imagepng($this->img);
}
}
/**
* Sets the title.
*
* @param string New title
*/
public function setTitle($title) {
$this->title = $title;
}
/**
* Sets the logo image file name.
*
* @param string New logo image file name
*/
public function setLogoFileName($logoFileName) {
$this->logoFileName = $logoFileName;
}
/**
* Return the GD image.
*
* @return GD Image
*/
public function getImg() {
return $this->img;
}
/**
* Return the palette.
*
* @return palette
*/
public function getPalette() {
return $this->palette;
}
/**
* Return the text.
*
* @return text
*/
public function getText() {
return $this->text;
}
/**
* Return the primitive.
*
* @return primitive
*/
public function getPrimitive() {
return $this->primitive;
}
/**
* Return the outer padding.
*
* @param integer Outer padding value in pixels
*/
public function getOuterPadding() {
return $outerPadding;
}
/**
* Set the outer padding.
*
* @param integer Outer padding value in pixels
*/
public function setOuterPadding($outerPadding) {
$this->outerPadding = $outerPadding;
}
/**
* Return the title height.
*
* @param integer title height
*/
public function setTitleHeight($titleHeight) {
$this->titleHeight = $titleHeight;
}
/**
* Return the title padding.
*
* @param integer title padding
*/
public function setTitlePadding($titlePadding) {
$this->titlePadding = $titlePadding;
}
/**
* Return the graph padding.
*
* @param integer graph padding
*/
public function setGraphPadding($graphPadding) {
$this->graphPadding = $graphPadding;
}
/**
* Set if the graph has a caption.
*
* @param boolean graph has a caption
*/
public function setHasCaption($hasCaption) {
$this->hasCaption = $hasCaption;
}
/**
* Set the caption padding.
*
* @param integer caption padding
*/
public function setCaptionPadding($captionPadding) {
$this->captionPadding = $captionPadding;
}
/**
* Set the graph/caption ratio.
*
* @param integer caption padding
*/
public function setGraphCaptionRatio($graphCaptionRatio) {
$this->graphCaptionRatio = $graphCaptionRatio;
}
/**
* Return the graph area.
*
* @return graph area
*/
public function getGraphArea() {
return $this->graphArea;
}
/**
* Return the caption area.
*
* @return caption area
*/
public function getCaptionArea() {
return $this->captionArea;
}
/**
* Return the text color.
*
* @return text color
*/
public function getTextColor() {
return $this->textColor;
}
}
?>

View File

@ -0,0 +1,68 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Primitive geometric object representing a padding.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
* @Created on 27 july 2007
*/
class Padding {
/**
* Top padding.
*/
public $top;
/**
* Right padding.
*/
public $right;
/**
* Bottom padding.
*/
public $bottom;
/**
* Left padding.
*/
public $left;
/**
* Creates a new padding.
*
* @param integer Top padding
* @param integer Right padding
* @param integer Bottom padding
* @param integer Left padding
*/
public function Padding($top, $right = null, $bottom = null, $left = null) {
$this->top = $top;
if ($right == null) {
$this->right = $top;
$this->bottom = $top;
$this->left = $top;
} else {
$this->right = $right;
$this->bottom = $bottom;
$this->left = $left;
}
}
}
?>

View File

@ -0,0 +1,70 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Graphic primitives, extends GD with chart related primitives.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class Primitive {
private $img;
/**
* Creates a new primitive object
*
* @param resource GD image resource
*/
public function Primitive($img) {
$this->img = $img;
}
/**
* Draws a straight line.
*
* @param integer line start (X)
* @param integer line start (Y)
* @param integer line end (X)
* @param integer line end (Y)
* @param Color line color
*/
public function line($x1, $y1, $x2, $y2, $color, $width = 1) {
imagefilledpolygon($this->img, array($x1, $y1 - $width / 2, $x1, $y1 + $width / 2, $x2, $y2 + $width / 2, $x2, $y2 - $width / 2), 4, $color->getColor($this->img));
// imageline($this->img, $x1, $y1, $x2, $y2, $color->getColor($this->img));
}
/**
* Draw a filled gray box with thick borders and darker corners.
*
* @param integer top left coordinate (x)
* @param integer top left coordinate (y)
* @param integer bottom right coordinate (x)
* @param integer bottom right coordinate (y)
* @param Color edge color
* @param Color corner color
*/
public function outlinedBox($x1, $y1, $x2, $y2, $color0, $color1) {
imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $color0->getColor($this->img));
imagerectangle($this->img, $x1, $y1, $x1 + 1, $y1 + 1, $color1->getColor($this->img));
imagerectangle($this->img, $x2 - 1, $y1, $x2, $y1 + 1, $color1->getColor($this->img));
imagerectangle($this->img, $x1, $y2 - 1, $x1 + 1, $y2, $color1->getColor($this->img));
imagerectangle($this->img, $x2 - 1, $y2 - 1, $x2, $y2, $color1->getColor($this->img));
}
}
?>

View File

@ -0,0 +1,80 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* A rectangle identified by the top-left and the bottom-right corners.
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
* @Created on 27 july 2007
*/
class Rectangle {
/**
* Top left X.
*/
public $x1;
/**
* Top left Y.
*/
public $y1;
/**
* Bottom right X.
*/
public $x2;
/**
* Bottom right Y.
*/
public $y2;
/**
* Constructor of Rectangle.
*
* @param x1 Left edge coordinate
* @param y1 Upper edge coordinate
* @param x2 Right edge coordinate
* @param y2 Bottom edge coordinate
*/
public function Rectangle($x1, $y1, $x2, $y2) {
$this->x1 = $x1;
$this->y1 = $y1;
$this->x2 = $x2;
$this->y2 = $y2;
}
/**
* Apply a padding and returns the resulting rectangle.
* The result is an enlarged rectangle.
*
* @return Padded rectangle
*/
public function getPaddedRectangle($padding) {
$rectangle = new Rectangle(
$this->x1 + $padding->left,
$this->y1 + $padding->top,
$this->x2 - $padding->right,
$this->y2 - $padding->bottom
);
//echo "(" . $this->x1 . "," . $this->y1 . ") (" . $this->x2 . "," . $this->y2 . ")<br>";
return $rectangle;
}
}
?>

View File

@ -0,0 +1,129 @@
<?php
/* Libchart - PHP chart library
* Copyright (C) 2005-2010 Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*
* 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/>.
*
*/
/**
* Text drawing helper
*
* @author Jean-Marc Tr<54>meaux (jm.tremeaux at gmail.com)
*/
class Text {
public $HORIZONTAL_LEFT_ALIGN = 1;
public $HORIZONTAL_CENTER_ALIGN = 2;
public $HORIZONTAL_RIGHT_ALIGN = 4;
public $VERTICAL_TOP_ALIGN = 8;
public $VERTICAL_CENTER_ALIGN = 16;
public $VERTICAL_BOTTOM_ALIGN = 32;
/**
* Creates a new text drawing helper.
*/
public function Text() {
$baseDir = dirname(__FILE__) . "/../../../";
// Free low-res fonts based on Bitstream Vera <http://dejavu.sourceforge.net/wiki/>
$this->fontCondensed = $baseDir . "fonts/DejaVuSansCondensed.ttf";
$this->fontCondensedBold = $baseDir . "fonts/DejaVuSansCondensed-Bold.ttf";
}
/**
* Print text.
*
* @param Image GD image
* @param integer text coordinate (x)
* @param integer text coordinate (y)
* @param Color text color
* @param string text value
* @param string font file name
* @param bitfield text alignment
*/
public function printText($img, $px, $py, $color, $text, $fontFileName, $align = 0) {
if (!($align & $this->HORIZONTAL_CENTER_ALIGN) && !($align & $this->HORIZONTAL_RIGHT_ALIGN)) {
$align |= $this->HORIZONTAL_LEFT_ALIGN;
}
if (!($align & $this->VERTICAL_CENTER_ALIGN) && !($align & $this->VERTICAL_BOTTOM_ALIGN)) {
$align |= $this->VERTICAL_TOP_ALIGN;
}
$fontSize = 8;
$lineSpacing = 1;
list ($llx, $lly, $lrx, $lry, $urx, $ury, $ulx, $uly) = imageftbbox($fontSize, 0, $fontFileName, $text, array("linespacing" => $lineSpacing));
$textWidth = $lrx - $llx;
$textHeight = $lry - $ury;
$angle = 0;
if ($align & $this->HORIZONTAL_CENTER_ALIGN) {
$px -= $textWidth / 2;
}
if ($align & $this->HORIZONTAL_RIGHT_ALIGN) {
$px -= $textWidth;
}
if ($align & $this->VERTICAL_CENTER_ALIGN) {
$py += $textHeight / 2;
}
if ($align & $this->VERTICAL_TOP_ALIGN) {
$py += $textHeight;
}
imagettftext($img, $fontSize, $angle, $px, $py, $color->getColor($img), $fontFileName, $text);
}
/**
* Print text centered horizontally on the image.
*
* @param Image GD image
* @param integer text coordinate (y)
* @param Color text color
* @param string text value
* @param string font file name
*/
public function printCentered($img, $py, $color, $text, $fontFileName) {
$this->printText($img, imagesx($img) / 2, $py, $color, $text, $fontFileName, $this->HORIZONTAL_CENTER_ALIGN | $this->VERTICAL_CENTER_ALIGN);
}
/**
* Print text in diagonal.
*
* @param Image GD image
* @param integer text coordinate (x)
* @param integer text coordinate (y)
* @param Color text color
* @param string text value
*/
public function printDiagonal($img, $px, $py, $color, $text) {
$fontSize = 8;
$fontFileName = $this->fontCondensed;
$lineSpacing = 1;
list ($lx, $ly, $rx, $ry) = imageftbbox($fontSize, 0, $fontFileName, $text, array("linespacing" => $lineSpacing));
$textWidth = $rx - $lx;
$angle = -45;
imagettftext($img, $fontSize, $angle, $px, $py, $color->getColor($img), $fontFileName, $text);
}
}
?>