posaune
[timetracker.git] / WEB-INF / lib / libchart / classes / view / chart / BarChart.php
1 <?php
2         /* Libchart - PHP chart library
3          * Copyright (C) 2005-2008 Jean-Marc Trémeaux (jm.tremeaux at gmail.com)
4          * 
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.
9          * 
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.
14          *
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/>.
17          * 
18          */
19         
20         /**
21          * Base abstract class for rendering both horizontal and vertical bar charts.
22          *
23          * @author Jean-Marc Trémeaux (jm.tremeaux at gmail.com)
24          */
25         abstract class BarChart extends Chart {
26                 protected $bound;
27                 protected $axis;
28                 protected $hasSeveralSerie;
29                 
30                 /**
31                  * Creates a new bar chart.
32                  *
33                  * @param integer width of the image
34                  * @param integer height of the image
35                  */
36                 protected function BarChart($width, $height) {
37                         parent::Chart($width, $height);
38
39                         // Initialize the bounds
40                         $this->bound = new Bound();
41                         $this->bound->setLowerBound(0);
42                 }
43
44                 /**
45                  * Compute the axis.
46                  */
47                 protected function computeAxis() {
48                         $this->axis = new Axis($this->bound->getYMinValue(), $this->bound->getYMaxValue());
49                         $this->axis->computeBoundaries();
50                 }
51
52                 /**
53                  * Create the image.
54                  */
55                 protected function createImage() {
56                         parent::createImage();
57
58                         // Get graphical obects
59                         $img = $this->plot->getImg();
60                         $palette = $this->plot->getPalette();
61                         $text = $this->plot->getText();
62                         $primitive = $this->plot->getPrimitive();
63                         
64                         // Get the graph area
65                         $graphArea = $this->plot->getGraphArea();
66
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);
71                         }
72
73                         // Axis
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));
76                 }
77
78                 /**
79                  * Returns true if the data set has some data.
80                  * @param minNumberOfPoint Minimum number of points (1 for bars, 2 for lines).
81                  *
82                  * @return true if data set empty
83                  */
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();
91                                 reset($serieList);
92                                 if (count($serieList) > 0) {
93                                         $serie = current($serieList);
94                                         $pointList = $serie->getPointList();
95                                         $pointCount = count($pointList);
96                                         return $pointCount < $minNumberOfPoint;
97                                 }
98                         } else {
99                                 die("Error: unknown dataset type");
100                         }
101                 }
102
103                 /**
104                  * Checks the data model before rendering the graph.
105                  */
106                 protected function checkDataModel() {
107                         // Check if a dataset was defined
108                         if (!$this->dataSet) {
109                                 die("Error: No dataset defined.");
110                         }
111                         
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. ">).");
125                                         }
126                                         $lastPointCount = $pointCount;
127                                 }
128                                 
129                                 // The dataset contains several series
130                                 $this->hasSeveralSerie = true;
131                         } else {
132                                 die("Error: Bar chart accept only XYDataSet and XYSeriesDataSet");
133                         }
134                 }
135
136                 /**
137                  * Return the data as a series list (for consistency).
138                  *
139                  * @return List of series
140                  */
141                 protected function getDataAsSerieList() {
142                         // Get the data as a series list
143                         $serieList = null;
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);
149                         }
150                         
151                         return $serieList;
152                 }
153                 
154                 /**
155                  * Return the first serie of the list, or the dataSet itself if there is no serie.
156                  *
157                  * @return XYDataSet
158                  */
159                 protected function getFirstSerieOfList() {
160                         $pointList = null;
161                         if ($this->dataSet instanceof XYSeriesDataSet) {
162                                 // For a series dataset, print the legend from the first serie
163                                 $serieList = $this->dataSet->getSerieList();
164                                 reset($serieList);
165                                 $serie = current($serieList);
166                                 $pointList = $serie->getPointList();
167                         } else if ($this->dataSet instanceof XYDataSet) {
168                                 $pointList = $this->dataSet->getPointList();
169                         }
170                         
171                         return $pointList;
172                 }
173                 
174                 /**
175                  * Retourns the bound.
176                  *
177                  * @return bound Bound
178                  */
179                 public function getBound() {
180                         return $this->bound;
181                 }
182         }
183 ?>