1<?php 2/** 3 * pData - Simplifying data population for pChart 4 * 5 * @copyright 2008 Jean-Damien POGOLOTTI 6 * @version 2.0 7 * 8 * http://pchart.sourceforge.net 9 * 10 * This program is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation, either version 1,2,3 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 25class pData { 26 private $Data = array(); 27 private $dataDescription = array(); 28 29 /** 30 * An entry for each series giving the maximum value in that 31 * series, if we've previously calculated it 32 */ 33 private $seriesMinimums = array(); 34 35 /** 36 * An entry for each series giving the minimum value in that 37 * series, if we've previously calculated it 38 */ 39 private $seriesMaximums = array(); 40 41 public function __construct() { 42 $this->dataDescription = new DataDescription('Name', 43 'number', 'number', 44 null, null); 45 } 46 47 /** 48 * Add a single point to the data set 49 */ 50 public function addPoint($value, $series = "Series1", $Description = "") { 51 if(is_array($value)) { 52 throw new InvalidArgumentException("Can't pass an array to addPoint()"); 53 } 54 55 return $this->addPoints( 56 array($value), 57 $series, 58 $Description 59 ); 60 } 61 62 /** 63 * Add an array of one or more points to the data set. 64 * 65 * @param $Value If this is an associative array the key values 66 * are ignored. The members of the array are added sequentially to 67 * the data set, taking on auto-incremented ID values based on the 68 * current state of the data set. 69 */ 70 public function addPoints(array $Value, $Serie = "Series1", $Description = "") { 71 $ID = 0; 72 for($i = 0; $i < count($this->Data); $i++) { 73 if(isset ($this->Data [$i] [$Serie])) { 74 $ID = $i + 1; 75 } 76 } 77 78 foreach($Value as $Val) { 79 $this->Data [$ID] [$Serie] = $Val; 80 if($Description != "") { 81 $this->Data[$ID]["Name"] = $Description; 82 } elseif(!isset ($this->Data [$ID] ["Name"])) { 83 $this->Data [$ID] ["Name"] = $ID; 84 } 85 $ID++; 86 } 87 } 88 89 public function addSeries($SerieName = "Series1") { 90 if(!isset($this->dataDescription->values)) { 91 $this->dataDescription->values[] = $SerieName; 92 } else { 93 $Found = FALSE; 94 foreach($this->dataDescription->values as $Value) 95 if($Value == $SerieName) { 96 $Found = TRUE; 97 } 98 99 if(!$Found) 100 $this->dataDescription->values[] = $SerieName; 101 } 102 } 103 104 public function addAllSeries() { 105 unset($this->dataDescription->values); 106 107 if(isset ($this->Data [0])) { 108 foreach(array_keys($this->Data [0]) as $Key) { 109 if($Key != "Name") { 110 $this->dataDescription->values[] = $Key; 111 } 112 } 113 } 114 } 115 116 public function removeSeries($SerieName = "Series1") { 117 if(!isset($this->dataDescription->values)) 118 return; 119 120 foreach($this->dataDescription->values as $key => $Value) { 121 if($Value == $SerieName) 122 unset ($this->dataDescription->values[$key]); 123 } 124 } 125 126 public function setAbscissaLabelSeries($seriesName = "Name") { 127 $this->dataDescription->setPosition($seriesName); 128 } 129 130 public function setSeriesName($Name, $SeriesName = "Series1") { 131 $this->dataDescription->description[$SeriesName] = $Name; 132 } 133 134 public function setXAxisName($Name) { 135 $this->dataDescription->setXAxisName($Name); 136 } 137 138 public function setYAxisName($Name) { 139 $this->dataDescription->setYAxisName($Name); 140 } 141 142 public function setSeriesSymbol($Name, $Symbol) { 143 $this->dataDescription->seriesSymbols[$Name] = $Symbol; 144 } 145 146 /** 147 * @param unknown_type $SerieName 148 */ 149 public function removeSeriesName($SerieName) { 150 if(isset ($this->dataDescription->description[$SerieName])) 151 unset ($this->dataDescription->description[$SerieName]); 152 } 153 154 public function removeAllSeries() { 155 $this->dataDescription->values = array(); 156 } 157 158 public function getData() { 159 return $this->Data; 160 } 161 162 public function getDataDescription() { 163 return $this->dataDescription; 164 } 165 166 /** 167 * @brief Get the minimum data value in the specified series 168 */ 169 public function getSeriesMin($seriesName) { 170 if(isset($this->seriesMinimums[$seriesName])) { 171 return $this->seriesMinimums[$seriesName]; 172 } 173 174 /** 175 * @todo This algorithm assumes that the data set contains a 176 * value at index 0 for the specified series - but this is the 177 * way it's always worked. 178 */ 179 $this->seriesMinimums[$seriesName] = $this->Data[0][$seriesName]; 180 181 foreach($this->Data as $valueSet) { 182 if(isset($valueSet[$seriesName])) { 183 $this->seriesMinimums[$seriesName] = 184 min( 185 $this->seriesMinimums[$seriesName], 186 $valueSet[$seriesName] 187 ); 188 } 189 } 190 191 return $this->seriesMinimums[$seriesName]; 192 } 193 194 /** 195 * @brief Get the maximum data value in the specified series 196 */ 197 public function getSeriesMax($seriesName) { 198 $this->seriesMaximums[$seriesName] = $this->Data[0][$seriesName]; 199 200 foreach($this->Data as $valueSet) { 201 if(isset($valueSet[$seriesName])) { 202 $this->seriesMaximums[$seriesName] = 203 max( 204 $this->seriesMaximums[$seriesName], 205 $valueSet[$seriesName] 206 ); 207 } 208 } 209 210 return $this->seriesMaximums[$seriesName]; 211 } 212 213 /** 214 * Get the numeric X and Y values, for a given series. 215 * 216 * Ugly interface, but this is a step towards refactoring 217 * duplicated code 218 * 219 * For some reason, the data set is assumed to start at (0, 0). 220 * 221 * @param[out] $xIn Returns an array of numeric X values 222 * @param[out] $yIn Returns an array of Y values, corresponding 223 * to the array of X values. Non-numeric values are omitted 224 * 225 * @param $index Returns the number of values in the specified 226 * data set, including any non-numeric values (thus this is not 227 * necessarily equal to the size of the $xIn or $yIn arrays), minus 228 * one (to account for the bogus (0, 0) value added to the X and Y 229 * arrays?) 230 * 231 * @param $missing Returns the X values for which no Y value is 232 * available. The missing keys form the keys of the $missing array, 233 * and the corresponding value in the associative array is always 234 * true 235 * 236 * @return Null 237 */ 238 public function getXYMap($colName, array &$xIn, array & $yIn, array & $missing, & $index) { 239 $xIn [0] = 0; 240 $yIn [0] = 0; 241 242 $index = 1; 243 244 foreach(array_keys($this->Data) as $Key) { 245 if(isset ($this->Data[$Key] [$colName])) { 246 $Value = $this->Data[$Key] [$colName]; 247 $xIn [$index] = $index; 248 $yIn [$index] = $Value; 249 if(!is_numeric($Value)) { 250 $missing [$index] = TRUE; 251 } 252 $index++; 253 } 254 } 255 $index--; 256 } 257}