]>
src.bluestatic.org Git - isso.git/blob - GraphLine.php
2 /*=====================================================================*
3 || ###################################################################
4 || # Blue Static ISSO Framework
5 || # Copyright (c)2002-2007 Blue Static
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.
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
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 \*=====================================================================*/
23 * Graphing System: Line Graph (GraphLine.php)
28 require_once('ISSO/Graph.php');
31 * Graphing System: Line Graph
33 * This creates a line graph from a set of data; each point requires
34 * a line name (because this supports multi-line graphing), an x-value,
35 * and a y-value. It creates PNG images.
38 * @copyright Copyright (c)2002 - 2007, Blue Static
42 class BSGraphLine
extends BSGraph
45 * Graphing dataset; 4D array
46 * array(array(name, array(array(xval, yval))), color)
49 protected $dataset = array();
52 * Array of data points that are used to calculate the standard deviation
55 private $piles = array(0 => array(), 1 => array());
58 * The names of the axes
61 private $axis = array(0 => 'X Axis', 1 => 'Y Axis');
64 * Number of ticks to display on the axes
69 // ###################################################################
71 * Does the actual graphing and returns a byte stream of a PNG image
73 * @return string Byte stream
75 public function graph()
77 $colors = $this->_primeColors();
78 $this->_paintCanvas();
81 $originx = self
::PADDING +
imagefontwidth(1) + self
::SPACING +
imagefontwidth(3) + self
::PADDING
;
82 $originy = $this->dimensions
['height'] - (self
::PADDING +
imagefontheight(1) + self
::SPACING +
imagefontheight(3) + self
::SPACING
);
83 $endx = $this->dimensions
['width'] - self
::PADDING
- 150 - self
::PADDING
;
85 $length = $endx - $originx;
86 $height = $originy - $endy;
87 imageline($this->image
, $originx, $originy, $endx, $originy, $colors['grey']);
88 imageline($this->image
, $originx, $originy, $originx, $endy, $colors['grey']);
90 // just to give us some padding
93 // calculates the standard deviation of the two piles to determine the x and y intervals
94 $xmin = min($this->piles
[0]);
95 $xmax = max($this->piles
[0]);
96 $xint = round(($xmax - $xmin) / $this->ticks
);
97 $xmin = ($xmin - $xint < 0 ? 0 : $xmin - $xint);
98 $xmax = $xmax +
$xint;
100 $ymin = min($this->piles
[1]);
101 $ymax = max($this->piles
[1]);
102 $yint = round(($ymax - $ymin) / $this->ticks
);
103 $ymin = ($ymin - $yint < 0 ? 0 : $ymin - $yint);
104 $ymax = $ymax +
$yint;
107 imagestring($this->image
, 3, $length / 2, $this->dimensions
['height'] - self
::SPACING
- imagefontheight(3), $this->axis
[0], $colors['black']);
108 imagestringup($this->image
, 3, self
::SPACING
, $height / 2 +
$endy, $this->axis
[1], $colors['black']);
112 for ($i = $originx; $i <= $endx; $i +
= ($length / $this->ticks
))
114 imageline($this->image
, $i - self
::SPACING
, $originy + self
::SPACING
, $i + self
::SPACING
, $originy - self
::SPACING
, $colors['grey']);
115 imagestring($this->image
, 1, $i, $originy + self
::PADDING
, round($count), $colors['black']);
119 for ($i = $originy; $i >= $endy; $i -= ($height / $this->ticks
))
121 imageline($this->image
, $originx, $i, $endx, $i, $colors['grey']);
122 imagestring($this->image
, 1, self
::SPACING + self
::SPACING + self
::PADDING + self
::SPACING
, $i - self
::SPACING
, round($count), $colors['black']);
127 $legy = $endy + self
::SPACING
; // "cursor" y-coord for the legend
128 $legx = $endx + self
::PADDING
; // x-coord for the legend BORDER
129 $legex = $this->dimensions
['width'] - self
::PADDING
; // end x-coord for the legend BORDER
130 imageline($this->image
, $legx, $endy, $legex, $endy, $colors['black']); // top legend border
132 // go through and plot each dataset
133 foreach ($this->dataset
AS $data)
135 // plot each point and connect the dots
137 foreach ($data[1] AS $points)
139 $xcord = $originx +
($points[0] * ($length / $xmax));
140 $ycord = $originy - ($points[1] * ($height / $ymax));
141 imagefilledellipse($this->image
, $xcord, $ycord, 5, 5, $data[2]);
144 imageline($this->image
, $xcord, $ycord, $oldpoint[0], $oldpoint[1], $data[2]);
146 $oldpoint = array($xcord, $ycord);
149 // draw the legend bit
151 $legx +
1 + self
::SPACING
, $legy, // top left
152 $legx +
1 + self
::SPACING
, $legy + self
::PADDING
, // bottom left
153 $legx +
11 + self
::SPACING
, $legy + self
::PADDING
, // bottom right
154 $legx +
11 + self
::SPACING
, $legy // top right
156 imagefilledpolygon($this->image
, $box, 4, $data[2]);
157 imagestring($this->image
, 2, $legx +
11 + self
::SPACING + self
::SPACING
, $legy - 1, $data[0], $colors['black']);
158 $legy +
= self
::PADDING + self
::SPACING
;
161 // finish the legend border
162 imageline($this->image
, $legx, $legy, $legex, $legy, $colors['black']); // bottom
163 imageline($this->image
, $legx, $endy, $legx, $legy, $colors['black']); // left
164 imageline($this->image
, $legex, $endy, $legex, $legy, $colors['black']); // right
166 return $this->_imageFlush();
169 // ###################################################################
171 * Adds a "line" with a given name and a set of datapoints in the form
174 * @param string The line's name
175 * @param array Array of array(x,y) as data points
177 public function addDataSet($name, $points)
179 $this->_addPoints($points);
180 $this->_sortPoints($points);
181 $this->dataset
[] = array($name, $points, $this->_fetchColor());
184 // ###################################################################
186 * This does the same thing as addDataSet(), except the client code
187 * can specify the color in the form of array(R, G, B)
189 * @param string The line's name
190 * @param array Array of array(x,y) as data points
191 * @param array A color in the form of 3 RGB points
193 public function addDataSetColor($name, $points, $color)
195 $this->_addPoints($points);
196 $this->_sortPoints($points);
197 $this->dataset
[] = array($name, $points, imagecolorallocate($this->image
, $color[0], $color[1], $color[2]));
200 // ###################################################################
202 * Adds a set of points to the piles and ensures that they are all valid
204 * @param array Points to add
206 private function _addPoints($points)
209 foreach ($points AS $point)
211 if (isset($xpairs["$point[0]"]))
213 trigger_error('You cannot have more than one of the same x-values for a given data set');
215 $xpairs["$point[0]"] = $point[0];
216 $this->piles
[0][] = $point[0];
217 $this->piles
[1][] = $point[1];
221 // ###################################################################
223 * Sorts an array of points using quick sort so they're in x-increasing
226 * @param array Array of points
228 private function _sortPoints(&$points)
230 $this->_quickSortPoints($points, 0, sizeof($points) - 1);
233 // ###################################################################
235 * Quicksort function for sorting function
237 * @param array Array of points
238 * @param integer Lower bound
239 * @param integer Upper bound
241 private function _quickSortPoints(&$points, $low, $high)
243 if (($high - $low) > 1)
245 $partition = $this->_partitionPoints($points, $low, $high);
246 $this->_quickSortPoints($points, $low, $partition);
247 $this->_quickSortPoints($points, $partition +
1, $high);
251 // ###################################################################
253 * Quicksort partitioner: returns the index of the pivot element where
254 * all x-coords on the left side of pivot are less than or equal to
255 * pivot, and all x-coords are higher to the right
257 * @param array Array of points
258 * @param integer Lower bound
259 * @param integer Upper bound
261 * @return integer Pivot index
263 private function _partitionPoints(&$points, $low, $high)
266 for ($unsorted = $low +
1; $unsorted <= $high; $unsorted++
)
268 if ($points[$unsorted][0] < $points[$pivot][0])
270 $temp = $points[$pivot];
271 $points[$pivot] = $points[$unsorted];
272 $points[$unsorted] = $points[$pivot +
1];
273 $points[$pivot +
1] = $temp;
280 // ###################################################################
282 * Sets the titles of the two axes
284 * @param string X-axis name
285 * @param string Y-axis name
287 public function setAxes($xaxis, $yaxis)
289 $this->axis
[0] = $xaxis;
290 $this->axis
[1] = $yaxis;