Removing all the package replacement tags and SVN keyword tags
[isso.git] / Graph.php
1 <?php
2 /*=====================================================================*
3 || ###################################################################
4 || # Blue Static ISSO Framework
5 || # Copyright ©2002-2007 Blue Static
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version 2 of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Graphing System (Graph.php)
24 *
25 * @package ISSO
26 */
27
28 /**
29 * Graphing System
30 *
31 * This is an abstract class that all other graphing systems extend. It takes
32 * care of things like scales, data sets, and dimensions.
33 *
34 * @author Blue Static
35 * @copyright Copyright (c)2002 - 2007, Blue Static
36 * @package ISSO
37 *
38 */
39 abstract class BSGraph
40 {
41 /**
42 * Graphing data set; 2D array of plot information
43 * @var array
44 */
45 protected $dataset = array();
46
47 /**
48 * Image resource
49 * @var resource
50 */
51 protected $image = null;
52
53 /**
54 * The dimensions of the image
55 * @var array
56 */
57 protected $dimensions = array('width' => 550, 'height' => 350);
58
59 /**
60 * Add a legend to the graph?
61 * @var bool
62 */
63 protected $legend = true;
64
65 /**
66 * Title of the graph
67 * @var string
68 */
69 protected $title = 'ISSO Pie Chart';
70
71 /**
72 * Padding in the graph
73 * @var integer
74 */
75 const PADDING = 10;
76
77 /**
78 * Spacing in the graph
79 * @var integer
80 */
81 const SPACING = 4;
82
83 // ###################################################################
84 /**
85 * Constructor
86 */
87 public function __construct()
88 {
89 $this->setScale(0);
90 }
91
92 // ###################################################################
93 /**
94 * Sets the width and height by using scale factors of 550x350; you
95 * can specify a positive value to multiply by that many times or a
96 * negative one to divide
97 *
98 * @param float Scale factor
99 */
100 public function setScale($scale)
101 {
102 $this->dimensions['width'] = 550;
103 $this->dimensions['height'] = 350;
104
105 if ($scale > 0)
106 {
107 $this->dimensions['width'] *= $scale;
108 $this->dimensions['height'] *= $scale;
109 }
110 else if ($scale < 0)
111 {
112 $scale = abs($scale);
113 $this->dimensions['width'] /= $scale;
114 $this->dimensions['height'] /= $scale;
115 }
116
117 if (!is_null($this->image))
118 {
119 imagedestroy($this->image);
120 }
121
122 $this->image = imagecreate($this->dimensions['width'], $this->dimensions['height']);
123 }
124
125 // ###################################################################
126 /**
127 * Sets whether or not a legend is created for the graph
128 *
129 * @param bool Draw a legend?
130 */
131 public function setLegend($yesno)
132 {
133 $this->legend = (bool)$yesno;
134 }
135
136 // ###################################################################
137 /**
138 * Sets the title of the chart to be drawn above the graph
139 *
140 * @param string Title of the chart
141 */
142 public function setTitle($title)
143 {
144 $this->title = $title;
145 }
146
147 // ###################################################################
148 /**
149 * Graphs the actual data and returns then sends the image result to
150 * the output buffer
151 */
152 public abstract function graph();
153
154 // ###################################################################
155 /**
156 * Adds an entry to the data set without specifying a color to add.
157 * This is the standard method as the color should only be overridden
158 * if necessary.
159 *
160 * @param string Data column name
161 * @param integer Amount
162 */
163 public abstract function addDataSet($name, $amount);
164
165 // ###################################################################
166 /**
167 * Adds an entry ot the data set with specifying a color. This works
168 * the same as addDataSet() but requires an array() as the 3rd parameter
169 * of R,G,B values
170 *
171 * @param string Data column name
172 * @param integer Percent of 100
173 * @param array Array of R,G,B values
174 */
175 public abstract function addDataSetColor($name, $amount, $color);
176
177 // ###################################################################
178 /**
179 * Fetches a color from the allocated color list and returns the value
180 *
181 * @return integer Allocated color resource
182 */
183 protected function _fetchColor()
184 {
185 static $colorlist = array(
186 array(100, 60, 175),
187 array(221, 110, 21),
188 array(179, 34, 31),
189 array(69, 196, 243),
190 array(128, 186, 33),
191 array(28, 101, 155),
192 array(246, 204, 95),
193 array(6, 43, 147),
194 array(204, 61, 7),
195 array(170, 169, 174),
196 array(90, 15, 24),
197 array(45, 130, 195)
198 );
199 static $allocated = 0;
200
201 $color = $colorlist["$allocated"];
202 $allocated++;
203
204 return imagecolorallocate($this->image, $color[0], $color[1], $color[2]);
205 }
206
207 // ###################################################################
208 /**
209 * Draws a white box, the title, and then a black border around the graph
210 */
211 protected function _paintCanvas()
212 {
213 $colors = $this->_primeColors();
214
215 // fill background
216 imagefill($this->image, 0, 0, $colors['white']);
217
218 // title the chart
219 imagestring($this->image, 5, ($this->dimensions['width'] - (imagefontwidth(5) * strlen($this->title))) / 2, self::PADDING, $this->title, $colors['black']);
220
221 // draw a border
222 imageline($this->image, 0, 0, 0, $this->dimensions['height'], $colors['black']); // left
223 imageline($this->image, 0, $this->dimensions['height'] - 1, $this->dimensions['width'], $this->dimensions['height'] - 1, $colors['black']); // bottom
224 imageline($this->image, $this->dimensions['width'] - 1, 0, $this->dimensions['width'] - 1, $this->dimensions['height'], $colors['black']); // right
225 imageline($this->image, 0, 0, $this->dimensions['width'], 0, $colors['black']); // top
226 }
227
228 // ###################################################################
229 /**
230 * Returns an array of colors that are useful (black, white, and grey)
231 *
232 * @return array Colors
233 */
234 protected function _primeColors()
235 {
236 $colors = array();
237 $colors['black'] = imagecolorallocate($this->image, 0, 0, 0);
238 $colors['white'] = imagecolorallocate($this->image, 255, 255, 255);
239 $colors['grey'] = imagecolorallocate($this->image, 121, 121, 123);
240 return $colors;
241 }
242
243 // ###################################################################
244 /**
245 * Runs the imagepng() function and returns the bytestream
246 *
247 * @return string Byte stream
248 */
249 protected function _imageFlush()
250 {
251 ob_start();
252 imagepng($this->image);
253 $data = ob_get_contents();
254 if ($data === false)
255 {
256 $data = ob_get_clean();
257 }
258 ob_clean();
259 ob_end_clean();
260 return $data;
261 }
262 }
263
264 ?>