pData.class.php

File

inc/pchart/pchart/class/pData.class.php
View source
  1. /*
  2. pDraw - class to manipulate data arrays
  3. Version : 2.1.4
  4. Made by : Jean-Damien POGOLOTTI
  5. Last Update : 19/01/2014
  6. This file can be distributed under the license you can find at :
  7. http://www.pchart.net/license
  8. You can find the whole class documentation on the pChart web site.
  9. */
  10. /* Axis configuration */
  11. define("AXIS_FORMAT_DEFAULT" , 680001);
  12. define("AXIS_FORMAT_TIME" , 680002);
  13. define("AXIS_FORMAT_DATE" , 680003);
  14. define("AXIS_FORMAT_METRIC" , 680004);
  15. define("AXIS_FORMAT_CURRENCY" , 680005);
  16. define("AXIS_FORMAT_TRAFFIC" , 680006);
  17. define("AXIS_FORMAT_CUSTOM" , 680007);
  18. /* Axis position */
  19. define("AXIS_POSITION_LEFT" , 681001);
  20. define("AXIS_POSITION_RIGHT" , 681002);
  21. define("AXIS_POSITION_TOP" , 681001);
  22. define("AXIS_POSITION_BOTTOM" , 681002);
  23. /* Families of data points */
  24. define("SERIE_SHAPE_FILLEDCIRCLE" , 681011);
  25. define("SERIE_SHAPE_FILLEDTRIANGLE" , 681012);
  26. define("SERIE_SHAPE_FILLEDSQUARE" , 681013);
  27. define("SERIE_SHAPE_FILLEDDIAMOND" , 681017);
  28. define("SERIE_SHAPE_CIRCLE" , 681014);
  29. define("SERIE_SHAPE_TRIANGLE" , 681015);
  30. define("SERIE_SHAPE_SQUARE" , 681016);
  31. define("SERIE_SHAPE_DIAMOND" , 681018);
  32. /* Axis position */
  33. define("AXIS_X" , 682001);
  34. define("AXIS_Y" , 682002);
  35. /* Define value limits */
  36. define("ABSOLUTE_MIN" , -10000000000000);
  37. define("ABSOLUTE_MAX" , 10000000000000);
  38. /* Replacement to the PHP NULL keyword */
  39. define("VOID" , 0.123456789);
  40. /* Euro symbol for GD fonts */
  41. define("EURO_SYMBOL" , utf8_encode("€"));
  42. /* pData class definition */
  43. class pData
  44. {
  45. var $Data = array();
  46. var $Palette = array("0"=>array("R"=>188,"G"=>224,"B"=>46,"Alpha"=>100),
  47. "1"=>array("R"=>224,"G"=>100,"B"=>46,"Alpha"=>100),
  48. "2"=>array("R"=>224,"G"=>214,"B"=>46,"Alpha"=>100),
  49. "3"=>array("R"=>46,"G"=>151,"B"=>224,"Alpha"=>100),
  50. "4"=>array("R"=>176,"G"=>46,"B"=>224,"Alpha"=>100),
  51. "5"=>array("R"=>224,"G"=>46,"B"=>117,"Alpha"=>100),
  52. "6"=>array("R"=>92,"G"=>224,"B"=>46,"Alpha"=>100),
  53. "7"=>array("R"=>224,"G"=>176,"B"=>46,"Alpha"=>100));
  54. /* Class creator */
  55. function pData()
  56. {
  57. $this->Data = array();
  58. $this->Data["XAxisDisplay"] = AXIS_FORMAT_DEFAULT;
  59. $this->Data["XAxisFormat"] = NULL;
  60. $this->Data["XAxisName"] = NULL;
  61. $this->Data["XAxisUnit"] = NULL;
  62. $this->Data["Abscissa"] = NULL;
  63. $this->Data["AbsicssaPosition"] = AXIS_POSITION_BOTTOM;
  64. $this->Data["Axis"][0]["Display"] = AXIS_FORMAT_DEFAULT;
  65. $this->Data["Axis"][0]["Position"] = AXIS_POSITION_LEFT;
  66. $this->Data["Axis"][0]["Identity"] = AXIS_Y;
  67. }
  68. /* Add a single point or an array to the given serie */
  69. function addPoints($Values,$SerieName="Serie1")
  70. {
  71. if (!isset($this->Data["Series"][$SerieName]))
  72. $this->initialise($SerieName);
  73. if ( is_array($Values) )
  74. {
  75. foreach($Values as $Key => $Value)
  76. { $this->Data["Series"][$SerieName]["Data"][] = $Value; }
  77. }
  78. else
  79. $this->Data["Series"][$SerieName]["Data"][] = $Values;
  80. if ( $Values != VOID )
  81. {
  82. $StrippedData = $this->stripVOID($this->Data["Series"][$SerieName]["Data"]);
  83. if ( empty($StrippedData) ) { $this->Data["Series"][$SerieName]["Max"] = 0; $this->Data["Series"][$SerieName]["Min"] =0; return(0); }
  84. $this->Data["Series"][$SerieName]["Max"] = max($StrippedData);
  85. $this->Data["Series"][$SerieName]["Min"] = min($StrippedData);
  86. }
  87. }
  88. /* Strip VOID values */
  89. function stripVOID($Values)
  90. { if (!is_array($Values)) { return(array()); } $Result = array(); foreach($Values as $Key => $Value) { if ( $Value != VOID ) { $Result[] = $Value; } } return($Result); }
  91. /* Return the number of values contained in a given serie */
  92. function getSerieCount($Serie)
  93. { if (isset($this->Data["Series"][$Serie]["Data"])) { return(sizeof($this->Data["Series"][$Serie]["Data"])); } else { return(0); } }
  94. /* Remove a serie from the pData object */
  95. function removeSerie($Series)
  96. {
  97. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  98. foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie])) { unset($this->Data["Series"][$Serie]); } }
  99. }
  100. /* Return a value from given serie & index */
  101. function getValueAt($Serie,$Index=0)
  102. { if (isset($this->Data["Series"][$Serie]["Data"][$Index])) { return($this->Data["Series"][$Serie]["Data"][$Index]); } else { return(NULL); } }
  103. /* Return the values array */
  104. function getValues($Serie)
  105. { if (isset($this->Data["Series"][$Serie]["Data"])) { return($this->Data["Series"][$Serie]["Data"]); } else { return(NULL); } }
  106. /* Reverse the values in the given serie */
  107. function reverseSerie($Series)
  108. {
  109. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  110. foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]["Data"])) { $this->Data["Series"][$Serie]["Data"] = array_reverse($this->Data["Series"][$Serie]["Data"]); } }
  111. }
  112. /* Return the sum of the serie values */
  113. function getSum($Serie)
  114. { if (isset($this->Data["Series"][$Serie])) { return(array_sum($this->Data["Series"][$Serie]["Data"])); } else { return(NULL); } }
  115. /* Return the max value of a given serie */
  116. function getMax($Serie)
  117. { if (isset($this->Data["Series"][$Serie]["Max"])) { return($this->Data["Series"][$Serie]["Max"]); } else { return(NULL); } }
  118. /* Return the min value of a given serie */
  119. function getMin($Serie)
  120. { if (isset($this->Data["Series"][$Serie]["Min"])) { return($this->Data["Series"][$Serie]["Min"]); } else { return(NULL); } }
  121. /* Set the description of a given serie */
  122. function setSerieShape($Series,$Shape=SERIE_SHAPE_FILLEDCIRCLE)
  123. {
  124. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  125. foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Shape"] = $Shape; } }
  126. }
  127. /* Set the description of a given serie */
  128. function setSerieDescription($Series,$Description="My serie")
  129. {
  130. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  131. foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Description"] = $Description; } }
  132. }
  133. /* Set a serie as "drawable" while calling a rendering function */
  134. function setSerieDrawable($Series,$Drawable=TRUE)
  135. {
  136. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  137. foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["isDrawable"] = $Drawable; } }
  138. }
  139. /* Set the icon associated to a given serie */
  140. function setSeriePicture($Series,$Picture=NULL)
  141. {
  142. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  143. foreach($Series as $Key => $Serie) { if (isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Picture"] = $Picture; } }
  144. }
  145. /* Set the name of the X Axis */
  146. function setXAxisName($Name)
  147. { $this->Data["XAxisName"] = $Name; }
  148. /* Set the display mode of the X Axis */
  149. function setXAxisDisplay($Mode,$Format=NULL)
  150. { $this->Data["XAxisDisplay"] = $Mode; $this->Data["XAxisFormat"] = $Format; }
  151. /* Set the unit that will be displayed on the X axis */
  152. function setXAxisUnit($Unit)
  153. { $this->Data["XAxisUnit"] = $Unit; }
  154. /* Set the serie that will be used as abscissa */
  155. function setAbscissa($Serie)
  156. { if (isset($this->Data["Series"][$Serie])) { $this->Data["Abscissa"] = $Serie; } }
  157. function setAbsicssaPosition($Position = AXIS_POSITION_BOTTOM)
  158. { $this->Data["AbsicssaPosition"] = $Position; }
  159. /* Set the name of the abscissa axis */
  160. function setAbscissaName($Name)
  161. { $this->Data["AbscissaName"] = $Name; }
  162. /* Create a scatter group specifyin X and Y data series */
  163. function setScatterSerie($SerieX,$SerieY,$ID=0)
  164. { if (isset($this->Data["Series"][$SerieX]) && isset($this->Data["Series"][$SerieY]) ) { $this->initScatterSerie($ID); $this->Data["ScatterSeries"][$ID]["X"] = $SerieX; $this->Data["ScatterSeries"][$ID]["Y"] = $SerieY; } }
  165. /* Set the shape of a given sctatter serie */
  166. function setScatterSerieShape($ID,$Shape=SERIE_SHAPE_FILLEDCIRCLE)
  167. { if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Shape"] = $Shape; } }
  168. /* Set the description of a given scatter serie */
  169. function setScatterSerieDescription($ID,$Description="My serie")
  170. { if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Description"] = $Description; } }
  171. /* Set the icon associated to a given scatter serie */
  172. function setScatterSeriePicture($ID,$Picture=NULL)
  173. { if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Picture"] = $Picture; } }
  174. /* Set a scatter serie as "drawable" while calling a rendering function */
  175. function setScatterSerieDrawable($ID ,$Drawable=TRUE)
  176. { if (isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["isDrawable"] = $Drawable; } }
  177. /* Define if a scatter serie should be draw with ticks */
  178. function setScatterSerieTicks($ID,$Width=0)
  179. { if ( isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Ticks"] = $Width; } }
  180. /* Define if a scatter serie should be draw with a special weight */
  181. function setScatterSerieWeight($ID,$Weight=0)
  182. { if ( isset($this->Data["ScatterSeries"][$ID]) ) { $this->Data["ScatterSeries"][$ID]["Weight"] = $Weight; } }
  183. /* Associate a color to a scatter serie */
  184. function setScatterSerieColor($ID,$Format)
  185. {
  186. $R = isset($Format["R"]) ? $Format["R"] : 0;
  187. $G = isset($Format["G"]) ? $Format["G"] : 0;
  188. $B = isset($Format["B"]) ? $Format["B"] : 0;
  189. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  190. if ( isset($this->Data["ScatterSeries"][$ID]) )
  191. {
  192. $this->Data["ScatterSeries"][$ID]["Color"]["R"] = $R;
  193. $this->Data["ScatterSeries"][$ID]["Color"]["G"] = $G;
  194. $this->Data["ScatterSeries"][$ID]["Color"]["B"] = $B;
  195. $this->Data["ScatterSeries"][$ID]["Color"]["Alpha"] = $Alpha;
  196. }
  197. }
  198. /* Compute the series limits for an individual and global point of view */
  199. function limits()
  200. {
  201. $GlobalMin = ABSOLUTE_MAX;
  202. $GlobalMax = ABSOLUTE_MIN;
  203. foreach($this->Data["Series"] as $Key => $Value)
  204. {
  205. if ( $this->Data["Abscissa"] != $Key && $this->Data["Series"][$Key]["isDrawable"] == TRUE)
  206. {
  207. if ( $GlobalMin > $this->Data["Series"][$Key]["Min"] ) { $GlobalMin = $this->Data["Series"][$Key]["Min"]; }
  208. if ( $GlobalMax < $this->Data["Series"][$Key]["Max"] ) { $GlobalMax = $this->Data["Series"][$Key]["Max"]; }
  209. }
  210. }
  211. $this->Data["Min"] = $GlobalMin;
  212. $this->Data["Max"] = $GlobalMax;
  213. return(array($GlobalMin,$GlobalMax));
  214. }
  215. /* Mark all series as drawable */
  216. function drawAll()
  217. { foreach($this->Data["Series"] as $Key => $Value) { if ( $this->Data["Abscissa"] != $Key ) { $this->Data["Series"][$Key]["isDrawable"]=TRUE; } } }
  218. /* Return the average value of the given serie */
  219. function getSerieAverage($Serie)
  220. {
  221. if ( isset($this->Data["Series"][$Serie]) )
  222. {
  223. $SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
  224. return(array_sum($SerieData)/sizeof($SerieData));
  225. }
  226. else
  227. return(NULL);
  228. }
  229. /* Return the geometric mean of the given serie */
  230. function getGeometricMean($Serie)
  231. {
  232. if ( isset($this->Data["Series"][$Serie]) )
  233. {
  234. $SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
  235. $Seriesum = 1; foreach($SerieData as $Key => $Value) { $Seriesum = $Seriesum * $Value; }
  236. return(pow($Seriesum,1/sizeof($SerieData)));
  237. }
  238. else
  239. return(NULL);
  240. }
  241. /* Return the harmonic mean of the given serie */
  242. function getHarmonicMean($Serie)
  243. {
  244. if ( isset($this->Data["Series"][$Serie]) )
  245. {
  246. $SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
  247. $Seriesum = 0; foreach($SerieData as $Key => $Value) { $Seriesum = $Seriesum + 1/$Value; }
  248. return(sizeof($SerieData)/$Seriesum);
  249. }
  250. else
  251. return(NULL);
  252. }
  253. /* Return the standard deviation of the given serie */
  254. function getStandardDeviation($Serie)
  255. {
  256. if ( isset($this->Data["Series"][$Serie]) )
  257. {
  258. $Average = $this->getSerieAverage($Serie);
  259. $SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
  260. $DeviationSum = 0;
  261. foreach($SerieData as $Key => $Value)
  262. $DeviationSum = $DeviationSum + ($Value-$Average)*($Value-$Average);
  263. $Deviation = sqrt($DeviationSum/count($SerieData));
  264. return($Deviation);
  265. }
  266. else
  267. return(NULL);
  268. }
  269. /* Return the Coefficient of variation of the given serie */
  270. function getCoefficientOfVariation($Serie)
  271. {
  272. if ( isset($this->Data["Series"][$Serie]) )
  273. {
  274. $Average = $this->getSerieAverage($Serie);
  275. $StandardDeviation = $this->getStandardDeviation($Serie);
  276. if ( $StandardDeviation != 0 )
  277. return($StandardDeviation/$Average);
  278. else
  279. return(NULL);
  280. }
  281. else
  282. return(NULL);
  283. }
  284. /* Return the median value of the given serie */
  285. function getSerieMedian($Serie)
  286. {
  287. if ( isset($this->Data["Series"][$Serie]) )
  288. {
  289. $SerieData = $this->stripVOID($this->Data["Series"][$Serie]["Data"]);
  290. sort($SerieData);
  291. $SerieCenter = floor(sizeof($SerieData)/2);
  292. if ( isset($SerieData[$SerieCenter]) )
  293. return($SerieData[$SerieCenter]);
  294. else
  295. return(NULL);
  296. }
  297. else
  298. return(NULL);
  299. }
  300. /* Return the x th percentil of the given serie */
  301. function getSeriePercentile($Serie="Serie1",$Percentil=95)
  302. {
  303. if (!isset($this->Data["Series"][$Serie]["Data"])) { return(NULL); }
  304. $Values = count($this->Data["Series"][$Serie]["Data"])-1;
  305. if ( $Values < 0 ) { $Values = 0; }
  306. $PercentilID = floor(($Values/100)*$Percentil+.5);
  307. $SortedValues = $this->Data["Series"][$Serie]["Data"];
  308. sort($SortedValues);
  309. if ( is_numeric($SortedValues[$PercentilID]) )
  310. return($SortedValues[$PercentilID]);
  311. else
  312. return(NULL);
  313. }
  314. /* Add random values to a given serie */
  315. function addRandomValues($SerieName="Serie1",$Options="")
  316. {
  317. $Values = isset($Options["Values"]) ? $Options["Values"] : 20;
  318. $Min = isset($Options["Min"]) ? $Options["Min"] : 0;
  319. $Max = isset($Options["Max"]) ? $Options["Max"] : 100;
  320. $withFloat = isset($Options["withFloat"]) ? $Options["withFloat"] : FALSE;
  321. for ($i=0;$i<=$Values;$i++)
  322. {
  323. if ( $withFloat ) { $Value = rand($Min*100,$Max*100)/100; } else { $Value = rand($Min,$Max); }
  324. $this->addPoints($Value,$SerieName);
  325. }
  326. }
  327. /* Test if we have valid data */
  328. function containsData()
  329. {
  330. if (!isset($this->Data["Series"])) { return(FALSE); }
  331. $Result = FALSE;
  332. foreach($this->Data["Series"] as $Key => $Value)
  333. { if ( $this->Data["Abscissa"] != $Key && $this->Data["Series"][$Key]["isDrawable"]==TRUE) { $Result=TRUE; } }
  334. return($Result);
  335. }
  336. /* Set the display mode of an Axis */
  337. function setAxisDisplay($AxisID,$Mode=AXIS_FORMAT_DEFAULT,$Format=NULL)
  338. {
  339. if ( isset($this->Data["Axis"][$AxisID] ) )
  340. {
  341. $this->Data["Axis"][$AxisID]["Display"] = $Mode;
  342. if ( $Format != NULL ) { $this->Data["Axis"][$AxisID]["Format"] = $Format; }
  343. }
  344. }
  345. /* Set the position of an Axis */
  346. function setAxisPosition($AxisID,$Position=AXIS_POSITION_LEFT)
  347. { if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Position"] = $Position; } }
  348. /* Associate an unit to an axis */
  349. function setAxisUnit($AxisID,$Unit)
  350. { if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Unit"] = $Unit; } }
  351. /* Associate a name to an axis */
  352. function setAxisName($AxisID,$Name)
  353. { if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Name"] = $Name; } }
  354. /* Associate a color to an axis */
  355. function setAxisColor($AxisID,$Format)
  356. {
  357. $R = isset($Format["R"]) ? $Format["R"] : 0;
  358. $G = isset($Format["G"]) ? $Format["G"] : 0;
  359. $B = isset($Format["B"]) ? $Format["B"] : 0;
  360. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  361. if ( isset($this->Data["Axis"][$AxisID] ) )
  362. {
  363. $this->Data["Axis"][$AxisID]["Color"]["R"] = $R;
  364. $this->Data["Axis"][$AxisID]["Color"]["G"] = $G;
  365. $this->Data["Axis"][$AxisID]["Color"]["B"] = $B;
  366. $this->Data["Axis"][$AxisID]["Color"]["Alpha"] = $Alpha;
  367. }
  368. }
  369. /* Design an axis as X or Y member */
  370. function setAxisXY($AxisID,$Identity=AXIS_Y)
  371. { if ( isset($this->Data["Axis"][$AxisID] ) ) { $this->Data["Axis"][$AxisID]["Identity"] = $Identity; } }
  372. /* Associate one data serie with one axis */
  373. function setSerieOnAxis($Series,$AxisID)
  374. {
  375. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  376. foreach($Series as $Key => $Serie)
  377. {
  378. $PreviousAxis = $this->Data["Series"][$Serie]["Axis"];
  379. /* Create missing axis */
  380. if ( !isset($this->Data["Axis"][$AxisID] ) )
  381. { $this->Data["Axis"][$AxisID]["Position"] = AXIS_POSITION_LEFT; $this->Data["Axis"][$AxisID]["Identity"] = AXIS_Y;}
  382. $this->Data["Series"][$Serie]["Axis"] = $AxisID;
  383. /* Cleanup unused axis */
  384. $Found = FALSE;
  385. foreach($this->Data["Series"] as $SerieName => $Values) { if ( $Values["Axis"] == $PreviousAxis ) { $Found = TRUE; } }
  386. if (!$Found) { unset($this->Data["Axis"][$PreviousAxis]); }
  387. }
  388. }
  389. /* Define if a serie should be draw with ticks */
  390. function setSerieTicks($Series,$Width=0)
  391. {
  392. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  393. foreach($Series as $Key => $Serie) { if ( isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Ticks"] = $Width; } }
  394. }
  395. /* Define if a serie should be draw with a special weight */
  396. function setSerieWeight($Series,$Weight=0)
  397. {
  398. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  399. foreach($Series as $Key => $Serie) { if ( isset($this->Data["Series"][$Serie]) ) { $this->Data["Series"][$Serie]["Weight"] = $Weight; } }
  400. }
  401. /* Returns the palette of the given serie */
  402. function getSeriePalette($Serie)
  403. {
  404. if ( !isset($this->Data["Series"][$Serie]) ) { return(NULL); }
  405. $Result = "";
  406. $Result["R"] = $this->Data["Series"][$Serie]["Color"]["R"];
  407. $Result["G"] = $this->Data["Series"][$Serie]["Color"]["G"];
  408. $Result["B"] = $this->Data["Series"][$Serie]["Color"]["B"];
  409. $Result["Alpha"] = $this->Data["Series"][$Serie]["Color"]["Alpha"];
  410. return($Result);
  411. }
  412. /* Set the color of one serie */
  413. function setPalette($Series,$Format=NULL)
  414. {
  415. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  416. foreach($Series as $Key => $Serie)
  417. {
  418. $R = isset($Format["R"]) ? $Format["R"] : 0;
  419. $G = isset($Format["G"]) ? $Format["G"] : 0;
  420. $B = isset($Format["B"]) ? $Format["B"] : 0;
  421. $Alpha = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
  422. if ( isset($this->Data["Series"][$Serie]) )
  423. {
  424. $OldR = $this->Data["Series"][$Serie]["Color"]["R"]; $OldG = $this->Data["Series"][$Serie]["Color"]["G"]; $OldB = $this->Data["Series"][$Serie]["Color"]["B"];
  425. $this->Data["Series"][$Serie]["Color"]["R"] = $R;
  426. $this->Data["Series"][$Serie]["Color"]["G"] = $G;
  427. $this->Data["Series"][$Serie]["Color"]["B"] = $B;
  428. $this->Data["Series"][$Serie]["Color"]["Alpha"] = $Alpha;
  429. /* Do reverse processing on the internal palette array */
  430. foreach ($this->Palette as $Key => $Value)
  431. { if ($Value["R"] == $OldR && $Value["G"] == $OldG && $Value["B"] == $OldB) { $this->Palette[$Key]["R"] = $R; $this->Palette[$Key]["G"] = $G; $this->Palette[$Key]["B"] = $B; $this->Palette[$Key]["Alpha"] = $Alpha;} }
  432. }
  433. }
  434. }
  435. /* Load a palette file */
  436. function loadPalette($FileName,$Overwrite=FALSE)
  437. {
  438. if ( !file_exists($FileName) ) { return(-1); }
  439. if ( $Overwrite ) { $this->Palette = ""; }
  440. $fileHandle = @fopen($FileName, "r");
  441. if (!$fileHandle) { return(-1); }
  442. while (!feof($fileHandle))
  443. {
  444. $buffer = fgets($fileHandle, 4096);
  445. if ( preg_match("/,/",$buffer) )
  446. {
  447. list($R,$G,$B,$Alpha) = preg_split("/,/",$buffer);
  448. if ( $this->Palette == "" ) { $ID = 0; } else { $ID = count($this->Palette); }
  449. $this->Palette[$ID] = array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha);
  450. }
  451. }
  452. fclose($fileHandle);
  453. /* Apply changes to current series */
  454. $ID = 0;
  455. if ( isset($this->Data["Series"]))
  456. {
  457. foreach($this->Data["Series"] as $Key => $Value)
  458. {
  459. if ( !isset($this->Palette[$ID]) )
  460. $this->Data["Series"][$Key]["Color"] = array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>0);
  461. else
  462. $this->Data["Series"][$Key]["Color"] = $this->Palette[$ID];
  463. $ID++;
  464. }
  465. }
  466. }
  467. /* Initialise a given scatter serie */
  468. function initScatterSerie($ID)
  469. {
  470. if ( isset($this->Data["ScatterSeries"][$ID]) ) { return(0); }
  471. $this->Data["ScatterSeries"][$ID]["Description"] = "Scatter ".$ID;
  472. $this->Data["ScatterSeries"][$ID]["isDrawable"] = TRUE;
  473. $this->Data["ScatterSeries"][$ID]["Picture"] = NULL;
  474. $this->Data["ScatterSeries"][$ID]["Ticks"] = 0;
  475. $this->Data["ScatterSeries"][$ID]["Weight"] = 0;
  476. if ( isset($this->Palette[$ID]) )
  477. $this->Data["ScatterSeries"][$ID]["Color"] = $this->Palette[$ID];
  478. else
  479. {
  480. $this->Data["ScatterSeries"][$ID]["Color"]["R"] = rand(0,255);
  481. $this->Data["ScatterSeries"][$ID]["Color"]["G"] = rand(0,255);
  482. $this->Data["ScatterSeries"][$ID]["Color"]["B"] = rand(0,255);
  483. $this->Data["ScatterSeries"][$ID]["Color"]["Alpha"] = 100;
  484. }
  485. }
  486. /* Initialise a given serie */
  487. function initialise($Serie)
  488. {
  489. if ( isset($this->Data["Series"]) ) { $ID = count($this->Data["Series"]); } else { $ID = 0; }
  490. $this->Data["Series"][$Serie]["Description"] = $Serie;
  491. $this->Data["Series"][$Serie]["isDrawable"] = TRUE;
  492. $this->Data["Series"][$Serie]["Picture"] = NULL;
  493. $this->Data["Series"][$Serie]["Max"] = NULL;
  494. $this->Data["Series"][$Serie]["Min"] = NULL;
  495. $this->Data["Series"][$Serie]["Axis"] = 0;
  496. $this->Data["Series"][$Serie]["Ticks"] = 0;
  497. $this->Data["Series"][$Serie]["Weight"] = 0;
  498. $this->Data["Series"][$Serie]["Shape"] = SERIE_SHAPE_FILLEDCIRCLE;
  499. if ( isset($this->Palette[$ID]) )
  500. $this->Data["Series"][$Serie]["Color"] = $this->Palette[$ID];
  501. else
  502. {
  503. $this->Data["Series"][$Serie]["Color"]["R"] = rand(0,255);
  504. $this->Data["Series"][$Serie]["Color"]["G"] = rand(0,255);
  505. $this->Data["Series"][$Serie]["Color"]["B"] = rand(0,255);
  506. $this->Data["Series"][$Serie]["Color"]["Alpha"] = 100;
  507. }
  508. }
  509. function normalize($NormalizationFactor=100,$UnitChange=NULL,$Round=1)
  510. {
  511. $Abscissa = $this->Data["Abscissa"];
  512. $SelectedSeries = "";
  513. $MaxVal = 0;
  514. foreach($this->Data["Axis"] as $AxisID => $Axis)
  515. {
  516. if ( $UnitChange != NULL ) { $this->Data["Axis"][$AxisID]["Unit"] = $UnitChange; }
  517. foreach($this->Data["Series"] as $SerieName => $Serie)
  518. {
  519. if ($Serie["Axis"] == $AxisID && $Serie["isDrawable"] == TRUE && $SerieName != $Abscissa)
  520. {
  521. $SelectedSeries[$SerieName] = $SerieName;
  522. if ( count($Serie["Data"] ) > $MaxVal ) { $MaxVal = count($Serie["Data"]); }
  523. }
  524. }
  525. }
  526. for($i=0;$i<=$MaxVal-1;$i++)
  527. {
  528. $Factor = 0;
  529. foreach ($SelectedSeries as $Key => $SerieName )
  530. {
  531. $Value = $this->Data["Series"][$SerieName]["Data"][$i];
  532. if ( $Value != VOID )
  533. $Factor = $Factor + abs($Value);
  534. }
  535. if ( $Factor != 0 )
  536. {
  537. $Factor = $NormalizationFactor / $Factor;
  538. foreach ($SelectedSeries as $Key => $SerieName )
  539. {
  540. $Value = $this->Data["Series"][$SerieName]["Data"][$i];
  541. if ( $Value != VOID && $Factor != $NormalizationFactor )
  542. $this->Data["Series"][$SerieName]["Data"][$i] = round(abs($Value)*$Factor,$Round);
  543. elseif ( $Value == VOID || $Value == 0 )
  544. $this->Data["Series"][$SerieName]["Data"][$i] = VOID;
  545. elseif ( $Factor == $NormalizationFactor )
  546. $this->Data["Series"][$SerieName]["Data"][$i] = $NormalizationFactor;
  547. }
  548. }
  549. }
  550. foreach ($SelectedSeries as $Key => $SerieName )
  551. {
  552. $this->Data["Series"][$SerieName]["Max"] = max($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
  553. $this->Data["Series"][$SerieName]["Min"] = min($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
  554. }
  555. }
  556. /* Load data from a CSV (or similar) data source */
  557. function importFromCSV($FileName,$Options="")
  558. {
  559. $Delimiter = isset($Options["Delimiter"]) ? $Options["Delimiter"] : ",";
  560. $GotHeader = isset($Options["GotHeader"]) ? $Options["GotHeader"] : FALSE;
  561. $SkipColumns = isset($Options["SkipColumns"]) ? $Options["SkipColumns"] : array(-1);
  562. $DefaultSerieName = isset($Options["DefaultSerieName"]) ? $Options["DefaultSerieName"] : "Serie";
  563. $Handle = @fopen($FileName,"r");
  564. if ($Handle)
  565. {
  566. $HeaderParsed = FALSE; $SerieNames = "";
  567. while (!feof($Handle))
  568. {
  569. $Buffer = fgets($Handle, 4096);
  570. $Buffer = str_replace(chr(10),"",$Buffer);
  571. $Buffer = str_replace(chr(13),"",$Buffer);
  572. $Values = preg_split("/".$Delimiter."/",$Buffer);
  573. if ( $Buffer != "" )
  574. {
  575. if ( $GotHeader && !$HeaderParsed )
  576. {
  577. foreach($Values as $Key => $Name) { if ( !in_array($Key,$SkipColumns) ) { $SerieNames[$Key] = $Name; } }
  578. $HeaderParsed = TRUE;
  579. }
  580. else
  581. {
  582. if ($SerieNames == "" ) { foreach($Values as $Key => $Name) { if ( !in_array($Key,$SkipColumns) ) { $SerieNames[$Key] = $DefaultSerieName.$Key; } } }
  583. foreach($Values as $Key => $Value) { if ( !in_array($Key,$SkipColumns) ) { $this->addPoints($Value,$SerieNames[$Key]); } }
  584. }
  585. }
  586. }
  587. fclose($Handle);
  588. }
  589. }
  590. /* Create a dataset based on a formula */
  591. function createFunctionSerie($SerieName,$Formula="",$Options="")
  592. {
  593. $MinX = isset($Options["MinX"]) ? $Options["MinX"] : -10;
  594. $MaxX = isset($Options["MaxX"]) ? $Options["MaxX"] : 10;
  595. $XStep = isset($Options["XStep"]) ? $Options["XStep"] : 1;
  596. $AutoDescription = isset($Options["AutoDescription"]) ? $Options["AutoDescription"] : FALSE;
  597. $RecordAbscissa = isset($Options["RecordAbscissa"]) ? $Options["RecordAbscissa"] : FALSE;
  598. $AbscissaSerie = isset($Options["AbscissaSerie"]) ? $Options["AbscissaSerie"] : "Abscissa";
  599. if ( $Formula == "" ) { return(0); }
  600. $Result = ""; $Abscissa = "";
  601. for($i=$MinX; $i<=$MaxX; $i=$i+$XStep)
  602. {
  603. $Expression = "\$return = '!'.(".str_replace("z",$i,$Formula).");";
  604. if ( @eval($Expression) === FALSE ) { $return = VOID; }
  605. if ( $return == "!" ) { $return = VOID; } else { $return = $this->right($return,strlen($return)-1); }
  606. if ( $return == "NAN" ) { $return = VOID; }
  607. if ( $return == "INF" ) { $return = VOID; }
  608. if ( $return == "-INF" ) { $return = VOID; }
  609. $Abscissa[] = $i;
  610. $Result[] = $return;
  611. }
  612. $this->addPoints($Result,$SerieName);
  613. if ( $AutoDescription ) { $this->setSerieDescription($SerieName,$Formula); }
  614. if ( $RecordAbscissa ) { $this->addPoints($Abscissa,$AbscissaSerie); }
  615. }
  616. function negateValues($Series)
  617. {
  618. if ( !is_array($Series) ) { $Series = $this->convertToArray($Series); }
  619. foreach($Series as $Key => $SerieName)
  620. {
  621. if (isset($this->Data["Series"][$SerieName]))
  622. {
  623. $Data = "";
  624. foreach($this->Data["Series"][$SerieName]["Data"] as $Key => $Value)
  625. { if ( $Value == VOID ) { $Data[] = VOID; } else { $Data[] = -$Value; } }
  626. $this->Data["Series"][$SerieName]["Data"] = $Data;
  627. $this->Data["Series"][$SerieName]["Max"] = max($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
  628. $this->Data["Series"][$SerieName]["Min"] = min($this->stripVOID($this->Data["Series"][$SerieName]["Data"]));
  629. }
  630. }
  631. }
  632. /* Return the data & configuration of the series */
  633. function getData()
  634. { return($this->Data); }
  635. /* Save a palette element */
  636. function savePalette($ID,$Color)
  637. { $this->Palette[$ID] = $Color; }
  638. /* Return the palette of the series */
  639. function getPalette()
  640. { return($this->Palette); }
  641. /* Called by the scaling algorithm to save the config */
  642. function saveAxisConfig($Axis) { $this->Data["Axis"]=$Axis; }
  643. /* Save the Y Margin if set */
  644. function saveYMargin($Value) { $this->Data["YMargin"]=$Value; }
  645. /* Save extended configuration to the pData object */
  646. function saveExtendedData($Tag,$Values) { $this->Data["Extended"][$Tag]=$Values; }
  647. /* Called by the scaling algorithm to save the orientation of the scale */
  648. function saveOrientation($Orientation) { $this->Data["Orientation"]=$Orientation; }
  649. /* Convert a string to a single elements array */
  650. function convertToArray($Value)
  651. { $Values = ""; $Values[] = $Value; return($Values); }
  652. /* Class string wrapper */
  653. function __toString()
  654. { return("pData object."); }
  655. function left($value,$NbChar) { return substr($value,0,$NbChar); }
  656. function right($value,$NbChar) { return substr($value,strlen($value)-$NbChar,$NbChar); }
  657. function mid($value,$Depart,$NbChar) { return substr($value,$Depart-1,$NbChar); }
  658. }

Constants

Classes

Namesort descending Description
pData