[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 require_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php'); 4 5 /** 6 * PHPExcel_Chart_Renderer_jpgraph 7 * 8 * Copyright (c) 2006 - 2015 PHPExcel 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library 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 GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 * @category PHPExcel 25 * @package PHPExcel_Chart_Renderer 26 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) 27 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL 28 * @version ##VERSION##, ##DATE## 29 */ 30 class PHPExcel_Chart_Renderer_jpgraph 31 { 32 private static $width = 640; 33 34 private static $height = 480; 35 36 private static $colourSet = array( 37 'mediumpurple1', 'palegreen3', 'gold1', 'cadetblue1', 38 'darkmagenta', 'coral', 'dodgerblue3', 'eggplant', 39 'mediumblue', 'magenta', 'sandybrown', 'cyan', 40 'firebrick1', 'forestgreen', 'deeppink4', 'darkolivegreen', 41 'goldenrod2' 42 ); 43 44 private static $markSet = array( 45 '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 56 57 private $chart; 58 59 private $graph; 60 61 private static $plotColour = 0; 62 63 private static $plotMark = 0; 64 65 66 private function formatPointMarker($seriesPlot, $markerID) 67 { 68 $plotMarkKeys = array_keys(self::$markSet); 69 if (is_null($markerID)) { 70 // 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 } elseif ($markerID !== 'none') { 74 // Use specified plot marker (if it exists) 75 if (isset(self::$markSet[$markerID])) { 76 $seriesPlot->mark->SetType(self::$markSet[$markerID]); 77 } else { 78 // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) 79 self::$plotMark %= count(self::$markSet); 80 $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]); 81 } 82 } else { 83 // Hide plot marker 84 $seriesPlot->mark->Hide(); 85 } 86 $seriesPlot->mark->SetColor(self::$colourSet[self::$plotColour]); 87 $seriesPlot->mark->SetFillColor(self::$colourSet[self::$plotColour]); 88 $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); 89 90 return $seriesPlot; 91 } 92 93 94 private function formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') 95 { 96 $datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); 97 if (!is_null($datasetLabelFormatCode)) { 98 // Retrieve any label formatting code 99 $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); 100 } 101 102 $testCurrentIndex = 0; 103 foreach ($datasetLabels as $i => $datasetLabel) { 104 if (is_array($datasetLabel)) { 105 if ($rotation == 'bar') { 106 $datasetLabels[$i] = implode(" ", $datasetLabel); 107 } else { 108 $datasetLabel = array_reverse($datasetLabel); 109 $datasetLabels[$i] = implode("\n", $datasetLabel); 110 } 111 } else { 112 // Format labels according to any formatting code 113 if (!is_null($datasetLabelFormatCode)) { 114 $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel, $datasetLabelFormatCode); 115 } 116 } 117 ++$testCurrentIndex; 118 } 119 120 return $datasetLabels; 121 } 122 123 124 private function percentageSumCalculation($groupID, $seriesCount) 125 { 126 // Adjust our values to a percentage value across all series in the group 127 for ($i = 0; $i < $seriesCount; ++$i) { 128 if ($i == 0) { 129 $sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); 130 } else { 131 $nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); 132 foreach ($nextValues as $k => $value) { 133 if (isset($sumValues[$k])) { 134 $sumValues[$k] += $value; 135 } else { 136 $sumValues[$k] = $value; 137 } 138 } 139 } 140 } 141 142 return $sumValues; 143 } 144 145 146 private function percentageAdjustValues($dataValues, $sumValues) 147 { 148 foreach ($dataValues as $k => $dataValue) { 149 $dataValues[$k] = $dataValue / $sumValues[$k] * 100; 150 } 151 152 return $dataValues; 153 } 154 155 156 private function getCaption($captionElement) 157 { 158 // Read any caption 159 $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : null; 160 // Test if we have a title caption to display 161 if (!is_null($caption)) { 162 // If we do, it could be a plain string or an array 163 if (is_array($caption)) { 164 // Implode an array to a plain string 165 $caption = implode('', $caption); 166 } 167 } 168 return $caption; 169 } 170 171 172 private function renderTitle() 173 { 174 $title = $this->getCaption($this->chart->getTitle()); 175 if (!is_null($title)) { 176 $this->graph->title->Set($title); 177 } 178 } 179 180 181 private function renderLegend() 182 { 183 $legend = $this->chart->getLegend(); 184 if (!is_null($legend)) { 185 $legendPosition = $legend->getPosition(); 186 $legendOverlay = $legend->getOverlay(); 187 switch ($legendPosition) { 188 case 'r': 189 $this->graph->legend->SetPos(0.01, 0.5, 'right', 'center'); // right 190 $this->graph->legend->SetColumns(1); 191 break; 192 case 'l': 193 $this->graph->legend->SetPos(0.01, 0.5, 'left', 'center'); // left 194 $this->graph->legend->SetColumns(1); 195 break; 196 case 't': 197 $this->graph->legend->SetPos(0.5, 0.01, 'center', 'top'); // top 198 break; 199 case 'b': 200 $this->graph->legend->SetPos(0.5, 0.99, 'center', 'bottom'); // bottom 201 break; 202 default: 203 $this->graph->legend->SetPos(0.01, 0.01, 'right', 'top'); // top-right 204 $this->graph->legend->SetColumns(1); 205 break; 206 } 207 } else { 208 $this->graph->legend->Hide(); 209 } 210 } 211 212 213 private function renderCartesianPlotArea($type = 'textlin') 214 { 215 $this->graph = new Graph(self::$width, self::$height); 216 $this->graph->SetScale($type); 217 218 $this->renderTitle(); 219 220 // Rotate for bar rather than column chart 221 $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); 222 $reverse = ($rotation == 'bar') ? true : false; 223 224 $xAxisLabel = $this->chart->getXAxisLabel(); 225 if (!is_null($xAxisLabel)) { 226 $title = $this->getCaption($xAxisLabel); 227 if (!is_null($title)) { 228 $this->graph->xaxis->SetTitle($title, 'center'); 229 $this->graph->xaxis->title->SetMargin(35); 230 if ($reverse) { 231 $this->graph->xaxis->title->SetAngle(90); 232 $this->graph->xaxis->title->SetMargin(90); 233 } 234 } 235 } 236 237 $yAxisLabel = $this->chart->getYAxisLabel(); 238 if (!is_null($yAxisLabel)) { 239 $title = $this->getCaption($yAxisLabel); 240 if (!is_null($title)) { 241 $this->graph->yaxis->SetTitle($title, 'center'); 242 if ($reverse) { 243 $this->graph->yaxis->title->SetAngle(0); 244 $this->graph->yaxis->title->SetMargin(-55); 245 } 246 } 247 } 248 } 249 250 251 private function renderPiePlotArea($doughnut = false) 252 { 253 $this->graph = new PieGraph(self::$width, self::$height); 254 255 $this->renderTitle(); 256 } 257 258 259 private function renderRadarPlotArea() 260 { 261 $this->graph = new RadarGraph(self::$width, self::$height); 262 $this->graph->SetScale('lin'); 263 264 $this->renderTitle(); 265 } 266 267 268 private function renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') 269 { 270 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); 271 272 $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); 273 if ($labelCount > 0) { 274 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); 275 $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); 276 $this->graph->xaxis->SetTickLabels($datasetLabels); 277 } 278 279 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); 280 $seriesPlots = array(); 281 if ($grouping == 'percentStacked') { 282 $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); 283 } 284 285 // Loop through each data series in turn 286 for ($i = 0; $i < $seriesCount; ++$i) { 287 $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); 288 $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); 289 290 if ($grouping == 'percentStacked') { 291 $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); 292 } 293 294 // Fill in any missing values in the $dataValues array 295 $testCurrentIndex = 0; 296 foreach ($dataValues as $k => $dataValue) { 297 while ($k != $testCurrentIndex) { 298 $dataValues[$testCurrentIndex] = null; 299 ++$testCurrentIndex; 300 } 301 ++$testCurrentIndex; 302 } 303 304 $seriesPlot = new LinePlot($dataValues); 305 if ($combination) { 306 $seriesPlot->SetBarCenter(); 307 } 308 309 if ($filled) { 310 $seriesPlot->SetFilled(true); 311 $seriesPlot->SetColor('black'); 312 $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); 313 } else { 314 // Set the appropriate plot marker 315 $this->formatPointMarker($seriesPlot, $marker); 316 } 317 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); 318 $seriesPlot->SetLegend($dataLabel); 319 320 $seriesPlots[] = $seriesPlot; 321 } 322 323 if ($grouping == 'standard') { 324 $groupPlot = $seriesPlots; 325 } else { 326 $groupPlot = new AccLinePlot($seriesPlots); 327 } 328 $this->graph->Add($groupPlot); 329 } 330 331 332 private function renderPlotBar($groupID, $dimensions = '2d') 333 { 334 $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); 335 // Rotate for bar rather than column chart 336 if (($groupID == 0) && ($rotation == 'bar')) { 337 $this->graph->Set90AndMargin(); 338 } 339 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); 340 341 $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); 342 if ($labelCount > 0) { 343 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); 344 $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); 345 // Rotate for bar rather than column chart 346 if ($rotation == 'bar') { 347 $datasetLabels = array_reverse($datasetLabels); 348 $this->graph->yaxis->SetPos('max'); 349 $this->graph->yaxis->SetLabelAlign('center', 'top'); 350 $this->graph->yaxis->SetLabelSide(SIDE_RIGHT); 351 } 352 $this->graph->xaxis->SetTickLabels($datasetLabels); 353 } 354 355 356 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); 357 $seriesPlots = array(); 358 if ($grouping == 'percentStacked') { 359 $sumValues = $this->percentageSumCalculation($groupID, $seriesCount); 360 } 361 362 // Loop through each data series in turn 363 for ($j = 0; $j < $seriesCount; ++$j) { 364 $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); 365 if ($grouping == 'percentStacked') { 366 $dataValues = $this->percentageAdjustValues($dataValues, $sumValues); 367 } 368 369 // Fill in any missing values in the $dataValues array 370 $testCurrentIndex = 0; 371 foreach ($dataValues as $k => $dataValue) { 372 while ($k != $testCurrentIndex) { 373 $dataValues[$testCurrentIndex] = null; 374 ++$testCurrentIndex; 375 } 376 ++$testCurrentIndex; 377 } 378 379 // Reverse the $dataValues order for bar rather than column chart 380 if ($rotation == 'bar') { 381 $dataValues = array_reverse($dataValues); 382 } 383 $seriesPlot = new BarPlot($dataValues); 384 $seriesPlot->SetColor('black'); 385 $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]); 386 if ($dimensions == '3d') { 387 $seriesPlot->SetShadow(); 388 } 389 if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { 390 $dataLabel = ''; 391 } else { 392 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); 393 } 394 $seriesPlot->SetLegend($dataLabel); 395 396 $seriesPlots[] = $seriesPlot; 397 } 398 // Reverse the plot order for bar rather than column chart 399 if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { 400 $seriesPlots = array_reverse($seriesPlots); 401 } 402 403 if ($grouping == 'clustered') { 404 $groupPlot = new GroupBarPlot($seriesPlots); 405 } elseif ($grouping == 'standard') { 406 $groupPlot = new GroupBarPlot($seriesPlots); 407 } else { 408 $groupPlot = new AccBarPlot($seriesPlots); 409 if ($dimensions == '3d') { 410 $groupPlot->SetShadow(); 411 } 412 } 413 414 $this->graph->Add($groupPlot); 415 } 416 417 418 private function renderPlotScatter($groupID, $bubble) 419 { 420 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); 421 $scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); 422 423 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); 424 $seriesPlots = array(); 425 426 // Loop through each data series in turn 427 for ($i = 0; $i < $seriesCount; ++$i) { 428 $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); 429 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); 430 431 foreach ($dataValuesY as $k => $dataValueY) { 432 $dataValuesY[$k] = $k; 433 } 434 435 $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); 436 if ($scatterStyle == 'lineMarker') { 437 $seriesPlot->SetLinkPoints(); 438 $seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]); 439 } elseif ($scatterStyle == 'smoothMarker') { 440 $spline = new Spline($dataValuesY, $dataValuesX); 441 list($splineDataY, $splineDataX) = $spline->Get(count($dataValuesX) * self::$width / 20); 442 $lplot = new LinePlot($splineDataX, $splineDataY); 443 $lplot->SetColor(self::$colourSet[self::$plotColour]); 444 445 $this->graph->Add($lplot); 446 } 447 448 if ($bubble) { 449 $this->formatPointMarker($seriesPlot, 'dot'); 450 $seriesPlot->mark->SetColor('black'); 451 $seriesPlot->mark->SetSize($bubbleSize); 452 } else { 453 $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); 454 $this->formatPointMarker($seriesPlot, $marker); 455 } 456 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); 457 $seriesPlot->SetLegend($dataLabel); 458 459 $this->graph->Add($seriesPlot); 460 } 461 } 462 463 464 private function renderPlotRadar($groupID) 465 { 466 $radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); 467 468 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); 469 $seriesPlots = array(); 470 471 // Loop through each data series in turn 472 for ($i = 0; $i < $seriesCount; ++$i) { 473 $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); 474 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); 475 $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); 476 477 $dataValues = array(); 478 foreach ($dataValuesY as $k => $dataValueY) { 479 $dataValues[$k] = implode(' ', array_reverse($dataValueY)); 480 } 481 $tmp = array_shift($dataValues); 482 $dataValues[] = $tmp; 483 $tmp = array_shift($dataValuesX); 484 $dataValuesX[] = $tmp; 485 486 $this->graph->SetTitles(array_reverse($dataValues)); 487 488 $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); 489 490 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); 491 $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); 492 if ($radarStyle == 'filled') { 493 $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour]); 494 } 495 $this->formatPointMarker($seriesPlot, $marker); 496 $seriesPlot->SetLegend($dataLabel); 497 498 $this->graph->Add($seriesPlot); 499 } 500 } 501 502 503 private function renderPlotContour($groupID) 504 { 505 $contourStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); 506 507 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); 508 $seriesPlots = array(); 509 510 $dataValues = array(); 511 // Loop through each data series in turn 512 for ($i = 0; $i < $seriesCount; ++$i) { 513 $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); 514 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); 515 516 $dataValues[$i] = $dataValuesX; 517 } 518 $seriesPlot = new ContourPlot($dataValues); 519 520 $this->graph->Add($seriesPlot); 521 } 522 523 524 private function renderPlotStock($groupID) 525 { 526 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); 527 $plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); 528 529 $dataValues = array(); 530 // Loop through each data series in turn and build the plot arrays 531 foreach ($plotOrder as $i => $v) { 532 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); 533 foreach ($dataValuesX as $j => $dataValueX) { 534 $dataValues[$plotOrder[$i]][$j] = $dataValueX; 535 } 536 } 537 if (empty($dataValues)) { 538 return; 539 } 540 541 $dataValuesPlot = array(); 542 // Flatten the plot arrays to a single dimensional array to work with jpgraph 543 for ($j = 0; $j < count($dataValues[0]); ++$j) { 544 for ($i = 0; $i < $seriesCount; ++$i) { 545 $dataValuesPlot[] = $dataValues[$i][$j]; 546 } 547 } 548 549 // Set the x-axis labels 550 $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); 551 if ($labelCount > 0) { 552 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); 553 $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); 554 $this->graph->xaxis->SetTickLabels($datasetLabels); 555 } 556 557 $seriesPlot = new StockPlot($dataValuesPlot); 558 $seriesPlot->SetWidth(20); 559 560 $this->graph->Add($seriesPlot); 561 } 562 563 564 private function renderAreaChart($groupCount, $dimensions = '2d') 565 { 566 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); 567 568 $this->renderCartesianPlotArea(); 569 570 for ($i = 0; $i < $groupCount; ++$i) { 571 $this->renderPlotLine($i, true, false, $dimensions); 572 } 573 } 574 575 576 private function renderLineChart($groupCount, $dimensions = '2d') 577 { 578 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); 579 580 $this->renderCartesianPlotArea(); 581 582 for ($i = 0; $i < $groupCount; ++$i) { 583 $this->renderPlotLine($i, false, false, $dimensions); 584 } 585 } 586 587 588 private function renderBarChart($groupCount, $dimensions = '2d') 589 { 590 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); 591 592 $this->renderCartesianPlotArea(); 593 594 for ($i = 0; $i < $groupCount; ++$i) { 595 $this->renderPlotBar($i, $dimensions); 596 } 597 } 598 599 600 private function renderScatterChart($groupCount) 601 { 602 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); 603 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); 604 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); 605 606 $this->renderCartesianPlotArea('linlin'); 607 608 for ($i = 0; $i < $groupCount; ++$i) { 609 $this->renderPlotScatter($i, false); 610 } 611 } 612 613 614 private function renderBubbleChart($groupCount) 615 { 616 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); 617 618 $this->renderCartesianPlotArea('linlin'); 619 620 for ($i = 0; $i < $groupCount; ++$i) { 621 $this->renderPlotScatter($i, true); 622 } 623 } 624 625 626 private function renderPieChart($groupCount, $dimensions = '2d', $doughnut = false, $multiplePlots = false) 627 { 628 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php'); 629 if ($dimensions == '3d') { 630 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php'); 631 } 632 633 $this->renderPiePlotArea($doughnut); 634 635 $iLimit = ($multiplePlots) ? $groupCount : 1; 636 for ($groupID = 0; $groupID < $iLimit; ++$groupID) { 637 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); 638 $exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); 639 if ($groupID == 0) { 640 $labelCount = count($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); 641 if ($labelCount > 0) { 642 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); 643 $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); 644 } 645 } 646 647 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); 648 $seriesPlots = array(); 649 // For pie charts, we only display the first series: doughnut charts generally display all series 650 $jLimit = ($multiplePlots) ? $seriesCount : 1; 651 // Loop through each data series in turn 652 for ($j = 0; $j < $jLimit; ++$j) { 653 $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); 654 655 // Fill in any missing values in the $dataValues array 656 $testCurrentIndex = 0; 657 foreach ($dataValues as $k => $dataValue) { 658 while ($k != $testCurrentIndex) { 659 $dataValues[$testCurrentIndex] = null; 660 ++$testCurrentIndex; 661 } 662 ++$testCurrentIndex; 663 } 664 665 if ($dimensions == '3d') { 666 $seriesPlot = new PiePlot3D($dataValues); 667 } else { 668 if ($doughnut) { 669 $seriesPlot = new PiePlotC($dataValues); 670 } else { 671 $seriesPlot = new PiePlot($dataValues); 672 } 673 } 674 675 if ($multiplePlots) { 676 $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); 677 } 678 679 if ($doughnut) { 680 $seriesPlot->SetMidColor('white'); 681 } 682 683 $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]); 684 if (count($datasetLabels) > 0) { 685 $seriesPlot->SetLabels(array_fill(0, count($datasetLabels), '')); 686 } 687 if ($dimensions != '3d') { 688 $seriesPlot->SetGuideLines(false); 689 } 690 if ($j == 0) { 691 if ($exploded) { 692 $seriesPlot->ExplodeAll(); 693 } 694 $seriesPlot->SetLegends($datasetLabels); 695 } 696 697 $this->graph->Add($seriesPlot); 698 } 699 } 700 } 701 702 703 private function renderRadarChart($groupCount) 704 { 705 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php'); 706 707 $this->renderRadarPlotArea(); 708 709 for ($groupID = 0; $groupID < $groupCount; ++$groupID) { 710 $this->renderPlotRadar($groupID); 711 } 712 } 713 714 715 private function renderStockChart($groupCount) 716 { 717 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php'); 718 719 $this->renderCartesianPlotArea('intint'); 720 721 for ($groupID = 0; $groupID < $groupCount; ++$groupID) { 722 $this->renderPlotStock($groupID); 723 } 724 } 725 726 727 private function renderContourChart($groupCount, $dimensions) 728 { 729 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php'); 730 731 $this->renderCartesianPlotArea('intint'); 732 733 for ($i = 0; $i < $groupCount; ++$i) { 734 $this->renderPlotContour($i); 735 } 736 } 737 738 739 private function renderCombinationChart($groupCount, $dimensions, $outputDestination) 740 { 741 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); 742 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php'); 743 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php'); 744 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php'); 745 require_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php'); 746 747 $this->renderCartesianPlotArea(); 748 749 for ($i = 0; $i < $groupCount; ++$i) { 750 $dimensions = null; 751 $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); 752 switch ($chartType) { 753 case 'area3DChart': 754 $dimensions = '3d'; 755 // no break 756 case 'areaChart': 757 $this->renderPlotLine($i, true, true, $dimensions); 758 break; 759 case 'bar3DChart': 760 $dimensions = '3d'; 761 // no break 762 case 'barChart': 763 $this->renderPlotBar($i, $dimensions); 764 break; 765 case 'line3DChart': 766 $dimensions = '3d'; 767 // no break 768 case 'lineChart': 769 $this->renderPlotLine($i, false, true, $dimensions); 770 break; 771 case 'scatterChart': 772 $this->renderPlotScatter($i, false); 773 break; 774 case 'bubbleChart': 775 $this->renderPlotScatter($i, true); 776 break; 777 default: 778 $this->graph = null; 779 return false; 780 } 781 } 782 783 $this->renderLegend(); 784 785 $this->graph->Stroke($outputDestination); 786 return true; 787 } 788 789 790 public function render($outputDestination) 791 { 792 self::$plotColour = 0; 793 794 $groupCount = $this->chart->getPlotArea()->getPlotGroupCount(); 795 796 $dimensions = null; 797 if ($groupCount == 1) { 798 $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); 799 } else { 800 $chartTypes = array(); 801 for ($i = 0; $i < $groupCount; ++$i) { 802 $chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); 803 } 804 $chartTypes = array_unique($chartTypes); 805 if (count($chartTypes) == 1) { 806 $chartType = array_pop($chartTypes); 807 } elseif (count($chartTypes) == 0) { 808 echo 'Chart is not yet implemented<br />'; 809 return false; 810 } else { 811 return $this->renderCombinationChart($groupCount, $dimensions, $outputDestination); 812 } 813 } 814 815 switch ($chartType) { 816 case 'area3DChart': 817 $dimensions = '3d'; 818 // no break 819 case 'areaChart': 820 $this->renderAreaChart($groupCount, $dimensions); 821 break; 822 case 'bar3DChart': 823 $dimensions = '3d'; 824 // no break 825 case 'barChart': 826 $this->renderBarChart($groupCount, $dimensions); 827 break; 828 case 'line3DChart': 829 $dimensions = '3d'; 830 // no break 831 case 'lineChart': 832 $this->renderLineChart($groupCount, $dimensions); 833 break; 834 case 'pie3DChart': 835 $dimensions = '3d'; 836 // no break 837 case 'pieChart': 838 $this->renderPieChart($groupCount, $dimensions, false, false); 839 break; 840 case 'doughnut3DChart': 841 $dimensions = '3d'; 842 // no break 843 case 'doughnutChart': 844 $this->renderPieChart($groupCount, $dimensions, true, true); 845 break; 846 case 'scatterChart': 847 $this->renderScatterChart($groupCount); 848 break; 849 case 'bubbleChart': 850 $this->renderBubbleChart($groupCount); 851 break; 852 case 'radarChart': 853 $this->renderRadarChart($groupCount); 854 break; 855 case 'surface3DChart': 856 $dimensions = '3d'; 857 // no break 858 case 'surfaceChart': 859 $this->renderContourChart($groupCount, $dimensions); 860 break; 861 case 'stockChart': 862 $this->renderStockChart($groupCount, $dimensions); 863 break; 864 default: 865 echo $chartType.' is not yet implemented<br />'; 866 return false; 867 } 868 $this->renderLegend(); 869 870 $this->graph->Stroke($outputDestination); 871 return true; 872 } 873 874 875 /** 876 * Create a new PHPExcel_Chart_Renderer_jpgraph 877 */ 878 public function __construct(PHPExcel_Chart $chart) 879 { 880 $this->graph = null; 881 $this->chart = $chart; 882 } 883 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |