PageRenderTime 62ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/phpexcel/PHPExcel/Chart/Renderer/jpgraph.php

https://bitbucket.org/synergylearning/campusconnect
PHP | 839 lines | 621 code | 155 blank | 63 comment | 123 complexity | 4022f377b4a2512944adf8d3ed21fed4 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, Apache-2.0, BSD-3-Clause, AGPL-3.0
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2012 PHPExcel
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category PHPExcel
  22. * @package PHPExcel_Chart
  23. * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version ##VERSION##, ##DATE##
  26. */
  27. require_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php');
  28. /**
  29. * PHPExcel_Chart_Renderer_jpgraph
  30. *
  31. * @category PHPExcel
  32. * @package PHPExcel_Chart_Renderer
  33. * @copyright Copyright (c) 2006 - 2012 PHPExcel (http://www.codeplex.com/PHPExcel)
  34. */
  35. class PHPExcel_Chart_Renderer_jpgraph
  36. {
  37. private static $_width = 640;
  38. private static $_height = 480;
  39. private static $_colourSet = array( 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1',
  40. 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant',
  41. 'mediumblue', 'magenta', 'sandybrown', 'cyan',
  42. 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen',
  43. 'goldenrod2'
  44. );
  45. private static $_markSet = array( 'diamond' => MARK_DIAMOND,
  46. 'square' => MARK_SQUARE,
  47. 'triangle' => MARK_UTRIANGLE,
  48. 'x' => MARK_X,
  49. 'star' => MARK_STAR,
  50. 'dot' => MARK_FILLEDCIRCLE,
  51. 'dash' => MARK_DTRIANGLE,
  52. 'circle' => MARK_CIRCLE,
  53. 'plus' => MARK_CROSS
  54. );
  55. private $_chart = null;
  56. private $_graph = null;
  57. private static $_plotColour = 0;
  58. private static $_plotMark = 0;
  59. private function _formatPointMarker($seriesPlot,$markerID) {
  60. $plotMarkKeys = array_keys(self::$_markSet);
  61. if (is_null($markerID)) {
  62. // Use default plot marker (next marker in the series)
  63. self::$_plotMark %= count(self::$_markSet);
  64. $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]);
  65. } elseif ($markerID !== 'none') {
  66. // Use specified plot marker (if it exists)
  67. if (isset(self::$_markSet[$markerID])) {
  68. $seriesPlot->mark->SetType(self::$_markSet[$markerID]);
  69. } else {
  70. // If the specified plot marker doesn't exist, use default plot marker (next marker in the series)
  71. self::$_plotMark %= count(self::$_markSet);
  72. $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]);
  73. }
  74. } else {
  75. // Hide plot marker
  76. $seriesPlot->mark->Hide();
  77. }
  78. $seriesPlot->mark->SetColor(self::$_colourSet[self::$_plotColour]);
  79. $seriesPlot->mark->SetFillColor(self::$_colourSet[self::$_plotColour]);
  80. $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]);
  81. return $seriesPlot;
  82. } // function _formatPointMarker()
  83. private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') {
  84. $datasetLabelFormatCode = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode();
  85. if (!is_null($datasetLabelFormatCode)) {
  86. // Retrieve any label formatting code
  87. $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode);
  88. }
  89. $testCurrentIndex = 0;
  90. foreach($datasetLabels as $i => $datasetLabel) {
  91. array_reverse($datasetLabel);
  92. if (is_array($datasetLabel)) {
  93. if ($rotation == 'bar') {
  94. $datasetLabel = array_reverse($datasetLabel);
  95. $datasetLabels[$i] = implode(" ",$datasetLabel);
  96. } else {
  97. $datasetLabels[$i] = implode("\n",$datasetLabel);
  98. }
  99. } else {
  100. // Format labels according to any formatting code
  101. if (!is_null($datasetLabelFormatCode)) {
  102. $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel,$datasetLabelFormatCode);
  103. }
  104. }
  105. ++$testCurrentIndex;
  106. }
  107. return $datasetLabels;
  108. } // function _formatDataSetLabels()
  109. private function _percentageSumCalculation($groupID,$seriesCount) {
  110. // Adjust our values to a percentage value across all series in the group
  111. for($i = 0; $i < $seriesCount; ++$i) {
  112. if ($i == 0) {
  113. $sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();
  114. } else {
  115. $nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();
  116. foreach($nextValues as $k => $value) {
  117. if (isset($sumValues[$k])) {
  118. $sumValues[$k] += $value;
  119. } else {
  120. $sumValues[$k] = $value;
  121. }
  122. }
  123. }
  124. }
  125. return $sumValues;
  126. } // function _percentageSumCalculation()
  127. private function _percentageAdjustValues($dataValues,$sumValues) {
  128. foreach($dataValues as $k => $dataValue) {
  129. $dataValues[$k] = $dataValue / $sumValues[$k] * 100;
  130. }
  131. return $dataValues;
  132. } // function _percentageAdjustValues()
  133. private function _getCaption($captionElement) {
  134. // Read any caption
  135. $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : NULL;
  136. // Test if we have a title caption to display
  137. if (!is_null($caption)) {
  138. // If we do, it could be a plain string or an array
  139. if (is_array($caption)) {
  140. // Implode an array to a plain string
  141. $caption = implode('',$caption);
  142. }
  143. }
  144. return $caption;
  145. } // function _getCaption()
  146. private function _renderTitle() {
  147. $title = $this->_getCaption($this->_chart->getTitle());
  148. if (!is_null($title)) {
  149. $this->_graph->title->Set($title);
  150. }
  151. } // function _renderTitle()
  152. private function _renderLegend() {
  153. $legend = $this->_chart->getLegend();
  154. if (!is_null($legend)) {
  155. $legendPosition = $legend->getPosition();
  156. $legendOverlay = $legend->getOverlay();
  157. switch ($legendPosition) {
  158. case 'r' :
  159. $this->_graph->legend->SetPos(0.01,0.5,'right','center'); // right
  160. $this->_graph->legend->SetColumns(1);
  161. break;
  162. case 'l' :
  163. $this->_graph->legend->SetPos(0.01,0.5,'left','center'); // left
  164. $this->_graph->legend->SetColumns(1);
  165. break;
  166. case 't' :
  167. $this->_graph->legend->SetPos(0.5,0.01,'center','top'); // top
  168. break;
  169. case 'b' :
  170. $this->_graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom
  171. break;
  172. default :
  173. $this->_graph->legend->SetPos(0.01,0.01,'right','top'); // top-right
  174. $this->_graph->legend->SetColumns(1);
  175. break;
  176. }
  177. } else {
  178. $this->_graph->legend->Hide();
  179. }
  180. } // function _renderLegend()
  181. private function _renderCartesianPlotArea($type='textlin') {
  182. $this->_graph = new Graph(self::$_width,self::$_height);
  183. $this->_graph->SetScale($type);
  184. $this->_renderTitle();
  185. // Rotate for bar rather than column chart
  186. $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection();
  187. $reverse = ($rotation == 'bar') ? true : false;
  188. $xAxisLabel = $this->_chart->getXAxisLabel();
  189. if (!is_null($xAxisLabel)) {
  190. $title = $this->_getCaption($xAxisLabel);
  191. if (!is_null($title)) {
  192. $this->_graph->xaxis->SetTitle($title,'center');
  193. $this->_graph->xaxis->title->SetMargin(35);
  194. if ($reverse) {
  195. $this->_graph->xaxis->title->SetAngle(90);
  196. $this->_graph->xaxis->title->SetMargin(90);
  197. }
  198. }
  199. }
  200. $yAxisLabel = $this->_chart->getYAxisLabel();
  201. if (!is_null($yAxisLabel)) {
  202. $title = $this->_getCaption($yAxisLabel);
  203. if (!is_null($title)) {
  204. $this->_graph->yaxis->SetTitle($title,'center');
  205. if ($reverse) {
  206. $this->_graph->yaxis->title->SetAngle(0);
  207. $this->_graph->yaxis->title->SetMargin(-55);
  208. }
  209. }
  210. }
  211. } // function _renderCartesianPlotArea()
  212. private function _renderPiePlotArea($doughnut = False) {
  213. $this->_graph = new PieGraph(self::$_width,self::$_height);
  214. $this->_renderTitle();
  215. } // function _renderPiePlotArea()
  216. private function _renderRadarPlotArea() {
  217. $this->_graph = new RadarGraph(self::$_width,self::$_height);
  218. $this->_graph->SetScale('lin');
  219. $this->_renderTitle();
  220. } // function _renderRadarPlotArea()
  221. private function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') {
  222. $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
  223. $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount());
  224. if ($labelCount > 0) {
  225. $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
  226. $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount);
  227. $this->_graph->xaxis->SetTickLabels($datasetLabels);
  228. }
  229. $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
  230. $seriesPlots = array();
  231. if ($grouping == 'percentStacked') {
  232. $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount);
  233. }
  234. // Loop through each data series in turn
  235. for($i = 0; $i < $seriesCount; ++$i) {
  236. $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();
  237. $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker();
  238. if ($grouping == 'percentStacked') {
  239. $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues);
  240. }
  241. // Fill in any missing values in the $dataValues array
  242. $testCurrentIndex = 0;
  243. foreach($dataValues as $k => $dataValue) {
  244. while($k != $testCurrentIndex) {
  245. $dataValues[$testCurrentIndex] = null;
  246. ++$testCurrentIndex;
  247. }
  248. ++$testCurrentIndex;
  249. }
  250. $seriesPlot = new LinePlot($dataValues);
  251. if ($combination) {
  252. $seriesPlot->SetBarCenter();
  253. }
  254. if ($filled) {
  255. $seriesPlot->SetFilled(true);
  256. $seriesPlot->SetColor('black');
  257. $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]);
  258. } else {
  259. // Set the appropriate plot marker
  260. $this->_formatPointMarker($seriesPlot,$marker);
  261. }
  262. $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue();
  263. $seriesPlot->SetLegend($dataLabel);
  264. $seriesPlots[] = $seriesPlot;
  265. }
  266. if ($grouping == 'standard') {
  267. $groupPlot = $seriesPlots;
  268. } else {
  269. $groupPlot = new AccLinePlot($seriesPlots);
  270. }
  271. $this->_graph->Add($groupPlot);
  272. } // function _renderPlotLine()
  273. private function _renderPlotBar($groupID, $dimensions = '2d') {
  274. $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection();
  275. // Rotate for bar rather than column chart
  276. if (($groupID == 0) && ($rotation == 'bar')) {
  277. $this->_graph->Set90AndMargin();
  278. }
  279. $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
  280. $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount());
  281. if ($labelCount > 0) {
  282. $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
  283. $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation);
  284. // Rotate for bar rather than column chart
  285. if ($rotation == 'bar') {
  286. $datasetLabels = array_reverse($datasetLabels);
  287. $this->_graph->yaxis->SetPos('max');
  288. $this->_graph->yaxis->SetLabelAlign('center','top');
  289. $this->_graph->yaxis->SetLabelSide(SIDE_RIGHT);
  290. }
  291. $this->_graph->xaxis->SetTickLabels($datasetLabels);
  292. }
  293. $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
  294. $seriesPlots = array();
  295. if ($grouping == 'percentStacked') {
  296. $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount);
  297. }
  298. // Loop through each data series in turn
  299. for($j = 0; $j < $seriesCount; ++$j) {
  300. $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues();
  301. if ($grouping == 'percentStacked') {
  302. $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues);
  303. }
  304. // Fill in any missing values in the $dataValues array
  305. $testCurrentIndex = 0;
  306. foreach($dataValues as $k => $dataValue) {
  307. while($k != $testCurrentIndex) {
  308. $dataValues[$testCurrentIndex] = null;
  309. ++$testCurrentIndex;
  310. }
  311. ++$testCurrentIndex;
  312. }
  313. // Reverse the $dataValues order for bar rather than column chart
  314. if ($rotation == 'bar') {
  315. $dataValues = array_reverse($dataValues);
  316. }
  317. $seriesPlot = new BarPlot($dataValues);
  318. $seriesPlot->SetColor('black');
  319. $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]);
  320. if ($dimensions == '3d') {
  321. $seriesPlot->SetShadow();
  322. }
  323. if (!$this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) {
  324. $dataLabel = '';
  325. } else {
  326. $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue();
  327. }
  328. $seriesPlot->SetLegend($dataLabel);
  329. $seriesPlots[] = $seriesPlot;
  330. }
  331. // Reverse the plot order for bar rather than column chart
  332. if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) {
  333. $seriesPlots = array_reverse($seriesPlots);
  334. }
  335. if ($grouping == 'clustered') {
  336. $groupPlot = new GroupBarPlot($seriesPlots);
  337. } elseif ($grouping == 'standard') {
  338. $groupPlot = new GroupBarPlot($seriesPlots);
  339. } else {
  340. $groupPlot = new AccBarPlot($seriesPlots);
  341. if ($dimensions == '3d') {
  342. $groupPlot->SetShadow();
  343. }
  344. }
  345. $this->_graph->Add($groupPlot);
  346. } // function _renderPlotBar()
  347. private function _renderPlotScatter($groupID,$bubble) {
  348. $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
  349. $scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
  350. $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
  351. $seriesPlots = array();
  352. // Loop through each data series in turn
  353. for($i = 0; $i < $seriesCount; ++$i) {
  354. $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues();
  355. $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();
  356. foreach($dataValuesY as $k => $dataValueY) {
  357. $dataValuesY[$k] = $k;
  358. }
  359. $seriesPlot = new ScatterPlot($dataValuesX,$dataValuesY);
  360. if ($scatterStyle == 'lineMarker') {
  361. $seriesPlot->SetLinkPoints();
  362. $seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]);
  363. } elseif ($scatterStyle == 'smoothMarker') {
  364. $spline = new Spline($dataValuesY,$dataValuesX);
  365. list($splineDataY,$splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20);
  366. $lplot = new LinePlot($splineDataX,$splineDataY);
  367. $lplot->SetColor(self::$_colourSet[self::$_plotColour]);
  368. $this->_graph->Add($lplot);
  369. }
  370. if ($bubble) {
  371. $this->_formatPointMarker($seriesPlot,'dot');
  372. $seriesPlot->mark->SetColor('black');
  373. $seriesPlot->mark->SetSize($bubbleSize);
  374. } else {
  375. $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker();
  376. $this->_formatPointMarker($seriesPlot,$marker);
  377. }
  378. $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue();
  379. $seriesPlot->SetLegend($dataLabel);
  380. $this->_graph->Add($seriesPlot);
  381. }
  382. } // function _renderPlotScatter()
  383. private function _renderPlotRadar($groupID) {
  384. $radarStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
  385. $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
  386. $seriesPlots = array();
  387. // Loop through each data series in turn
  388. for($i = 0; $i < $seriesCount; ++$i) {
  389. $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues();
  390. $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();
  391. $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker();
  392. $dataValues = array();
  393. foreach($dataValuesY as $k => $dataValueY) {
  394. $dataValues[$k] = implode(' ',array_reverse($dataValueY));
  395. }
  396. $tmp = array_shift($dataValues);
  397. $dataValues[] = $tmp;
  398. $tmp = array_shift($dataValuesX);
  399. $dataValuesX[] = $tmp;
  400. $this->_graph->SetTitles(array_reverse($dataValues));
  401. $seriesPlot = new RadarPlot(array_reverse($dataValuesX));
  402. $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue();
  403. $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]);
  404. if ($radarStyle == 'filled') {
  405. $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]);
  406. }
  407. $this->_formatPointMarker($seriesPlot,$marker);
  408. $seriesPlot->SetLegend($dataLabel);
  409. $this->_graph->Add($seriesPlot);
  410. }
  411. } // function _renderPlotRadar()
  412. private function _renderPlotContour($groupID) {
  413. $contourStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
  414. $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
  415. $seriesPlots = array();
  416. $dataValues = array();
  417. // Loop through each data series in turn
  418. for($i = 0; $i < $seriesCount; ++$i) {
  419. $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues();
  420. $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();
  421. $dataValues[$i] = $dataValuesX;
  422. }
  423. $seriesPlot = new ContourPlot($dataValues);
  424. $this->_graph->Add($seriesPlot);
  425. } // function _renderPlotContour()
  426. private function _renderPlotStock($groupID) {
  427. $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
  428. $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder();
  429. $seriesPlots = array();
  430. $dataValues = array();
  431. // Loop through each data series in turn
  432. for($i = 0; $i < $seriesCount; ++$i) {
  433. $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues();
  434. $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();
  435. foreach($dataValuesX as $j => $dataValueX)
  436. $dataValues[$j][$plotOrder[$i]] = $dataValueX;
  437. }
  438. $seriesPlot = new StockPlot($dataValues);
  439. $this->_graph->Add($seriesPlot);
  440. } // function _renderPlotStock()
  441. private function _renderAreaChart($groupCount, $dimensions = '2d') {
  442. require_once('jpgraph_line.php');
  443. $this->_renderCartesianPlotArea();
  444. for($i = 0; $i < $groupCount; ++$i) {
  445. $this->_renderPlotLine($i,True,False,$dimensions);
  446. }
  447. } // function _renderAreaChart()
  448. private function _renderLineChart($groupCount, $dimensions = '2d') {
  449. require_once('jpgraph_line.php');
  450. $this->_renderCartesianPlotArea();
  451. for($i = 0; $i < $groupCount; ++$i) {
  452. $this->_renderPlotLine($i,False,False,$dimensions);
  453. }
  454. } // function _renderLineChart()
  455. private function _renderBarChart($groupCount, $dimensions = '2d') {
  456. require_once('jpgraph_bar.php');
  457. $this->_renderCartesianPlotArea();
  458. for($i = 0; $i < $groupCount; ++$i) {
  459. $this->_renderPlotBar($i,$dimensions);
  460. }
  461. } // function _renderBarChart()
  462. private function _renderScatterChart($groupCount) {
  463. require_once('jpgraph_scatter.php');
  464. require_once('jpgraph_regstat.php');
  465. require_once('jpgraph_line.php');
  466. $this->_renderCartesianPlotArea('linlin');
  467. for($i = 0; $i < $groupCount; ++$i) {
  468. $this->_renderPlotScatter($i,false);
  469. }
  470. } // function _renderScatterChart()
  471. private function _renderBubbleChart($groupCount) {
  472. require_once('jpgraph_scatter.php');
  473. $this->_renderCartesianPlotArea('linlin');
  474. for($i = 0; $i < $groupCount; ++$i) {
  475. $this->_renderPlotScatter($i,true);
  476. }
  477. } // function _renderBubbleChart()
  478. private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) {
  479. require_once('jpgraph_pie.php');
  480. if ($dimensions == '3d') {
  481. require_once('jpgraph_pie3d.php');
  482. }
  483. $this->_renderPiePlotArea($doughnut);
  484. $iLimit = ($multiplePlots) ? $groupCount : 1;
  485. for($groupID = 0; $groupID < $iLimit; ++$groupID) {
  486. $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
  487. $exploded = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
  488. if ($groupID == 0) {
  489. $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount());
  490. if ($labelCount > 0) {
  491. $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
  492. $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount);
  493. }
  494. }
  495. $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
  496. $seriesPlots = array();
  497. // For pie charts, we only display the first series: doughnut charts generally display all series
  498. $jLimit = ($multiplePlots) ? $seriesCount : 1;
  499. // Loop through each data series in turn
  500. for($j = 0; $j < $jLimit; ++$j) {
  501. $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues();
  502. // Fill in any missing values in the $dataValues array
  503. $testCurrentIndex = 0;
  504. foreach($dataValues as $k => $dataValue) {
  505. while($k != $testCurrentIndex) {
  506. $dataValues[$testCurrentIndex] = null;
  507. ++$testCurrentIndex;
  508. }
  509. ++$testCurrentIndex;
  510. }
  511. if ($dimensions == '3d') {
  512. $seriesPlot = new PiePlot3D($dataValues);
  513. } else {
  514. if ($doughnut) {
  515. $seriesPlot = new PiePlotC($dataValues);
  516. } else {
  517. $seriesPlot = new PiePlot($dataValues);
  518. }
  519. }
  520. if ($multiplePlots) {
  521. $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4));
  522. }
  523. if ($doughnut) {
  524. $seriesPlot->SetMidColor('white');
  525. }
  526. $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]);
  527. if (count($datasetLabels) > 0)
  528. $seriesPlot->SetLabels(array_fill(0,count($datasetLabels),''));
  529. if ($dimensions != '3d') {
  530. $seriesPlot->SetGuideLines(false);
  531. }
  532. if ($j == 0) {
  533. if ($exploded) {
  534. $seriesPlot->ExplodeAll();
  535. }
  536. $seriesPlot->SetLegends($datasetLabels);
  537. }
  538. $this->_graph->Add($seriesPlot);
  539. }
  540. }
  541. } // function _renderPieChart()
  542. private function _renderRadarChart($groupCount) {
  543. require_once('jpgraph_radar.php');
  544. $this->_renderRadarPlotArea();
  545. for($groupID = 0; $groupID < $groupCount; ++$groupID) {
  546. $this->_renderPlotRadar($groupID);
  547. }
  548. } // function _renderRadarChart()
  549. private function _renderStockChart($groupCount) {
  550. require_once('jpgraph_stock.php');
  551. $this->_renderCartesianPlotArea();
  552. for($groupID = 0; $groupID < $groupCount; ++$i) {
  553. $this->_renderPlotStock($groupID);
  554. }
  555. } // function _renderStockChart()
  556. private function _renderContourChart($groupCount,$dimensions) {
  557. require_once('jpgraph_contour.php');
  558. $this->_renderCartesianPlotArea('intint');
  559. for($i = 0; $i < $groupCount; ++$i) {
  560. $this->_renderPlotContour($i);
  561. }
  562. } // function _renderContourChart()
  563. private function _renderCombinationChart($groupCount,$dimensions,$outputDestination) {
  564. require_once('jpgraph_line.php');
  565. require_once('jpgraph_bar.php');
  566. require_once('jpgraph_scatter.php');
  567. require_once('jpgraph_regstat.php');
  568. require_once('jpgraph_line.php');
  569. $this->_renderCartesianPlotArea();
  570. for($i = 0; $i < $groupCount; ++$i) {
  571. $dimensions = null;
  572. $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
  573. switch ($chartType) {
  574. case 'area3DChart' :
  575. $dimensions = '3d';
  576. case 'areaChart' :
  577. $this->_renderPlotLine($i,True,True,$dimensions);
  578. break;
  579. case 'bar3DChart' :
  580. $dimensions = '3d';
  581. case 'barChart' :
  582. $this->_renderPlotBar($i,$dimensions);
  583. break;
  584. case 'line3DChart' :
  585. $dimensions = '3d';
  586. case 'lineChart' :
  587. $this->_renderPlotLine($i,False,True,$dimensions);
  588. break;
  589. case 'scatterChart' :
  590. $this->_renderPlotScatter($i,false);
  591. break;
  592. case 'bubbleChart' :
  593. $this->_renderPlotScatter($i,true);
  594. break;
  595. default :
  596. $this->_graph = null;
  597. return false;
  598. }
  599. }
  600. $this->_renderLegend();
  601. $this->_graph->Stroke($outputDestination);
  602. return true;
  603. } // function _renderCombinationChart()
  604. public function render($outputDestination) {
  605. self::$_plotColour = 0;
  606. $groupCount = $this->_chart->getPlotArea()->getPlotGroupCount();
  607. $dimensions = null;
  608. if ($groupCount == 1) {
  609. $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
  610. } else {
  611. $chartTypes = array();
  612. for($i = 0; $i < $groupCount; ++$i) {
  613. $chartTypes[] = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
  614. }
  615. $chartTypes = array_unique($chartTypes);
  616. if (count($chartTypes) == 1) {
  617. $chartType = array_pop($chartTypes);
  618. } elseif (count($chartTypes) == 0) {
  619. echo 'Chart is not yet implemented<br />';
  620. return false;
  621. } else {
  622. return $this->_renderCombinationChart($groupCount,$dimensions,$outputDestination);
  623. }
  624. }
  625. switch ($chartType) {
  626. case 'area3DChart' :
  627. $dimensions = '3d';
  628. case 'areaChart' :
  629. $this->_renderAreaChart($groupCount,$dimensions);
  630. break;
  631. case 'bar3DChart' :
  632. $dimensions = '3d';
  633. case 'barChart' :
  634. $this->_renderBarChart($groupCount,$dimensions);
  635. break;
  636. case 'line3DChart' :
  637. $dimensions = '3d';
  638. case 'lineChart' :
  639. $this->_renderLineChart($groupCount,$dimensions);
  640. break;
  641. case 'pie3DChart' :
  642. $dimensions = '3d';
  643. case 'pieChart' :
  644. $this->_renderPieChart($groupCount,$dimensions,False,False);
  645. break;
  646. case 'doughnut3DChart' :
  647. $dimensions = '3d';
  648. case 'doughnutChart' :
  649. $this->_renderPieChart($groupCount,$dimensions,True,True);
  650. break;
  651. case 'scatterChart' :
  652. $this->_renderScatterChart($groupCount);
  653. break;
  654. case 'bubbleChart' :
  655. $this->_renderBubbleChart($groupCount);
  656. break;
  657. case 'radarChart' :
  658. $this->_renderRadarChart($groupCount);
  659. break;
  660. case 'surface3DChart' :
  661. $dimensions = '3d';
  662. case 'surfaceChart' :
  663. $this->_renderContourChart($groupCount,$dimensions);
  664. break;
  665. case 'stockChart' :
  666. $this->_renderStockChart($groupCount,$dimensions);
  667. break;
  668. default :
  669. echo $chartType.' is not yet implemented<br />';
  670. return false;
  671. }
  672. $this->_renderLegend();
  673. $this->_graph->Stroke($outputDestination);
  674. return true;
  675. } // function render()
  676. /**
  677. * Create a new PHPExcel_Chart_Renderer_jpgraph
  678. */
  679. public function __construct(PHPExcel_Chart $chart)
  680. {
  681. $this->_graph = null;
  682. $this->_chart = $chart;
  683. } // function __construct()
  684. } // PHPExcel_Chart_Renderer_jpgraph