Removing the PHP4 constructors
[isso.git] / graph_pie.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Blue Static ISSO Framework [#]issoversion[#]
5 || # Copyright ©2002-[#]year[#] 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 [#]gpl[#] 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: pie chart
24 * graph_pie.php
25 *
26 * @package ISSO
27 */
28
29 /**
30 * Graphing System: Pie Chart
31 *
32 * This framework creates pie charts as PNG image strings. Simply add to
33 * the data set and graph to get the byte stream returned.
34 *
35 * @author Blue Static
36 * @copyright Copyright ©2002 - [#]year[#], Blue Static
37 * @version $Revision$
38 * @package ISSO
39 *
40 */
41 class Graph_Pie
42 {
43 /**
44 * Framework registry object
45 * @var object
46 */
47 private $registry = null;
48
49 /**
50 * Graphing data set; 2D array of
51 * array(NAME, PERCENT, COLOR)
52 * @var array
53 */
54 private $dataset = array();
55
56 /**
57 * Image resource
58 * @var resource
59 */
60 private $image = null;
61
62 /**
63 * The dimensions of the image
64 * @var array
65 */
66 private $dimensions = array('width' => 550, 'height' => 350);
67
68 /**
69 * Add a legend to the graph
70 * @var bool
71 */
72 private $legend = true;
73
74 /**
75 * Title of the graph
76 * @var string
77 */
78 private $title = 'ISSO Pie Chart';
79
80 // ###################################################################
81 /**
82 * Constructor
83 */
84 function __construct(&$registry)
85 {
86 $this->registry =& $registry;
87
88 $this->set_scale(0);
89 }
90
91 // ###################################################################
92 /**
93 * Graphs the actual graph and returns a byte stream
94 *
95 * @access public
96 *
97 * @return string Byte stream
98 */
99 function graph()
100 {
101 $colours['black'] = imagecolorallocate($this->image, 0, 0, 0);
102 $colours['white'] = imagecolorallocate($this->image, 255, 255, 255);
103 $colours['grey'] = imagecolorallocate($this->image, 121, 121, 123);
104
105 $graphpadding = 10;
106 $graphspacing = 4;
107 $diameter = $this->dimensions['height'] - (5 * $graphpadding);
108 $radius = $diameter / 2;
109 $graphstart = $graphpadding + imagefontheight(5) + $graphpadding;
110 $legendbox = 10;
111
112 // fill background
113 imagefill($this->image, 0, 0, $colours['white']);
114
115 // title the chart
116 imagestring($this->image, 5, ($this->dimensions['width'] - (imagefontwidth(5) * strlen($this->title))) / 2, $graphpadding, $this->title, $colours['black']);
117
118 $center = array(
119 'x' => ($this->legend ? ($radius + $graphpadding) : ($this->dimensions['width'] / 2)),
120 'y' => ($this->dimensions['height'] / 2) + $graphpadding
121 );
122
123 // draw a border
124 imageline($this->image, 0, 0, 0, $this->dimensions['height'], $colours['black']); // left
125 imageline($this->image, 0, $this->dimensions['height'] - 1, $this->dimensions['width'], $this->dimensions['height'] - 1, $colours['black']); // bottom
126 imageline($this->image, $this->dimensions['width'] - 1, 0, $this->dimensions['width'] - 1, $this->dimensions['height'], $colours['black']); // right
127 imageline($this->image, 0, 0, $this->dimensions['width'], 0, $colours['black']); // top
128
129 $legx = (2 * $graphpadding) + $diameter;
130
131 $lastdeg = 0;
132 $boxoffset = 0;
133 foreach ($this->dataset AS $plot)
134 {
135 $deg = (360 / 100) * $plot[1];
136 imagefilledarc($this->image, $center['x'], $center['y'], $diameter, $diameter, $lastdeg, $deg + $lastdeg, $plot[2], IMG_ARC_PIE);
137 imagefilledarc($this->image, $center['x'], $center['y'], $diameter, $diameter, $lastdeg, $deg + $lastdeg, $colours['grey'], IMG_ARC_EDGED | IMG_ARC_NOFILL);
138 $lastdeg += $deg;
139
140 if ($this->legend)
141 {
142 $box = array(
143 $legx + 1 + $graphspacing, $graphstart + 1 + $graphspacing + $boxoffset, // top left
144 $legx + 1 + $graphspacing, $graphstart + 1 + $graphspacing + $boxoffset + $legendbox, // bottom left
145 $legx + 1 + $graphspacing + $legendbox, $graphstart + 1 + $graphspacing + $boxoffset + $legendbox, // bottom right
146 $legx + 1 + $graphspacing + $legendbox, $graphstart + 1 + $graphspacing + $boxoffset // top right
147 );
148 imagefilledpolygon($this->image, $box, 4, $plot[2]);
149
150 imagestring($this->image, 2, ($legx + 1 + $graphspacing + $legendbox + $graphspacing), ($graphstart + $graphspacing + $boxoffset), $plot[0] . " ($plot[1]%)", $colours['black']);
151
152 $boxoffset += $graphspacing + $legendbox;
153 }
154 }
155
156 // draw the ellipse (do here so it cleans up the arc edges)
157 imageellipse($this->image, $center['x'], $center['y'], $diameter, $diameter, $colours['grey']);
158
159 // do the legend
160 if ($this->legend)
161 {
162 imageline($this->image, $legx, $graphstart, $this->dimensions['width'] - $graphpadding, $graphstart, $colours['black']); // top
163 imageline($this->image, $legx, $graphstart, $legx, $legy = ($graphstart + $graphspacing + $boxoffset + 1), $colours['black']); // left
164 imageline($this->image, $legx, $legy, $this->dimensions['width'] - $graphpadding, $legy, $colours['black']); // bottom
165 imageline($this->image, $this->dimensions['width'] - $graphpadding, $graphstart, $this->dimensions['width'] - $graphpadding, $legy, $colours['black']); // right
166 }
167
168 ob_start();
169 imagepng($this->image);
170 $data = ob_get_contents();
171 if ($data === false)
172 {
173 $data = ob_get_clean();
174 }
175 ob_clean();
176 ob_end_clean();
177
178 return $data;
179 }
180
181 // ###################################################################
182 /**
183 * Sets the width and height by using scale factors of 550x350; you
184 * can specify a positive value to multiply by that many times or a
185 * negative one to divide
186 *
187 * @access public
188 *
189 * @param float Scale factor
190 */
191 function set_scale($scale)
192 {
193 $this->dimensions['width'] = 550;
194 $this->dimensions['height'] = 350;
195
196 if ($scale > 0)
197 {
198 $this->dimensions['width'] *= $scale;
199 $this->dimensions['height'] *= $scale;
200 }
201 else if ($scale < 0)
202 {
203 $scale = abs($scale);
204 $this->dimensions['width'] /= $scale;
205 $this->dimensions['height'] /= $scale;
206 }
207
208 if (!is_null($this->image))
209 {
210 imagedestroy($this->image);
211 }
212
213 $this->image = imagecreate($this->dimensions['width'], $this->dimensions['height']);
214 }
215
216 // ###################################################################
217 /**
218 * Sets whether or not a legend is created for the graph
219 *
220 * @access public
221 *
222 * @param bool Draw a legend?
223 */
224 function set_legend($yesno)
225 {
226 $this->legend = (bool)$yesno;
227 }
228
229 // ###################################################################
230 /**
231 * Sets the title of the chart to be drawn above the graph
232 *
233 * @access public
234 *
235 * @param string Title of the chart
236 */
237 function set_title($title)
238 {
239 $this->title = $title;
240 }
241
242 // ###################################################################
243 /**
244 * Adds an entry to the data set without specifying a colour to add.
245 * This is the standard method as the colour should only be overridden
246 * if necessary.
247 *
248 * @access public
249 *
250 * @param string Data column name
251 * @param integer Percentage of 100
252 */
253 function add_data_set($name, $percent)
254 {
255 $this->dataset[] = array($name, intval($percent), $this->fetch_colour());
256 }
257
258 // ###################################################################
259 /**
260 * Adds an entry ot the data set with specifying a colour. This works
261 * the same as add_data_st() but requires an array() as the 3rd parameter
262 * of R,G,B values
263 *
264 * @access public
265 *
266 * @param string Data column name
267 * @param integer Percent of 100
268 * @param array Array of R,G,B values
269 */
270 function add_data_set_colour($name, $percent, $colour)
271 {
272 $this->dataset[] = array($name, intval($percent), imagecolorallocate($this->image, $colour[0], $colour[1], $colour[2]));
273 }
274
275 // ###################################################################
276 /**
277 * Fetches a colour from the allocated colour list and returns the value
278 *
279 * @access private
280 *
281 * @return integer Allocated colour resource
282 */
283 function fetch_colour()
284 {
285 static $colourlist = array(
286 array(100, 60, 175),
287 array(221, 110, 21),
288 array(179, 34, 31),
289 array(69, 196, 243),
290 array(128, 186, 33),
291 array(28, 101, 155),
292 array(246, 204, 95),
293 array(6, 43, 147),
294 array(204, 61, 7),
295 array(170, 169, 174),
296 array(90, 15, 24),
297 array(45, 130, 195)
298 );
299 static $allocated = 0;
300
301 $colour = $colourlist["$allocated"];
302 $allocated++;
303
304 return imagecolorallocate($this->image, $colour[0], $colour[1], $colour[2]);
305 }
306 }
307
308 /*=====================================================================*\
309 || ###################################################################
310 || # $HeadURL$
311 || # $Id$
312 || ###################################################################
313 \*=====================================================================*/
314 ?>