31 'mediumpurple1',
'palegreen3',
'gold1',
'cadetblue1',
32 'darkmagenta',
'coral',
'dodgerblue3',
'eggplant',
33 'mediumblue',
'magenta',
'sandybrown',
'cyan',
34 'firebrick1',
'forestgreen',
'deeppink4',
'darkolivegreen',
58 private static function init(): void
60 static $loaded =
false;
65 \JpGraph\JpGraph::load();
66 \JpGraph\JpGraph::module(
'bar');
67 \JpGraph\JpGraph::module(
'contour');
68 \JpGraph\JpGraph::module(
'line');
69 \JpGraph\JpGraph::module(
'pie');
70 \JpGraph\JpGraph::module(
'pie3d');
71 \JpGraph\JpGraph::module(
'radar');
72 \JpGraph\JpGraph::module(
'regstat');
73 \JpGraph\JpGraph::module(
'scatter');
74 \JpGraph\JpGraph::module(
'stock');
77 'diamond' => MARK_DIAMOND,
78 'square' => MARK_SQUARE,
79 'triangle' => MARK_UTRIANGLE,
82 'dot' => MARK_FILLEDCIRCLE,
83 'dash' => MARK_DTRIANGLE,
84 'circle' => MARK_CIRCLE,
93 $plotMarkKeys = array_keys(self::$markSet);
94 if ($markerID === null) {
96 self::$plotMark %= count(self::$markSet);
97 $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]);
98 } elseif ($markerID !==
'none') {
100 if (isset(self::$markSet[$markerID])) {
101 $seriesPlot->mark->SetType(self::$markSet[$markerID]);
104 self::$plotMark %= count(self::$markSet);
105 $seriesPlot->mark->SetType(self::$markSet[$plotMarkKeys[self::$plotMark++]]);
109 $seriesPlot->mark->Hide();
111 $seriesPlot->mark->SetColor(self::$colourSet[self::$plotColour]);
112 $seriesPlot->mark->SetFillColor(self::$colourSet[self::$plotColour]);
113 $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]);
120 $datasetLabelFormatCode = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode();
121 if ($datasetLabelFormatCode !== null) {
123 $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode);
126 $testCurrentIndex = 0;
127 foreach ($datasetLabels as
$i => $datasetLabel) {
128 if (is_array($datasetLabel)) {
129 if ($rotation ==
'bar') {
130 $datasetLabels[
$i] = implode(
' ', $datasetLabel);
132 $datasetLabel = array_reverse($datasetLabel);
133 $datasetLabels[
$i] = implode(
"\n", $datasetLabel);
137 if ($datasetLabelFormatCode !== null) {
144 return $datasetLabels;
151 for (
$i = 0;
$i < $seriesCount; ++
$i) {
153 $sumValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getDataValues();
155 $nextValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getDataValues();
156 foreach ($nextValues as $k => $value) {
157 if (isset($sumValues[$k])) {
158 $sumValues[$k] += $value;
160 $sumValues[$k] = $value;
171 foreach ($dataValues as $k => $dataValue) {
172 $dataValues[$k] = $dataValue / $sumValues[$k] * 100;
181 $caption = ($captionElement !== null) ? $captionElement->getCaption() : null;
183 if ($caption !== null) {
185 if (is_array($caption)) {
187 $caption = implode(
'', $caption);
198 $this->graph->title->Set(
$title);
204 $legend = $this->chart->getLegend();
206 $legendPosition =
$legend->getPosition();
207 switch ($legendPosition) {
209 $this->graph->legend->SetPos(0.01, 0.5,
'right',
'center');
210 $this->graph->legend->SetColumns(1);
214 $this->graph->legend->SetPos(0.01, 0.5,
'left',
'center');
215 $this->graph->legend->SetColumns(1);
219 $this->graph->legend->SetPos(0.5, 0.01,
'center',
'top');
223 $this->graph->legend->SetPos(0.5, 0.99,
'center',
'bottom');
227 $this->graph->legend->SetPos(0.01, 0.01,
'right',
'top');
228 $this->graph->legend->SetColumns(1);
233 $this->graph->legend->Hide();
239 $this->graph =
new Graph(self::$width, self::$height);
240 $this->graph->SetScale(
$type);
245 $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection();
246 $reverse = $rotation ==
'bar';
248 $xAxisLabel = $this->chart->getXAxisLabel();
249 if ($xAxisLabel !== null) {
252 $this->graph->xaxis->SetTitle(
$title,
'center');
253 $this->graph->xaxis->title->SetMargin(35);
255 $this->graph->xaxis->title->SetAngle(90);
256 $this->graph->xaxis->title->SetMargin(90);
261 $yAxisLabel = $this->chart->getYAxisLabel();
262 if ($yAxisLabel !== null) {
265 $this->graph->yaxis->SetTitle(
$title,
'center');
267 $this->graph->yaxis->title->SetAngle(0);
268 $this->graph->yaxis->title->SetMargin(-55);
276 $this->graph =
new PieGraph(self::$width, self::$height);
283 $this->graph =
new RadarGraph(self::$width, self::$height);
284 $this->graph->SetScale(
'lin');
289 private function renderPlotLine($groupID, $filled =
false, $combination =
false, $dimensions =
'2d'): void
291 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
293 $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount();
294 if ($labelCount > 0) {
295 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
297 $this->graph->xaxis->SetTickLabels($datasetLabels);
300 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
302 if ($grouping ==
'percentStacked') {
309 for (
$i = 0;
$i < $seriesCount; ++
$i) {
310 $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getDataValues();
311 $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getPointMarker();
313 if ($grouping ==
'percentStacked') {
318 $testCurrentIndex = 0;
319 foreach ($dataValues as $k => $dataValue) {
320 while ($k != $testCurrentIndex) {
321 $dataValues[$testCurrentIndex] = null;
327 $seriesPlot =
new LinePlot($dataValues);
329 $seriesPlot->SetBarCenter();
333 $seriesPlot->SetFilled(
true);
334 $seriesPlot->SetColor(
'black');
335 $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]);
340 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex(
$i)->getDataValue();
341 $seriesPlot->SetLegend($dataLabel);
343 $seriesPlots[] = $seriesPlot;
346 if ($grouping ==
'standard') {
347 $groupPlot = $seriesPlots;
351 $this->graph->Add($groupPlot);
356 $rotation = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection();
358 if (($groupID == 0) && ($rotation ==
'bar')) {
359 $this->graph->Set90AndMargin();
361 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
363 $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount();
364 if ($labelCount > 0) {
365 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
366 $datasetLabels = $this->
formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation);
368 if ($rotation ==
'bar') {
369 $datasetLabels = array_reverse($datasetLabels);
370 $this->graph->yaxis->SetPos(
'max');
371 $this->graph->yaxis->SetLabelAlign(
'center',
'top');
372 $this->graph->yaxis->SetLabelSide(SIDE_RIGHT);
374 $this->graph->xaxis->SetTickLabels($datasetLabels);
377 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
379 if ($grouping ==
'percentStacked') {
386 for ($j = 0; $j < $seriesCount; ++$j) {
387 $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues();
388 if ($grouping ==
'percentStacked') {
393 $testCurrentIndex = 0;
394 foreach ($dataValues as $k => $dataValue) {
395 while ($k != $testCurrentIndex) {
396 $dataValues[$testCurrentIndex] = null;
403 if ($rotation ==
'bar') {
404 $dataValues = array_reverse($dataValues);
406 $seriesPlot =
new BarPlot($dataValues);
407 $seriesPlot->SetColor(
'black');
408 $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour++]);
409 if ($dimensions ==
'3d') {
410 $seriesPlot->SetShadow();
412 if (!$this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) {
415 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue();
417 $seriesPlot->SetLegend($dataLabel);
419 $seriesPlots[] = $seriesPlot;
422 if (($rotation ==
'bar') && ($grouping !=
'percentStacked')) {
423 $seriesPlots = array_reverse($seriesPlots);
426 if ($grouping ==
'clustered') {
428 } elseif ($grouping ==
'standard') {
432 if ($dimensions ==
'3d') {
433 $groupPlot->SetShadow();
437 $this->graph->Add($groupPlot);
442 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
443 $scatterStyle = $bubbleSize = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
445 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
449 for (
$i = 0;
$i < $seriesCount; ++
$i) {
450 $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(
$i)->getDataValues();
451 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getDataValues();
453 foreach ($dataValuesY as $k => $dataValueY) {
454 $dataValuesY[$k] = $k;
457 $seriesPlot =
new ScatterPlot($dataValuesX, $dataValuesY);
458 if ($scatterStyle ==
'lineMarker') {
459 $seriesPlot->SetLinkPoints();
460 $seriesPlot->link->SetColor(self::$colourSet[self::$plotColour]);
461 } elseif ($scatterStyle ==
'smoothMarker') {
462 $spline =
new Spline($dataValuesY, $dataValuesX);
463 [$splineDataY, $splineDataX] = $spline->Get(count($dataValuesX) * self::$width / 20);
464 $lplot =
new LinePlot($splineDataX, $splineDataY);
465 $lplot->SetColor(self::$colourSet[self::$plotColour]);
467 $this->graph->Add($lplot);
472 $seriesPlot->mark->SetColor(
'black');
473 $seriesPlot->mark->SetSize($bubbleSize);
475 $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getPointMarker();
478 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex(
$i)->getDataValue();
479 $seriesPlot->SetLegend($dataLabel);
481 $this->graph->Add($seriesPlot);
487 $radarStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
489 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
493 for (
$i = 0;
$i < $seriesCount; ++
$i) {
494 $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(
$i)->getDataValues();
495 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getDataValues();
496 $marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getPointMarker();
499 foreach ($dataValuesY as $k => $dataValueY) {
500 $dataValues[$k] = implode(
' ', array_reverse($dataValueY));
502 $tmp = array_shift($dataValues);
503 $dataValues[] = $tmp;
504 $tmp = array_shift($dataValuesX);
505 $dataValuesX[] = $tmp;
507 $this->graph->SetTitles(array_reverse($dataValues));
509 $seriesPlot =
new RadarPlot(array_reverse($dataValuesX));
511 $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex(
$i)->getDataValue();
512 $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]);
513 if ($radarStyle ==
'filled') {
514 $seriesPlot->SetFillColor(self::$colourSet[self::$plotColour]);
517 $seriesPlot->SetLegend($dataLabel);
519 $this->graph->Add($seriesPlot);
525 $contourStyle = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
527 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
532 for (
$i = 0;
$i < $seriesCount; ++
$i) {
533 $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(
$i)->getDataValues();
534 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(
$i)->getDataValues();
536 $dataValues[
$i] = $dataValuesX;
540 $this->graph->Add($seriesPlot);
545 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
546 $plotOrder = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder();
550 foreach ($plotOrder as
$i => $v) {
551 $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues();
552 foreach ($dataValuesX as $j => $dataValueX) {
553 $dataValues[$plotOrder[
$i]][$j] = $dataValueX;
556 if (empty($dataValues)) {
560 $dataValuesPlot = [];
562 $jMax = count($dataValues[0]);
563 for ($j = 0; $j < $jMax; ++$j) {
564 for (
$i = 0;
$i < $seriesCount; ++
$i) {
565 $dataValuesPlot[] = $dataValues[
$i][$j];
570 $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount();
571 if ($labelCount > 0) {
572 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
574 $this->graph->xaxis->SetTickLabels($datasetLabels);
577 $seriesPlot =
new StockPlot($dataValuesPlot);
578 $seriesPlot->SetWidth(20);
580 $this->graph->Add($seriesPlot);
587 for (
$i = 0;
$i < $groupCount; ++
$i) {
596 for (
$i = 0;
$i < $groupCount; ++
$i) {
605 for (
$i = 0;
$i < $groupCount; ++
$i) {
614 for (
$i = 0;
$i < $groupCount; ++
$i) {
623 for (
$i = 0;
$i < $groupCount; ++
$i) {
628 private function renderPieChart($groupCount, $dimensions =
'2d', $doughnut =
false, $multiplePlots =
false): void
632 $iLimit = ($multiplePlots) ? $groupCount : 1;
633 for ($groupID = 0; $groupID < $iLimit; ++$groupID) {
634 $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
635 $exploded = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();
638 $labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount();
639 if ($labelCount > 0) {
640 $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
645 $seriesCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();
648 $jLimit = ($multiplePlots) ? $seriesCount : 1;
650 for ($j = 0; $j < $jLimit; ++$j) {
651 $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues();
654 $testCurrentIndex = 0;
655 foreach ($dataValues as $k => $dataValue) {
656 while ($k != $testCurrentIndex) {
657 $dataValues[$testCurrentIndex] = null;
663 if ($dimensions ==
'3d') {
664 $seriesPlot =
new PiePlot3D($dataValues);
667 $seriesPlot =
new PiePlotC($dataValues);
669 $seriesPlot =
new PiePlot($dataValues);
673 if ($multiplePlots) {
674 $seriesPlot->SetSize(($jLimit - $j) / ($jLimit * 4));
678 $seriesPlot->SetMidColor(
'white');
681 $seriesPlot->SetColor(self::$colourSet[self::$plotColour++]);
682 if (count($datasetLabels) > 0) {
683 $seriesPlot->SetLabels(array_fill(0, count($datasetLabels),
''));
685 if ($dimensions !=
'3d') {
686 $seriesPlot->SetGuideLines(
false);
690 $seriesPlot->ExplodeAll();
692 $seriesPlot->SetLegends($datasetLabels);
695 $this->graph->Add($seriesPlot);
704 for ($groupID = 0; $groupID < $groupCount; ++$groupID) {
713 for ($groupID = 0; $groupID < $groupCount; ++$groupID) {
722 for (
$i = 0;
$i < $groupCount; ++
$i) {
731 for (
$i = 0;
$i < $groupCount; ++
$i) {
733 $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(
$i)->getPlotType();
734 switch ($chartType) {
773 $this->graph->Stroke($outputDestination);
778 public function render($outputDestination)
780 self::$plotColour = 0;
782 $groupCount = $this->chart->getPlotArea()->getPlotGroupCount();
785 if ($groupCount == 1) {
786 $chartType = $this->chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
789 for (
$i = 0;
$i < $groupCount; ++
$i) {
790 $chartTypes[] = $this->chart->getPlotArea()->getPlotGroupByIndex(
$i)->getPlotType();
792 $chartTypes = array_unique($chartTypes);
793 if (count($chartTypes) == 1) {
794 $chartType = array_pop($chartTypes);
795 } elseif (count($chartTypes) == 0) {
796 echo 'Chart is not yet implemented<br />';
804 switch ($chartType) {
833 case 'doughnut3DChart':
836 case 'doughnutChart':
852 case 'surface3DChart':
864 echo $chartType .
' is not yet implemented<br />';
870 $this->graph->Stroke($outputDestination);
__construct(Chart $chart)
Create a new jpgraph.
renderPlotStock($groupID)
getCaption($captionElement)
renderCombinationChart($groupCount, $dimensions, $outputDestination)
renderRadarChart($groupCount)
renderPlotScatter($groupID, $bubble)
renderLineChart($groupCount, $dimensions='2d')
renderPlotRadar($groupID)
percentageSumCalculation($groupID, $seriesCount)
percentageAdjustValues($dataValues, $sumValues)
renderPlotContour($groupID)
renderScatterChart($groupCount)
renderPlotLine($groupID, $filled=false, $combination=false, $dimensions='2d')
renderContourChart($groupCount, $dimensions)
renderPieChart($groupCount, $dimensions='2d', $doughnut=false, $multiplePlots=false)
renderAreaChart($groupCount, $dimensions='2d')
render($outputDestination)
Render the chart to given file (or stream).
renderBarChart($groupCount, $dimensions='2d')
renderCartesianPlotArea($type='textlin')
renderBubbleChart($groupCount)
while(count($oldTaskList) > 0) foreach(array_keys($newTaskList) as $task) init()
renderStockChart($groupCount)
formatPointMarker($seriesPlot, $markerID)
renderPlotBar($groupID, $dimensions='2d')
formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation='')