2 /* Libchart - PHP chart library
3 * Copyright (C) 2005-2008 Jean-Marc Trémeaux (jm.tremeaux at gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * Base abstract class for rendering both horizontal and vertical bar charts.
23 * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com)
25 abstract class BarChart extends Chart {
28 protected $hasSeveralSerie;
31 * Creates a new bar chart.
33 * @param integer width of the image
34 * @param integer height of the image
36 protected function BarChart($width, $height) {
37 parent::Chart($width, $height);
39 // Initialize the bounds
40 $this->bound = new Bound();
41 $this->bound->setLowerBound(0);
47 protected function computeAxis() {
48 $this->axis = new Axis($this->bound->getYMinValue(), $this->bound->getYMaxValue());
49 $this->axis->computeBoundaries();
55 protected function createImage() {
56 parent::createImage();
58 // Get graphical obects
59 $img = $this->plot->getImg();
60 $palette = $this->plot->getPalette();
61 $text = $this->plot->getText();
62 $primitive = $this->plot->getPrimitive();
65 $graphArea = $this->plot->getGraphArea();
67 // Aqua-like background
68 for ($i = $graphArea->y1; $i < $graphArea->y2; $i++) {
69 $color = $palette->aquaColor[($i + 3) % 4];
70 $primitive->line($graphArea->x1, $i, $graphArea->x2, $i, $color);
74 imagerectangle($img, $graphArea->x1 - 1, $graphArea->y1, $graphArea->x1, $graphArea->y2, $palette->axisColor[0]->getColor($img));
75 imagerectangle($img, $graphArea->x1 - 1, $graphArea->y2, $graphArea->x2, $graphArea->y2 + 1, $palette->axisColor[0]->getColor($img));
79 * Returns true if the data set has some data.
80 * @param minNumberOfPoint Minimum number of points (1 for bars, 2 for lines).
82 * @return true if data set empty
84 protected function isEmptyDataSet($minNumberOfPoint) {
85 if ($this->dataSet instanceof XYDataSet) {
86 $pointList = $this->dataSet->getPointList();
87 $pointCount = count($pointList);
88 return $pointCount < $minNumberOfPoint;
89 } else if ($this->dataSet instanceof XYSeriesDataSet) {
90 $serieList = $this->dataSet->getSerieList();
92 if (count($serieList) > 0) {
93 $serie = current($serieList);
94 $pointList = $serie->getPointList();
95 $pointCount = count($pointList);
96 return $pointCount < $minNumberOfPoint;
99 die("Error: unknown dataset type");
104 * Checks the data model before rendering the graph.
106 protected function checkDataModel() {
107 // Check if a dataset was defined
108 if (!$this->dataSet) {
109 die("Error: No dataset defined.");
112 // Bar charts accept both XYDataSet and XYSeriesDataSet
113 if ($this->dataSet instanceof XYDataSet) {
114 // The dataset contains only one serie
115 $this->hasSeveralSerie = false;
116 } else if ($this->dataSet instanceof XYSeriesDataSet) {
117 // Check if each series has the same number of points
118 unset($lastPointCount);
119 $serieList = $this->dataSet->getSerieList();
120 for ($i = 0; $i < count($serieList); $i++) {
121 $serie = $serieList[$i];
122 $pointCount = count($serie->getPointList());
123 if (isset($lastPointCount) && $pointCount != $lastPointCount) {
124 die("Error: serie <" . $i . "> doesn't have the same number of points as last serie (last one: <" . $lastPointCount. ">, this one: <" . $pointCount. ">).");
126 $lastPointCount = $pointCount;
129 // The dataset contains several series
130 $this->hasSeveralSerie = true;
132 die("Error: Bar chart accept only XYDataSet and XYSeriesDataSet");
137 * Return the data as a series list (for consistency).
139 * @return List of series
141 protected function getDataAsSerieList() {
142 // Get the data as a series list
144 if ($this->dataSet instanceof XYSeriesDataSet) {
145 $serieList = $this->dataSet->getSerieList();
146 } else if ($this->dataSet instanceof XYDataSet) {
147 $serieList = array();
148 array_push($serieList, $this->dataSet);
155 * Return the first serie of the list, or the dataSet itself if there is no serie.
159 protected function getFirstSerieOfList() {
161 if ($this->dataSet instanceof XYSeriesDataSet) {
162 // For a series dataset, print the legend from the first serie
163 $serieList = $this->dataSet->getSerieList();
165 $serie = current($serieList);
166 $pointList = $serie->getPointList();
167 } else if ($this->dataSet instanceof XYDataSet) {
168 $pointList = $this->dataSet->getPointList();
175 * Retourns the bound.
177 * @return bound Bound
179 public function getBound() {