array(), 1 => array()); // ################################################################### /** * Does the actual graphing and returns a byte stream of a PNG image * * @return string Byte stream */ public function graph() { // calculates the standard deviation of the two piles to determine the x and y intervals $xint = $this->_standardDeviation($this->piles[0]); $yint = $this->_standardDeviation($this->piles[1]); $xmin = min($this->piles[0]); $xmin = ($xmin - $xint < 0 ? 0 : $xmin - $xint); $xmax = max($this->piles[0]) + $xint; $ymin = min($this->piles[1]); $ymin = ($ymin - $int < 0 ? 0 : $ymin - $yint); $ymax = max($this->piles[1]) + $yint; } // ################################################################### /** * Adds a "line" with a given name and a set of datapoints in the form * array(x, y) * * @param string The line's name * @param array Array of array(x,y) as data points */ public function addDataSet($name, $points) { $this->_addPoints($points); $this->_sortPoints($points); $this->dataset[] = array($name, $points, $this->_fetchColor()); } // ################################################################### /** * This does the same thing as addDataSet(), except the client code * can specify the color in the form of array(R, G, B) * * @param string The line's name * @param array Array of array(x,y) as data points * @param array A color in the form of 3 RGB points */ public function addDataSetColor($name, $points, $color) { $this->_addPoints($points); $this->_sortPoints($points); $this->dataset[] = array($name, $points, imagecolorallocate($this->image, $color[0], $color[1], $color[2])); } // ################################################################### /** * Adds a set of points to the piles and ensures that they are all valid * * @param array Points to add */ private function _addPoints($points) { $xpairs = array(); foreach ($points AS $point) { if (isset($xpairs["$point[0]"])) { trigger_error('You cannot have more than one of the same x-values for a given data set'); } $xpairs["$point[0]"] = $point[0]; $this->piles[0][] = $point[0]; $this->piles[1][] = $point[1]; } } // ################################################################### /** * Sorts an array of points using quick sort so they're in x-increasing * order * * @param array Array of points */ private function _sortPoints(&$points) { $this->_quickSortPoints($points, 0, sizeof($points) - 1); } // ################################################################### /** * Quicksort function for sorting function * * @param array Array of points * @param integer Lower bound * @param integer Upper bound */ private function _quickSortPoints(&$points, $low, $high) { if (($high - $low) > 1) { $partition = $this->_partitionPoints($points, $low, $high); $this->_quickSortPoints($points, $low, $partition); $this->_quickSortPoints($points, $partition + 1, $high); } } // ################################################################### /** * Quicksort partitioner: returns the index of the pivot element where * all x-coords on the left side of pivot are less than or equal to * pivot, and all x-coords are higher to the right * * @param array Array of points * @param integer Lower bound * @param integer Upper bound * * @return integer Pivot index */ private function _partitionPoints(&$points, $low, $high) { $pivot = $low; for ($unsorted = $low + 1; $unsorted <= $high; $unsorted++) { if ($points[$unsorted][0] < $points[$pivot][0]) { $temp = $points[$pivot]; $points[$pivot] = $points[$unsorted]; $points[$unsorted] = $points[$pivot + 1]; $points[$pivot + 1] = $temp; $pivot++; } } return $pivot; } // ################################################################### /** * Returns the unbiased statistical standard deviation of an array of * values * * @param array Array of values * * @return float Standard deviation (unbiased) */ private function _standardDeviation($vals) { $average = $this->_arrayAverage($vals); $popVariance = array(); foreach ($vals AS $val) { $popVariance[] = pow($val - $average, 2); } return sqrt($this->_arrayAverage($popVariance)); } // ################################################################### /** * Returns the stastical mean of an array of values * * @param array Array of values * * @return float Statistical mean */ private function _arrayAverage($vals) { return array_sum($vals) / count($vals); } } /*=====================================================================* || ################################################################### || # $HeadURL$ || # $Id$ || ################################################################### \*=====================================================================*/ ?>