mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-11-15 08:11:59 +01:00
183 lines
5.5 KiB
PHP
183 lines
5.5 KiB
PHP
|
<?php
|
|||
|
/* Libchart - PHP chart library
|
|||
|
* Copyright (C) 2005-2010 Jean-Marc Tr<EFBFBD>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<EFBFBD>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;
|
|||
|
}
|
|||
|
}
|
|||
|
?>
|