2 /*=====================================================================*
3 || ###################################################################
4 || # Blue Static ISSO Framework
5 || # Copyright ©2002-[#]year[#] 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 [#]gpl[#] 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 - [#]year[#], Blue Static
43 class BSGraphLine
extends BSGraph
46 * Graphing dataset; 4D array
47 * array(array(name, array(array(xval, yval))), color)
50 protected $dataset = array();
53 * Array of data points that are used to calculate the standard deviation
56 private $piles = array(0 => array(), 1 => array());
58 // ###################################################################
60 * Does the actual graphing and returns a byte stream of a PNG image
62 * @return string Byte stream
64 public function graph()
66 // calculates the standard deviation of the two piles to determine the x and y intervals
67 $xint = $this->_standardDeviation($this->piles
[0]);
68 $yint = $this->_standardDeviation($this->piles
[1]);
70 $xmin = min($this->piles
[0]);
71 $xmin = ($xmin - $xint < 0 ?
0 : $xmin - $xint);
72 $xmax = max($this->piles
[0]) +
$xint;
74 $ymin = min($this->piles
[1]);
75 $ymin = ($ymin - $int < 0 ?
0 : $ymin - $yint);
76 $ymax = max($this->piles
[1]) +
$yint;
81 // ###################################################################
83 * Adds a "line" with a given name and a set of datapoints in the form
86 * @param string The line's name
87 * @param array Array of array(x,y) as data points
89 public function addDataSet($name, $points)
91 $this->_addPoints($points);
92 $this->_sortPoints($points);
93 $this->dataset
[] = array($name, $points, $this->_fetchColor());
96 // ###################################################################
98 * This does the same thing as addDataSet(), except the client code
99 * can specify the color in the form of array(R, G, B)
101 * @param string The line's name
102 * @param array Array of array(x,y) as data points
103 * @param array A color in the form of 3 RGB points
105 public function addDataSetColor($name, $points, $color)
107 $this->_addPoints($points);
108 $this->_sortPoints($points);
109 $this->dataset
[] = array($name, $points, imagecolorallocate($this->image
, $color[0], $color[1], $color[2]));
112 // ###################################################################
114 * Adds a set of points to the piles and ensures that they are all valid
116 * @param array Points to add
118 private function _addPoints($points)
121 foreach ($points AS $point)
123 if (isset($xpairs["$point[0]"]))
125 trigger_error('You cannot have more than one of the same x-values for a given data set');
127 $xpairs["$point[0]"] = $point[0];
128 $this->piles
[0][] = $point[0];
129 $this->piles
[1][] = $point[1];
133 // ###################################################################
135 * Sorts an array of points using quick sort so they're in x-increasing
138 * @param array Array of points
140 private function _sortPoints(&$points)
142 $this->_quickSortPoints($points, 0, sizeof($points) - 1);
145 // ###################################################################
147 * Quicksort function for sorting function
149 * @param array Array of points
150 * @param integer Lower bound
151 * @param integer Upper bound
153 private function _quickSortPoints(&$points, $low, $high)
155 if (($high - $low) > 1)
157 $partition = $this->_partitionPoints($points, $low, $high);
158 $this->_quickSortPoints($points, $low, $partition);
159 $this->_quickSortPoints($points, $partition +
1, $high);
163 // ###################################################################
165 * Quicksort partitioner: returns the index of the pivot element where
166 * all x-coords on the left side of pivot are less than or equal to
167 * pivot, and all x-coords are higher to the right
169 * @param array Array of points
170 * @param integer Lower bound
171 * @param integer Upper bound
173 * @return integer Pivot index
175 private function _partitionPoints(&$points, $low, $high)
178 for ($unsorted = $low +
1; $unsorted <= $high; $unsorted++
)
180 if ($points[$unsorted][0] < $points[$pivot][0])
182 $temp = $points[$pivot];
183 $points[$pivot] = $points[$unsorted];
184 $points[$unsorted] = $points[$pivot +
1];
185 $points[$pivot +
1] = $temp;
192 // ###################################################################
194 * Returns the unbiased statistical standard deviation of an array of
197 * @param array Array of values
199 * @return float Standard deviation (unbiased)
201 private function _standardDeviation($vals)
203 $average = $this->_arrayAverage($vals);
204 $popVariance = array();
206 foreach ($vals AS $val)
208 $popVariance[] = pow($val - $average, 2);
211 return sqrt($this->_arrayAverage($popVariance));
214 // ###################################################################
216 * Returns the stastical mean of an array of values
218 * @param array Array of values
220 * @return float Statistical mean
222 private function _arrayAverage($vals)
224 return array_sum($vals) / count($vals);
228 /*=====================================================================*
229 || ###################################################################
232 || ###################################################################
233 \*=====================================================================*/