Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
<?php

namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;

use PhpOffice\PhpSpreadsheet\Chart\Axis;
> use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
< use PhpOffice\PhpSpreadsheet\Chart\GridLines;
use PhpOffice\PhpSpreadsheet\Chart\Layout; use PhpOffice\PhpSpreadsheet\Chart\Legend; use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
> use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PhpOffice\PhpSpreadsheet\Chart\Title;
< use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
> use PhpOffice\PhpSpreadsheet\Chart\TrendLine; > use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Namespaces;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter; use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException; class Chart extends WriterPart {
< protected $calculateCellValues; <
/** * @var int */ private $seriesIndex; /** * Write charts to XML format. *
< * @param \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart
* @param mixed $calculateCellValues *
< * @throws WriterException < *
* @return string XML Output */
< public function writeChart(\PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $calculateCellValues = true)
> public function writeChart(\PhpOffice\PhpSpreadsheet\Chart\Chart $chart, $calculateCellValues = true)
{
< $this->calculateCellValues = $calculateCellValues; <
// Create XML writer $objWriter = null; if ($this->getParentWriter()->getUseDiskCaching()) { $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); } else { $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); } // Ensure that data series values are up-to-date before we save
< if ($this->calculateCellValues) { < $pChart->refresh();
> if ($calculateCellValues) { > $chart->refresh();
} // XML header $objWriter->startDocument('1.0', 'UTF-8', 'yes'); // c:chartSpace $objWriter->startElement('c:chartSpace');
< $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); < $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); < $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
> $objWriter->writeAttribute('xmlns:c', Namespaces::CHART); > $objWriter->writeAttribute('xmlns:a', Namespaces::DRAWINGML); > $objWriter->writeAttribute('xmlns:r', Namespaces::SCHEMA_OFFICE_DOCUMENT);
$objWriter->startElement('c:date1904');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
$objWriter->endElement(); $objWriter->startElement('c:lang'); $objWriter->writeAttribute('val', 'en-GB'); $objWriter->endElement(); $objWriter->startElement('c:roundedCorners');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', $chart->getRoundedCorners() ? '1' : '0');
$objWriter->endElement(); $this->writeAlternateContent($objWriter); $objWriter->startElement('c:chart');
< $this->writeTitle($objWriter, $pChart->getTitle());
> $this->writeTitle($objWriter, $chart->getTitle());
$objWriter->startElement('c:autoTitleDeleted');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', (string) (int) $chart->getAutoTitleDeleted());
$objWriter->endElement();
< $this->writePlotArea($objWriter, $pChart->getWorksheet(), $pChart->getPlotArea(), $pChart->getXAxisLabel(), $pChart->getYAxisLabel(), $pChart->getChartAxisX(), $pChart->getChartAxisY(), $pChart->getMajorGridlines(), $pChart->getMinorGridlines());
> $objWriter->startElement('c:view3D'); > $surface2D = false; > $plotArea = $chart->getPlotArea(); > if ($plotArea !== null) { > $seriesArray = $plotArea->getPlotGroup(); > foreach ($seriesArray as $series) { > if ($series->getPlotType() === DataSeries::TYPE_SURFACECHART) { > $surface2D = true; > > break; > } > } > } > $this->writeView3D($objWriter, $chart->getRotX(), 'c:rotX', $surface2D, 90); > $this->writeView3D($objWriter, $chart->getRotY(), 'c:rotY', $surface2D); > $this->writeView3D($objWriter, $chart->getRAngAx(), 'c:rAngAx', $surface2D); > $this->writeView3D($objWriter, $chart->getPerspective(), 'c:perspective', $surface2D); > $objWriter->endElement(); // view3D > > $this->writePlotArea($objWriter, $chart->getPlotArea(), $chart->getXAxisLabel(), $chart->getYAxisLabel(), $chart->getChartAxisX(), $chart->getChartAxisY());
< $this->writeLegend($objWriter, $pChart->getLegend());
> $this->writeLegend($objWriter, $chart->getLegend());
$objWriter->startElement('c:plotVisOnly');
< $objWriter->writeAttribute('val', (int) $pChart->getPlotVisibleOnly());
> $objWriter->writeAttribute('val', (string) (int) $chart->getPlotVisibleOnly());
$objWriter->endElement(); $objWriter->startElement('c:dispBlanksAs');
< $objWriter->writeAttribute('val', $pChart->getDisplayBlanksAs());
> $objWriter->writeAttribute('val', $chart->getDisplayBlanksAs());
$objWriter->endElement(); $objWriter->startElement('c:showDLblsOverMax');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
$objWriter->endElement();
< $objWriter->endElement();
> $objWriter->endElement(); // c:chart > if ($chart->getNoFill()) { > $objWriter->startElement('c:spPr'); > $objWriter->startElement('a:noFill'); > $objWriter->endElement(); // a:noFill > $objWriter->endElement(); // c:spPr > }
$this->writePrintSettings($objWriter);
< $objWriter->endElement();
> $objWriter->endElement(); // c:chartSpace
// Return return $objWriter->getData(); }
> private function writeView3D(XMLWriter $objWriter, ?int $value, string $tag, bool $surface2D, int $default = 0): void /** > { * Write Chart Title. > if ($value === null && $surface2D) { * > $value = $default; * @param XMLWriter $objWriter XML Writer > } * @param Title $title > if ($value !== null) { * > $objWriter->startElement($tag); * @throws WriterException > $objWriter->writeAttribute('val', "$value"); */ > $objWriter->endElement(); private function writeTitle(XMLWriter $objWriter, Title $title = null) > } { > } if ($title === null) { >
< * < * @param XMLWriter $objWriter XML Writer < * @param Title $title < * < * @throws WriterException
< private function writeTitle(XMLWriter $objWriter, Title $title = null)
> private function writeTitle(XMLWriter $objWriter, ?Title $title = null): void
$objWriter->startElement('a:bodyPr'); $objWriter->endElement(); $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); $objWriter->startElement('a:p');
> $objWriter->startElement('a:pPr'); > $objWriter->startElement('a:defRPr'); $caption = $title->getCaption(); > $objWriter->endElement(); if ((is_array($caption)) && (count($caption) > 0)) { > $objWriter->endElement();
$caption = $caption[0]; }
< $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a');
> $this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a');
$objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $this->writeLayout($objWriter, $title->getLayout()); $objWriter->startElement('c:overlay');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', ($title->getOverlay()) ? '1' : '0');
$objWriter->endElement(); $objWriter->endElement(); } /** * Write Chart Legend.
< * < * @param XMLWriter $objWriter XML Writer < * @param Legend $legend < * < * @throws WriterException
*/
< private function writeLegend(XMLWriter $objWriter, Legend $legend = null)
> private function writeLegend(XMLWriter $objWriter, ?Legend $legend = null): void
{ if ($legend === null) { return; } $objWriter->startElement('c:legend'); $objWriter->startElement('c:legendPos'); $objWriter->writeAttribute('val', $legend->getPosition()); $objWriter->endElement(); $this->writeLayout($objWriter, $legend->getLayout()); $objWriter->startElement('c:overlay'); $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); $objWriter->endElement(); $objWriter->startElement('c:txPr'); $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); $objWriter->startElement('a:p'); $objWriter->startElement('a:pPr');
< $objWriter->writeAttribute('rtl', 0);
> $objWriter->writeAttribute('rtl', '0');
$objWriter->startElement('a:defRPr'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('a:endParaRPr'); $objWriter->writeAttribute('lang', 'en-US'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } /** * Write Chart Plot Area.
< * < * @param XMLWriter $objWriter XML Writer < * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pSheet < * @param PlotArea $plotArea < * @param Title $xAxisLabel < * @param Title $yAxisLabel < * @param Axis $xAxis < * @param Axis $yAxis < * @param null|GridLines $majorGridlines < * @param null|GridLines $minorGridlines < * < * @throws WriterException
*/
< private function writePlotArea(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pSheet, PlotArea $plotArea, Title $xAxisLabel = null, Title $yAxisLabel = null, Axis $xAxis = null, Axis $yAxis = null, GridLines $majorGridlines = null, GridLines $minorGridlines = null)
> private function writePlotArea(XMLWriter $objWriter, ?PlotArea $plotArea, ?Title $xAxisLabel = null, ?Title $yAxisLabel = null, ?Axis $xAxis = null, ?Axis $yAxis = null): void
{ if ($plotArea === null) { return; }
< $id1 = $id2 = 0;
> $id1 = $id2 = $id3 = '0';
$this->seriesIndex = 0; $objWriter->startElement('c:plotArea'); $layout = $plotArea->getLayout(); $this->writeLayout($objWriter, $layout); $chartTypes = self::getChartType($plotArea); $catIsMultiLevelSeries = $valIsMultiLevelSeries = false; $plotGroupingType = '';
> $chartType = null;
foreach ($chartTypes as $chartType) { $objWriter->startElement('c:' . $chartType); $groupCount = $plotArea->getPlotGroupCount();
> $plotGroup = null;
for ($i = 0; $i < $groupCount; ++$i) { $plotGroup = $plotArea->getPlotGroupByIndex($i); $groupType = $plotGroup->getPlotType(); if ($groupType == $chartType) { $plotStyle = $plotGroup->getPlotStyle();
< if ($groupType === DataSeries::TYPE_RADARCHART) {
> if (!empty($plotStyle) && $groupType === DataSeries::TYPE_RADARCHART) {
$objWriter->startElement('c:radarStyle'); $objWriter->writeAttribute('val', $plotStyle); $objWriter->endElement();
< } elseif ($groupType === DataSeries::TYPE_SCATTERCHART) {
> } elseif (!empty($plotStyle) && $groupType === DataSeries::TYPE_SCATTERCHART) {
$objWriter->startElement('c:scatterStyle'); $objWriter->writeAttribute('val', $plotStyle); $objWriter->endElement();
> } elseif ($groupType === DataSeries::TYPE_SURFACECHART_3D || $groupType === DataSeries::TYPE_SURFACECHART) { } > $objWriter->startElement('c:wireframe'); > $objWriter->writeAttribute('val', $plotStyle ? '1' : '0'); $this->writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType); > $objWriter->endElement();
} } $this->writeDataLabels($objWriter, $layout);
< if ($chartType === DataSeries::TYPE_LINECHART) {
> if ($chartType === DataSeries::TYPE_LINECHART && $plotGroup) {
// Line only, Line3D can't be smoothed $objWriter->startElement('c:smooth');
< $objWriter->writeAttribute('val', (int) $plotGroup->getSmoothLine());
> $objWriter->writeAttribute('val', (string) (int) $plotGroup->getSmoothLine());
$objWriter->endElement(); } elseif (($chartType === DataSeries::TYPE_BARCHART) || ($chartType === DataSeries::TYPE_BARCHART_3D)) { $objWriter->startElement('c:gapWidth');
< $objWriter->writeAttribute('val', 150);
> $objWriter->writeAttribute('val', '150');
$objWriter->endElement(); if ($plotGroupingType == 'percentStacked' || $plotGroupingType == 'stacked') { $objWriter->startElement('c:overlap');
< $objWriter->writeAttribute('val', 100);
> $objWriter->writeAttribute('val', '100');
$objWriter->endElement(); } } elseif ($chartType === DataSeries::TYPE_BUBBLECHART) {
> $scale = ($plotGroup === null) ? '' : (string) $plotGroup->getPlotStyle(); $objWriter->startElement('c:bubbleScale'); > if ($scale !== '') {
< $objWriter->writeAttribute('val', 25);
> $objWriter->writeAttribute('val', $scale);
$objWriter->endElement();
> }
$objWriter->startElement('c:showNegBubbles');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
$objWriter->endElement(); } elseif ($chartType === DataSeries::TYPE_STOCKCHART) { $objWriter->startElement('c:hiLowLines'); $objWriter->endElement(); $objWriter->startElement('c:upDownBars'); $objWriter->startElement('c:gapWidth');
< $objWriter->writeAttribute('val', 300);
> $objWriter->writeAttribute('val', '300');
$objWriter->endElement(); $objWriter->startElement('c:upBars'); $objWriter->endElement(); $objWriter->startElement('c:downBars'); $objWriter->endElement(); $objWriter->endElement(); }
< // Generate 2 unique numbers to use for axId values < $id1 = '75091328'; < $id2 = '75089408';
> // Generate 3 unique numbers to use for axId values > $id1 = '110438656'; > $id2 = '110444544'; > $id3 = '110365312'; // used in Surface Chart
if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) { $objWriter->startElement('c:axId'); $objWriter->writeAttribute('val', $id1); $objWriter->endElement(); $objWriter->startElement('c:axId'); $objWriter->writeAttribute('val', $id2); $objWriter->endElement();
> if ($chartType === DataSeries::TYPE_SURFACECHART_3D || $chartType === DataSeries::TYPE_SURFACECHART) { } else { > $objWriter->startElement('c:axId'); $objWriter->startElement('c:firstSliceAng'); > $objWriter->writeAttribute('val', $id3); $objWriter->writeAttribute('val', 0); > $objWriter->endElement(); $objWriter->endElement(); > }
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
if ($chartType === DataSeries::TYPE_DONUTCHART) { $objWriter->startElement('c:holeSize');
< $objWriter->writeAttribute('val', 50);
> $objWriter->writeAttribute('val', '50');
$objWriter->endElement(); } } $objWriter->endElement(); } if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) { if ($chartType === DataSeries::TYPE_BUBBLECHART) {
< $this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
> $this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id2, $id1, $catIsMultiLevelSeries, $xAxis ?? new Axis());
} else {
< $this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $yAxis);
> $this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $xAxis ?? new Axis()); > } > > $this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $yAxis ?? new Axis()); > if ($chartType === DataSeries::TYPE_SURFACECHART_3D || $chartType === DataSeries::TYPE_SURFACECHART) { > $this->writeSerAxis($objWriter, $id2, $id3); > } > } > $stops = $plotArea->getGradientFillStops(); > if ($plotArea->getNoFill() || !empty($stops)) { > $objWriter->startElement('c:spPr'); > if ($plotArea->getNoFill()) { > $objWriter->startElement('a:noFill'); > $objWriter->endElement(); // a:noFill > } > if (!empty($stops)) { > $objWriter->startElement('a:gradFill'); > $objWriter->startElement('a:gsLst'); > foreach ($stops as $stop) { > $objWriter->startElement('a:gs'); > $objWriter->writeAttribute('pos', (string) (Properties::PERCENTAGE_MULTIPLIER * (float) $stop[0])); > $this->writeColor($objWriter, $stop[1], false); > $objWriter->endElement(); // a:gs > } > $objWriter->endElement(); // a:gsLst > $angle = $plotArea->getGradientFillAngle(); > if ($angle !== null) { > $objWriter->startElement('a:lin'); > $objWriter->writeAttribute('ang', Properties::angleToXml($angle)); > $objWriter->endElement(); // a:lin > } > $objWriter->endElement(); // a:gradFill > } > $objWriter->endElement(); // c:spPr
}
< $this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
> $objWriter->endElement(); // c:plotArea
}
> private function writeDataLabelsBool(XMLWriter $objWriter, string $name, ?bool $value): void $objWriter->endElement(); > { } > if ($value !== null) { > $objWriter->startElement("c:$name"); /** > $objWriter->writeAttribute('val', $value ? '1' : '0');
* Write Data Labels.
> }
< * < * @param XMLWriter $objWriter XML Writer < * @param \PhpOffice\PhpSpreadsheet\Chart\Layout $chartLayout Chart layout
*/
< private function writeDataLabels(XMLWriter $objWriter, Layout $chartLayout = null)
> private function writeDataLabels(XMLWriter $objWriter, ?Layout $chartLayout = null): void
{
> if (!isset($chartLayout)) { $objWriter->startElement('c:dLbls'); > return; > }
< $objWriter->startElement('c:showLegendKey'); < $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); < $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1)); < $objWriter->endElement(); < < $objWriter->startElement('c:showVal'); < $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); < $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1)); < $objWriter->endElement();
> $fillColor = $chartLayout->getLabelFillColor(); > $borderColor = $chartLayout->getLabelBorderColor(); > if ($fillColor && $fillColor->isUsable()) { > $objWriter->startElement('c:spPr'); > $this->writeColor($objWriter, $fillColor); > if ($borderColor && $borderColor->isUsable()) { > $objWriter->startElement('a:ln'); > $this->writeColor($objWriter, $borderColor); > $objWriter->endElement(); // a:ln > } > $objWriter->endElement(); // c:spPr > } > $fontColor = $chartLayout->getLabelFontColor(); > if ($fontColor && $fontColor->isUsable()) { > $objWriter->startElement('c:txPr');
< $objWriter->startElement('c:showCatName'); < $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); < $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1)); < $objWriter->endElement();
> $objWriter->startElement('a:bodyPr'); > $objWriter->writeAttribute('wrap', 'square'); > $objWriter->writeAttribute('lIns', '38100'); > $objWriter->writeAttribute('tIns', '19050'); > $objWriter->writeAttribute('rIns', '38100'); > $objWriter->writeAttribute('bIns', '19050'); > $objWriter->writeAttribute('anchor', 'ctr'); > $objWriter->startElement('a:spAutoFit'); > $objWriter->endElement(); // a:spAutoFit > $objWriter->endElement(); // a:bodyPr
< $objWriter->startElement('c:showSerName'); < $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); < $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1)); < $objWriter->endElement();
> $objWriter->startElement('a:lstStyle'); > $objWriter->endElement(); // a:lstStyle
< $objWriter->startElement('c:showPercent'); < $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); < $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1)); < $objWriter->endElement();
> $objWriter->startElement('a:p'); > $objWriter->startElement('a:pPr'); > $objWriter->startElement('a:defRPr'); > $this->writeColor($objWriter, $fontColor); > $objWriter->endElement(); // a:defRPr > $objWriter->endElement(); // a:pPr > $objWriter->endElement(); // a:p
< $objWriter->startElement('c:showBubbleSize'); < $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); < $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1)); < $objWriter->endElement();
> $objWriter->endElement(); // c:txPr > }
< $objWriter->startElement('c:showLeaderLines'); < $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); < $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1)); < $objWriter->endElement();
> if ($chartLayout->getNumFmtCode() !== '') { > $objWriter->startElement('c:numFmt'); > $objWriter->writeAttribute('formatCode', $chartLayout->getnumFmtCode()); > $objWriter->writeAttribute('sourceLinked', (string) (int) $chartLayout->getnumFmtLinked()); > $objWriter->endElement(); // c:numFmt > } > if ($chartLayout->getDLblPos() !== '') { > $objWriter->startElement('c:dLblPos'); > $objWriter->writeAttribute('val', $chartLayout->getDLblPos()); > $objWriter->endElement(); // c:dLblPos > } > $this->writeDataLabelsBool($objWriter, 'showLegendKey', $chartLayout->getShowLegendKey()); > $this->writeDataLabelsBool($objWriter, 'showVal', $chartLayout->getShowVal()); > $this->writeDataLabelsBool($objWriter, 'showCatName', $chartLayout->getShowCatName()); > $this->writeDataLabelsBool($objWriter, 'showSerName', $chartLayout->getShowSerName()); > $this->writeDataLabelsBool($objWriter, 'showPercent', $chartLayout->getShowPercent()); > $this->writeDataLabelsBool($objWriter, 'showBubbleSize', $chartLayout->getShowBubbleSize()); > $this->writeDataLabelsBool($objWriter, 'showLeaderLines', $chartLayout->getShowLeaderLines());
< $objWriter->endElement();
> $objWriter->endElement(); // c:dLbls
} /** * Write Category Axis. *
< * @param XMLWriter $objWriter XML Writer < * @param Title $xAxisLabel
* @param string $id1 * @param string $id2 * @param bool $isMultiLevelSeries
< * @param Axis $yAxis < * < * @throws WriterException
*/
< private function writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis)
> private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id1, $id2, $isMultiLevelSeries, Axis $yAxis): void
{
< $objWriter->startElement('c:catAx');
> // N.B. writeCategoryAxis may be invoked with the last parameter($yAxis) using $xAxis for ScatterChart, etc > // In that case, xAxis may contain values like the yAxis, or it may be a date axis (LINECHART). > $axisType = $yAxis->getAxisType(); > if ($axisType !== '') { > $objWriter->startElement("c:$axisType"); > } elseif ($yAxis->getAxisIsNumericFormat()) { > $objWriter->startElement('c:' . Axis::AXIS_TYPE_VALUE); > } else { > $objWriter->startElement('c:' . Axis::AXIS_TYPE_CATEGORY); > } > $majorGridlines = $yAxis->getMajorGridlines(); > $minorGridlines = $yAxis->getMinorGridlines();
< if ($id1 > 0) {
> if ($id1 !== '0') {
$objWriter->startElement('c:axId'); $objWriter->writeAttribute('val', $id1); $objWriter->endElement(); } $objWriter->startElement('c:scaling');
> if ($yAxis->getAxisOptionsProperty('maximum') !== null) { $objWriter->startElement('c:orientation'); > $objWriter->startElement('c:max'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation')); > $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('maximum')); $objWriter->endElement(); > $objWriter->endElement(); $objWriter->endElement(); > } > if ($yAxis->getAxisOptionsProperty('minimum') !== null) { $objWriter->startElement('c:delete'); > $objWriter->startElement('c:min'); $objWriter->writeAttribute('val', 0); > $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minimum')); $objWriter->endElement(); > $objWriter->endElement(); > } $objWriter->startElement('c:axPos'); > if (!empty($yAxis->getAxisOptionsProperty('orientation'))) {
< $objWriter->endElement();
> } > $objWriter->endElement(); // c:scaling
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('hidden') ?? '0');
> if ($majorGridlines !== null) { if ($xAxisLabel !== null) { > $objWriter->startElement('c:majorGridlines'); $objWriter->startElement('c:title'); > $objWriter->startElement('c:spPr'); $objWriter->startElement('c:tx'); > $this->writeLineStyles($objWriter, $majorGridlines); $objWriter->startElement('c:rich'); > $this->writeEffects($objWriter, $majorGridlines); > $objWriter->endElement(); //end spPr $objWriter->startElement('a:bodyPr'); > $objWriter->endElement(); //end majorGridLines $objWriter->endElement(); > } > $objWriter->startElement('a:lstStyle'); > if ($minorGridlines !== null && $minorGridlines->getObjectState()) { $objWriter->endElement(); > $objWriter->startElement('c:minorGridlines'); > $objWriter->startElement('c:spPr'); $objWriter->startElement('a:p'); > $this->writeLineStyles($objWriter, $minorGridlines); $objWriter->startElement('a:r'); > $this->writeEffects($objWriter, $minorGridlines); > $objWriter->endElement(); //end spPr $caption = $xAxisLabel->getCaption(); > $objWriter->endElement(); //end minorGridLines if (is_array($caption)) { > } $caption = $caption[0]; >
< $objWriter->startElement('a:r');
< $objWriter->startElement('a:t'); < $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption)); < $objWriter->endElement();
> $this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a');
$objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement();
< $objWriter->endElement();
$layout = $xAxisLabel->getLayout(); $this->writeLayout($objWriter, $layout); $objWriter->startElement('c:overlay');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
$objWriter->endElement(); $objWriter->endElement(); } $objWriter->startElement('c:numFmt'); $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat()); $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked()); $objWriter->endElement();
> if (!empty($yAxis->getAxisOptionsProperty('major_tick_mark'))) {
$objWriter->startElement('c:majorTickMark'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark')); $objWriter->endElement();
> }
> if (!empty($yAxis->getAxisOptionsProperty('minor_tick_mark'))) {
$objWriter->startElement('c:minorTickMark'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark')); $objWriter->endElement();
> }
> if (!empty($yAxis->getAxisOptionsProperty('axis_labels'))) {
$objWriter->startElement('c:tickLblPos'); $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels')); $objWriter->endElement();
> } > if ($id2 > 0) { > $textRotation = $yAxis->getAxisOptionsProperty('textRotation'); $objWriter->startElement('c:crossAx'); > if (is_numeric($textRotation)) { $objWriter->writeAttribute('val', $id2); > $objWriter->startElement('c:txPr'); $objWriter->endElement(); > $objWriter->startElement('a:bodyPr'); > $objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation)); $objWriter->startElement('c:crosses'); > $objWriter->endElement(); // a:bodyPr $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses')); > $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); > $objWriter->endElement(); // a:lstStyle } > $objWriter->startElement('a:p'); > $objWriter->startElement('a:pPr'); $objWriter->startElement('c:auto'); > $objWriter->startElement('a:defRPr'); $objWriter->writeAttribute('val', 1); > $objWriter->endElement(); // a:defRPr $objWriter->endElement(); > $objWriter->endElement(); // a:pPr > $objWriter->endElement(); // a:p $objWriter->startElement('c:lblAlgn'); > $objWriter->endElement(); // c:txPr $objWriter->writeAttribute('val', 'ctr'); > } $objWriter->endElement(); > > $objWriter->startElement('c:spPr'); $objWriter->startElement('c:lblOffset'); > $this->writeColor($objWriter, $yAxis->getFillColorObject()); $objWriter->writeAttribute('val', 100); > $this->writeLineStyles($objWriter, $yAxis); $objWriter->endElement(); > $this->writeEffects($objWriter, $yAxis); > $objWriter->endElement(); // spPr
< if ($id2 > 0) {
> if ($yAxis->getAxisOptionsProperty('major_unit') !== null) { > $objWriter->startElement('c:majorUnit'); > $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_unit')); > $objWriter->endElement(); > } > > if ($yAxis->getAxisOptionsProperty('minor_unit') !== null) { > $objWriter->startElement('c:minorUnit'); > $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_unit')); > $objWriter->endElement(); > } > > if ($id2 !== '0') {
$objWriter->startElement('c:noMultiLvlLbl');
> if (!empty($yAxis->getAxisOptionsProperty('horizontal_crosses'))) {
$objWriter->writeAttribute('val', 0);
> }
< $objWriter->writeAttribute('val', 1);
> // LineChart with dateAx wants '0' > $objWriter->writeAttribute('val', ($axisType === Axis::AXIS_TYPE_DATE) ? '0' : '1');
< $objWriter->writeAttribute('val', 100);
> $objWriter->writeAttribute('val', '100');
$objWriter->endElement();
> if ($axisType === Axis::AXIS_TYPE_DATE) { } > $property = 'baseTimeUnit'; > $propertyVal = $yAxis->getAxisOptionsProperty($property); /** > if (!empty($propertyVal)) { * Write Value Axis. > $objWriter->startElement("c:$property"); * > $objWriter->writeAttribute('val', $propertyVal); * @param XMLWriter $objWriter XML Writer > $objWriter->endElement(); * @param Title $yAxisLabel > } * @param string $groupType Chart type > $property = 'majorTimeUnit'; * @param string $id1 > $propertyVal = $yAxis->getAxisOptionsProperty($property); * @param string $id2 > if (!empty($propertyVal)) { * @param bool $isMultiLevelSeries > $objWriter->startElement("c:$property"); * @param Axis $xAxis > $objWriter->writeAttribute('val', $propertyVal); * @param GridLines $majorGridlines > $objWriter->endElement(); * @param GridLines $minorGridlines > } * > $property = 'minorTimeUnit'; * @throws WriterException > $propertyVal = $yAxis->getAxisOptionsProperty($property); */ > if (!empty($propertyVal)) { private function writeValueAxis($objWriter, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis, GridLines $majorGridlines, GridLines $minorGridlines) > $objWriter->startElement("c:$property"); { > $objWriter->writeAttribute('val', $propertyVal); $objWriter->startElement('c:valAx'); > $objWriter->endElement(); > } if ($id2 > 0) { > } $objWriter->startElement('c:axId'); >
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
< * @param XMLWriter $objWriter XML Writer < * @param Title $yAxisLabel < * @param string $groupType Chart type
> * @param null|string $groupType Chart type
< * @param Axis $xAxis < * @param GridLines $majorGridlines < * @param GridLines $minorGridlines < * < * @throws WriterException
< private function writeValueAxis($objWriter, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis, GridLines $majorGridlines, GridLines $minorGridlines)
> private function writeValueAxis(XMLWriter $objWriter, ?Title $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis): void
< $objWriter->startElement('c:valAx');
> $objWriter->startElement('c:' . Axis::AXIS_TYPE_VALUE); > $majorGridlines = $xAxis->getMajorGridlines(); > $minorGridlines = $xAxis->getMinorGridlines();
< if ($id2 > 0) {
> if ($id2 !== '0') {
if ($xAxis->getAxisOptionsProperty('minimum') !== null) { $objWriter->startElement('c:min'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum')); $objWriter->endElement(); }
> if (!empty($xAxis->getAxisOptionsProperty('orientation'))) {
$objWriter->startElement('c:orientation'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation'));
< < $objWriter->endElement();
$objWriter->endElement();
> } > $objWriter->startElement('c:delete'); > $objWriter->endElement(); // c:scaling
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('hidden') ?? '0');
$objWriter->endElement(); $objWriter->startElement('c:axPos'); $objWriter->writeAttribute('val', 'l'); $objWriter->endElement();
> if ($majorGridlines !== null) {
$objWriter->startElement('c:majorGridlines'); $objWriter->startElement('c:spPr');
< < if ($majorGridlines->getLineColorProperty('value') !== null) { < $objWriter->startElement('a:ln'); < $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width')); < $objWriter->startElement('a:solidFill'); < $objWriter->startElement("a:{$majorGridlines->getLineColorProperty('type')}"); < $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value')); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha')); < $objWriter->endElement(); //end alpha < $objWriter->endElement(); //end srgbClr < $objWriter->endElement(); //end solidFill < < $objWriter->startElement('a:prstDash'); < $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash')); < $objWriter->endElement(); < < if ($majorGridlines->getLineStyleProperty('join') == 'miter') { < $objWriter->startElement('a:miter'); < $objWriter->writeAttribute('lim', '800000'); < $objWriter->endElement(); < } else { < $objWriter->startElement('a:bevel'); < $objWriter->endElement(); < } < < if ($majorGridlines->getLineStyleProperty(['arrow', 'head', 'type']) !== null) { < $objWriter->startElement('a:headEnd'); < $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'head', 'type'])); < $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w')); < $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len')); < $objWriter->endElement(); < } < < if ($majorGridlines->getLineStyleProperty(['arrow', 'end', 'type']) !== null) { < $objWriter->startElement('a:tailEnd'); < $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(['arrow', 'end', 'type'])); < $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w')); < $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len')); < $objWriter->endElement(); < } < $objWriter->endElement(); //end ln < } < $objWriter->startElement('a:effectLst'); < < if ($majorGridlines->getGlowSize() !== null) { < $objWriter->startElement('a:glow'); < $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize()); < $objWriter->startElement("a:{$majorGridlines->getGlowColor('type')}"); < $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value')); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha')); < $objWriter->endElement(); //end alpha < $objWriter->endElement(); //end schemeClr < $objWriter->endElement(); //end glow < } < < if ($majorGridlines->getShadowProperty('presets') !== null) { < $objWriter->startElement("a:{$majorGridlines->getShadowProperty('effect')}"); < if ($majorGridlines->getShadowProperty('blur') !== null) { < $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur')); < } < if ($majorGridlines->getShadowProperty('distance') !== null) { < $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance')); < } < if ($majorGridlines->getShadowProperty('direction') !== null) { < $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction')); < } < if ($majorGridlines->getShadowProperty('algn') !== null) { < $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn')); < } < if ($majorGridlines->getShadowProperty(['size', 'sx']) !== null) { < $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(['size', 'sx'])); < } < if ($majorGridlines->getShadowProperty(['size', 'sy']) !== null) { < $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(['size', 'sy'])); < } < if ($majorGridlines->getShadowProperty(['size', 'kx']) !== null) { < $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(['size', 'kx'])); < } < if ($majorGridlines->getShadowProperty('rotWithShape') !== null) { < $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape')); < } < $objWriter->startElement("a:{$majorGridlines->getShadowProperty(['color', 'type'])}"); < $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'value'])); < < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(['color', 'alpha'])); < $objWriter->endElement(); //end alpha < < $objWriter->endElement(); //end color:type < $objWriter->endElement(); //end shadow < } < < if ($majorGridlines->getSoftEdgesSize() !== null) { < $objWriter->startElement('a:softEdge'); < $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize()); < $objWriter->endElement(); //end softEdge < } < < $objWriter->endElement(); //end effectLst
> $this->writeLineStyles($objWriter, $majorGridlines); > $this->writeEffects($objWriter, $majorGridlines);
$objWriter->endElement(); //end spPr $objWriter->endElement(); //end majorGridLines
> }
< if ($minorGridlines->getObjectState()) {
> if ($minorGridlines !== null && $minorGridlines->getObjectState()) {
$objWriter->startElement('c:minorGridlines'); $objWriter->startElement('c:spPr');
< < if ($minorGridlines->getLineColorProperty('value') !== null) { < $objWriter->startElement('a:ln'); < $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width')); < $objWriter->startElement('a:solidFill'); < $objWriter->startElement("a:{$minorGridlines->getLineColorProperty('type')}"); < $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value')); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha')); < $objWriter->endElement(); //end alpha < $objWriter->endElement(); //end srgbClr < $objWriter->endElement(); //end solidFill < < $objWriter->startElement('a:prstDash'); < $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash')); < $objWriter->endElement(); < < if ($minorGridlines->getLineStyleProperty('join') == 'miter') { < $objWriter->startElement('a:miter'); < $objWriter->writeAttribute('lim', '800000'); < $objWriter->endElement(); < } else { < $objWriter->startElement('a:bevel'); < $objWriter->endElement(); < } < < if ($minorGridlines->getLineStyleProperty(['arrow', 'head', 'type']) !== null) { < $objWriter->startElement('a:headEnd'); < $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'head', 'type'])); < $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w')); < $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len')); < $objWriter->endElement(); < } < < if ($minorGridlines->getLineStyleProperty(['arrow', 'end', 'type']) !== null) { < $objWriter->startElement('a:tailEnd'); < $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(['arrow', 'end', 'type'])); < $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w')); < $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len')); < $objWriter->endElement(); < } < $objWriter->endElement(); //end ln < } < < $objWriter->startElement('a:effectLst'); < < if ($minorGridlines->getGlowSize() !== null) { < $objWriter->startElement('a:glow'); < $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize()); < $objWriter->startElement("a:{$minorGridlines->getGlowColor('type')}"); < $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value')); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha')); < $objWriter->endElement(); //end alpha < $objWriter->endElement(); //end schemeClr < $objWriter->endElement(); //end glow < } < < if ($minorGridlines->getShadowProperty('presets') !== null) { < $objWriter->startElement("a:{$minorGridlines->getShadowProperty('effect')}"); < if ($minorGridlines->getShadowProperty('blur') !== null) { < $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur')); < } < if ($minorGridlines->getShadowProperty('distance') !== null) { < $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance')); < } < if ($minorGridlines->getShadowProperty('direction') !== null) { < $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction')); < } < if ($minorGridlines->getShadowProperty('algn') !== null) { < $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn')); < } < if ($minorGridlines->getShadowProperty(['size', 'sx']) !== null) { < $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(['size', 'sx'])); < } < if ($minorGridlines->getShadowProperty(['size', 'sy']) !== null) { < $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(['size', 'sy'])); < } < if ($minorGridlines->getShadowProperty(['size', 'kx']) !== null) { < $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(['size', 'kx'])); < } < if ($minorGridlines->getShadowProperty('rotWithShape') !== null) { < $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape')); < } < $objWriter->startElement("a:{$minorGridlines->getShadowProperty(['color', 'type'])}"); < $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'value'])); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(['color', 'alpha'])); < $objWriter->endElement(); //end alpha < $objWriter->endElement(); //end color:type < $objWriter->endElement(); //end shadow < } < < if ($minorGridlines->getSoftEdgesSize() !== null) { < $objWriter->startElement('a:softEdge'); < $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize()); < $objWriter->endElement(); //end softEdge < } < < $objWriter->endElement(); //end effectLst
> $this->writeLineStyles($objWriter, $minorGridlines); > $this->writeEffects($objWriter, $minorGridlines);
$objWriter->endElement(); //end spPr $objWriter->endElement(); //end minorGridLines } if ($yAxisLabel !== null) { $objWriter->startElement('c:title'); $objWriter->startElement('c:tx'); $objWriter->startElement('c:rich'); $objWriter->startElement('a:bodyPr'); $objWriter->endElement(); $objWriter->startElement('a:lstStyle'); $objWriter->endElement(); $objWriter->startElement('a:p');
< $objWriter->startElement('a:r');
$caption = $yAxisLabel->getCaption(); if (is_array($caption)) { $caption = $caption[0]; }
< < $objWriter->startElement('a:t'); < $objWriter->writeRawData(StringHelper::controlCharacterPHP2OOXML($caption)); < $objWriter->endElement();
> $this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a');
$objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement();
< $objWriter->endElement();
if ($groupType !== DataSeries::TYPE_BUBBLECHART) { $layout = $yAxisLabel->getLayout(); $this->writeLayout($objWriter, $layout); } $objWriter->startElement('c:overlay');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
$objWriter->endElement(); $objWriter->endElement(); } $objWriter->startElement('c:numFmt'); $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat()); $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked()); $objWriter->endElement();
> if (!empty($xAxis->getAxisOptionsProperty('major_tick_mark'))) {
$objWriter->startElement('c:majorTickMark'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark')); $objWriter->endElement();
> }
> if (!empty($xAxis->getAxisOptionsProperty('minor_tick_mark'))) {
$objWriter->startElement('c:minorTickMark'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark')); $objWriter->endElement();
> }
> if (!empty($xAxis->getAxisOptionsProperty('axis_labels'))) {
$objWriter->startElement('c:tickLblPos'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels')); $objWriter->endElement();
< < $objWriter->startElement('c:spPr'); < < if ($xAxis->getFillProperty('value') !== null) { < $objWriter->startElement('a:solidFill'); < $objWriter->startElement('a:' . $xAxis->getFillProperty('type')); < $objWriter->writeAttribute('val', $xAxis->getFillProperty('value')); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha')); < $objWriter->endElement(); < $objWriter->endElement(); < $objWriter->endElement(); < } < < $objWriter->startElement('a:ln'); < < $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width')); < $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap')); < $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound')); < < if ($xAxis->getLineProperty('value') !== null) { < $objWriter->startElement('a:solidFill'); < $objWriter->startElement('a:' . $xAxis->getLineProperty('type')); < $objWriter->writeAttribute('val', $xAxis->getLineProperty('value')); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha')); < $objWriter->endElement(); < $objWriter->endElement(); < $objWriter->endElement(); < } < < $objWriter->startElement('a:prstDash'); < $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash')); < $objWriter->endElement(); < < if ($xAxis->getLineStyleProperty('join') == 'miter') { < $objWriter->startElement('a:miter'); < $objWriter->writeAttribute('lim', '800000'); < $objWriter->endElement(); < } else { < $objWriter->startElement('a:bevel'); < $objWriter->endElement(); < } < < if ($xAxis->getLineStyleProperty(['arrow', 'head', 'type']) !== null) { < $objWriter->startElement('a:headEnd'); < $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'head', 'type'])); < $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head')); < $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head')); < $objWriter->endElement(); < } < < if ($xAxis->getLineStyleProperty(['arrow', 'end', 'type']) !== null) { < $objWriter->startElement('a:tailEnd'); < $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(['arrow', 'end', 'type'])); < $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end')); < $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end')); < $objWriter->endElement(); < } < < $objWriter->endElement(); < < $objWriter->startElement('a:effectLst'); < < if ($xAxis->getGlowProperty('size') !== null) { < $objWriter->startElement('a:glow'); < $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size')); < $objWriter->startElement("a:{$xAxis->getGlowProperty(['color', 'type'])}"); < $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color', 'value'])); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $xAxis->getGlowProperty(['color', 'alpha'])); < $objWriter->endElement(); < $objWriter->endElement(); < $objWriter->endElement();
}
< if ($xAxis->getShadowProperty('presets') !== null) { < $objWriter->startElement("a:{$xAxis->getShadowProperty('effect')}"); < < if ($xAxis->getShadowProperty('blur') !== null) { < $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur')); < } < if ($xAxis->getShadowProperty('distance') !== null) { < $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance')); < } < if ($xAxis->getShadowProperty('direction') !== null) { < $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction')); < } < if ($xAxis->getShadowProperty('algn') !== null) { < $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn')); < } < if ($xAxis->getShadowProperty(['size', 'sx']) !== null) { < $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(['size', 'sx'])); < } < if ($xAxis->getShadowProperty(['size', 'sy']) !== null) { < $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(['size', 'sy'])); < } < if ($xAxis->getShadowProperty(['size', 'kx']) !== null) { < $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(['size', 'kx'])); < } < if ($xAxis->getShadowProperty('rotWithShape') !== null) { < $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape')); < } < < $objWriter->startElement("a:{$xAxis->getShadowProperty(['color', 'type'])}"); < $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'value'])); < $objWriter->startElement('a:alpha'); < $objWriter->writeAttribute('val', $xAxis->getShadowProperty(['color', 'alpha'])); < $objWriter->endElement(); < $objWriter->endElement(); < < $objWriter->endElement(); < } < < if ($xAxis->getSoftEdgesSize() !== null) { < $objWriter->startElement('a:softEdge'); < $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize()); < $objWriter->endElement();
> $textRotation = $xAxis->getAxisOptionsProperty('textRotation'); > if (is_numeric($textRotation)) { > $objWriter->startElement('c:txPr'); > $objWriter->startElement('a:bodyPr'); > $objWriter->writeAttribute('rot', Properties::angleToXml((float) $textRotation)); > $objWriter->endElement(); // a:bodyPr > $objWriter->startElement('a:lstStyle'); > $objWriter->endElement(); // a:lstStyle > $objWriter->startElement('a:p'); > $objWriter->startElement('a:pPr'); > $objWriter->startElement('a:defRPr'); > $objWriter->endElement(); // a:defRPr > $objWriter->endElement(); // a:pPr > $objWriter->endElement(); // a:p > $objWriter->endElement(); // c:txPr
}
< $objWriter->endElement(); //effectList
> $objWriter->startElement('c:spPr'); > $this->writeColor($objWriter, $xAxis->getFillColorObject()); > $this->writeLineStyles($objWriter, $xAxis); > $this->writeEffects($objWriter, $xAxis);
$objWriter->endElement(); //end spPr
< if ($id1 > 0) {
> if ($id1 !== '0') {
$objWriter->startElement('c:crossAx');
< $objWriter->writeAttribute('val', $id2);
> $objWriter->writeAttribute('val', $id1);
$objWriter->endElement(); if ($xAxis->getAxisOptionsProperty('horizontal_crosses_value') !== null) { $objWriter->startElement('c:crossesAt'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value')); $objWriter->endElement(); } else {
> $crosses = $xAxis->getAxisOptionsProperty('horizontal_crosses'); $objWriter->startElement('c:crosses'); > if ($crosses) {
< $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses'));
> $objWriter->writeAttribute('val', $crosses);
$objWriter->endElement(); }
> }
> $crossBetween = $xAxis->getCrossBetween(); $objWriter->startElement('c:crossBetween'); > if ($crossBetween !== '') {
< $objWriter->writeAttribute('val', 'midCat');
> $objWriter->writeAttribute('val', $crossBetween);
$objWriter->endElement();
> }
if ($xAxis->getAxisOptionsProperty('major_unit') !== null) { $objWriter->startElement('c:majorUnit'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit')); $objWriter->endElement(); } if ($xAxis->getAxisOptionsProperty('minor_unit') !== null) { $objWriter->startElement('c:minorUnit'); $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit')); $objWriter->endElement(); } } if ($isMultiLevelSeries) { if ($groupType !== DataSeries::TYPE_BUBBLECHART) { $objWriter->startElement('c:noMultiLvlLbl');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
$objWriter->endElement(); } } $objWriter->endElement(); } /**
> * Write Ser Axis, for Surface chart. * Get the data series type(s) for a chart plot series. > */ * > private function writeSerAxis(XMLWriter $objWriter, string $id2, string $id3): void * @param PlotArea $plotArea > { * > $objWriter->startElement('c:serAx'); * @throws WriterException > * > $objWriter->startElement('c:axId'); * @return array|string > $objWriter->writeAttribute('val', $id3); */ > $objWriter->endElement(); // axId private static function getChartType($plotArea) > { > $objWriter->startElement('c:scaling'); $groupCount = $plotArea->getPlotGroupCount(); > $objWriter->startElement('c:orientation'); > $objWriter->writeAttribute('val', 'minMax'); if ($groupCount == 1) { > $objWriter->endElement(); // orientation $chartType = [$plotArea->getPlotGroupByIndex(0)->getPlotType()]; > $objWriter->endElement(); // scaling } else { > $chartTypes = []; > $objWriter->startElement('c:delete'); for ($i = 0; $i < $groupCount; ++$i) { > $objWriter->writeAttribute('val', '0'); $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType(); > $objWriter->endElement(); // delete } > $chartType = array_unique($chartTypes); > $objWriter->startElement('c:axPos'); if (count($chartTypes) == 0) { > $objWriter->writeAttribute('val', 'b'); throw new WriterException('Chart is not yet implemented'); > $objWriter->endElement(); // axPos } > } > $objWriter->startElement('c:majorTickMark'); > $objWriter->writeAttribute('val', 'out'); return $chartType; > $objWriter->endElement(); // majorTickMark } > > $objWriter->startElement('c:minorTickMark'); /** > $objWriter->writeAttribute('val', 'none'); * Method writing plot series values. > $objWriter->endElement(); // minorTickMark * > * @param XMLWriter $objWriter XML Writer > $objWriter->startElement('c:tickLblPos'); * @param int $val value for idx (default: 3) > $objWriter->writeAttribute('val', 'nextTo'); * @param string $fillColor hex color (default: FF9900) > $objWriter->endElement(); // tickLblPos * > * @return XMLWriter XML Writer > $objWriter->startElement('c:crossAx'); */ > $objWriter->writeAttribute('val', $id2); private function writePlotSeriesValuesElement($objWriter, $val = 3, $fillColor = 'FF9900') > $objWriter->endElement(); // crossAx { > $objWriter->startElement('c:dPt'); > $objWriter->startElement('c:crosses'); $objWriter->startElement('c:idx'); > $objWriter->writeAttribute('val', 'autoZero'); $objWriter->writeAttribute('val', $val); > $objWriter->endElement(); // crosses $objWriter->endElement(); > > $objWriter->endElement(); //serAx $objWriter->startElement('c:bubble3D'); > } $objWriter->writeAttribute('val', 0); > $objWriter->endElement(); > /**
< * @param PlotArea $plotArea < * < * @throws WriterException < * < * @return array|string
> * @return string[]
< private static function getChartType($plotArea)
> private static function getChartType(PlotArea $plotArea): array
< * < * @param XMLWriter $objWriter XML Writer < * @param int $val value for idx (default: 3) < * @param string $fillColor hex color (default: FF9900) < * < * @return XMLWriter XML Writer
< private function writePlotSeriesValuesElement($objWriter, $val = 3, $fillColor = 'FF9900')
> private function writePlotSeriesValuesElement(XMLWriter $objWriter, int $val, ?ChartColor $fillColor): void
/**
> if ($fillColor === null || !$fillColor->isUsable()) { * Write Plot Group (series of related plots). > return; * > }
< $objWriter->startElement('c:idx'); < $objWriter->writeAttribute('val', $val); < $objWriter->endElement();
< $objWriter->startElement('c:bubble3D'); < $objWriter->writeAttribute('val', 0); < $objWriter->endElement();
> $objWriter->startElement('c:idx'); > $objWriter->writeAttribute('val', "$val"); > $objWriter->endElement(); // c:idx
< $objWriter->startElement('a:solidFill'); < $objWriter->startElement('a:srgbClr'); < $objWriter->writeAttribute('val', $fillColor); < $objWriter->endElement(); < $objWriter->endElement(); < $objWriter->endElement(); < $objWriter->endElement();
> $this->writeColor($objWriter, $fillColor); > $objWriter->endElement(); // c:spPr
< return $objWriter;
> $objWriter->endElement(); // c:dPt
< * @param DataSeries $plotGroup
< * @param XMLWriter $objWriter XML Writer < * @param bool &$catIsMultiLevelSeries Is category a multi-series category < * @param bool &$valIsMultiLevelSeries Is value set a multi-series set < * @param string &$plotGroupingType Type of grouping for multi-series values < * < * @throws WriterException
> * @param bool $catIsMultiLevelSeries Is category a multi-series category > * @param bool $valIsMultiLevelSeries Is value set a multi-series set > * @param string $plotGroupingType Type of grouping for multi-series values
< private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType)
> private function writePlotGroup(?DataSeries $plotGroup, string $groupType, XMLWriter $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType): void
< if ($plotGroup->getPlotGrouping() !== null) {
$objWriter->startElement('c:grouping');
> if ($plotGroupingType !== null && $groupType !== DataSeries::TYPE_SURFACECHART && $groupType !== DataSeries::TYPE_SURFACECHART_3D) {
$objWriter->writeAttribute('val', $plotGroupingType); $objWriter->endElement(); } // Get these details before the loop, because we can use the count to check for varyColors $plotSeriesOrder = $plotGroup->getPlotOrder(); $plotSeriesCount = count($plotSeriesOrder); if (($groupType !== DataSeries::TYPE_RADARCHART) && ($groupType !== DataSeries::TYPE_STOCKCHART)) { if ($groupType !== DataSeries::TYPE_LINECHART) { if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART) || ($plotSeriesCount > 1)) { $objWriter->startElement('c:varyColors');
< $objWriter->writeAttribute('val', 1);
> $objWriter->writeAttribute('val', '1');
$objWriter->endElement(); } else { $objWriter->startElement('c:varyColors');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0');
$objWriter->endElement(); } } }
> $plotSeriesIdx = 0;
foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { $objWriter->startElement('c:ser');
< $plotLabel = $plotGroup->getPlotLabelByIndex($plotSeriesIdx); < if ($plotLabel) { < $fillColor = $plotLabel->getFillColor(); < if ($fillColor !== null && !is_array($fillColor)) { < $objWriter->startElement('c:spPr'); < $objWriter->startElement('a:solidFill'); < $objWriter->startElement('a:srgbClr'); < $objWriter->writeAttribute('val', $fillColor); < $objWriter->endElement(); < $objWriter->endElement(); < $objWriter->endElement(); < } < } <
$objWriter->startElement('c:idx');
< $objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesIdx);
> $adder = array_key_exists(0, $plotSeriesOrder) ? $this->seriesIndex : 0; > $objWriter->writeAttribute('val', (string) ($adder + $plotSeriesIdx));
$objWriter->endElement(); $objWriter->startElement('c:order');
< $objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesRef);
> $objWriter->writeAttribute('val', (string) ($adder + $plotSeriesRef));
$objWriter->endElement();
> $plotLabel = $plotGroup->getPlotLabelByIndex($plotSeriesIdx); // Values > $labelFill = null; $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); > if ($plotLabel && $groupType === DataSeries::TYPE_LINECHART) { > $labelFill = $plotLabel->getFillColorObject(); if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) { > $labelFill = ($labelFill instanceof ChartColor) ? $labelFill : null; $fillColorValues = $plotSeriesValues->getFillColor(); > } if ($fillColorValues !== null && is_array($fillColorValues)) { > if ($plotLabel && $groupType !== DataSeries::TYPE_LINECHART) { foreach ($plotSeriesValues->getDataValues() as $dataKey => $dataValue) { > $fillColor = $plotLabel->getFillColorObject(); $this->writePlotSeriesValuesElement($objWriter, $dataKey, ($fillColorValues[$dataKey] ?? 'FF9900')); > if ($fillColor !== null && !is_array($fillColor) && $fillColor->isUsable()) { } > $objWriter->startElement('c:spPr'); } else { > $this->writeColor($objWriter, $fillColor); $this->writePlotSeriesValuesElement($objWriter); > $objWriter->endElement(); // c:spPr } > } } > } >
< $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef);
> $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesIdx);
< if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) { < $fillColorValues = $plotSeriesValues->getFillColor();
> if ($plotSeriesValues !== false && in_array($groupType, self::CUSTOM_COLOR_TYPES, true)) { > $fillColorValues = $plotSeriesValues->getFillColorObject();
< $this->writePlotSeriesValuesElement($objWriter, $dataKey, ($fillColorValues[$dataKey] ?? 'FF9900'));
> $this->writePlotSeriesValuesElement($objWriter, $dataKey, $fillColorValues[$dataKey] ?? null); > }
< } else { < $this->writePlotSeriesValuesElement($objWriter);
$objWriter->endElement();
> if ($plotSeriesValues !== false && $plotSeriesValues->getLabelLayout()) { $objWriter->endElement(); > $this->writeDataLabels($objWriter, $plotSeriesValues->getLabelLayout());
< $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef);
> $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesIdx);
// Formatting for the points
< if (($groupType == DataSeries::TYPE_LINECHART) || ($groupType == DataSeries::TYPE_STOCKCHART)) { < $plotLineWidth = 12700; < if ($plotSeriesValues) { < $plotLineWidth = $plotSeriesValues->getLineWidth(); < } <
> if ( > $plotSeriesValues !== false > ) {
$objWriter->startElement('c:spPr');
> $fillObject = $labelFill ?? $plotSeriesValues->getFillColorObject(); $objWriter->startElement('a:ln'); > $callLineStyles = true; $objWriter->writeAttribute('w', $plotLineWidth); > if ($fillObject instanceof ChartColor && $fillObject->isUsable()) { if ($groupType == DataSeries::TYPE_STOCKCHART) { > if ($groupType === DataSeries::TYPE_LINECHART) {
< $objWriter->writeAttribute('w', $plotLineWidth); < if ($groupType == DataSeries::TYPE_STOCKCHART) { < $objWriter->startElement('a:noFill'); < $objWriter->endElement();
> $callLineStyles = false;
< $objWriter->endElement(); < $objWriter->endElement();
> $this->writeColor($objWriter, $fillObject); > if (!$callLineStyles) { > $objWriter->endElement(); // a:ln > } > } > $nofill = $groupType === DataSeries::TYPE_STOCKCHART || (($groupType === DataSeries::TYPE_SCATTERCHART || $groupType === DataSeries::TYPE_LINECHART) && !$plotSeriesValues->getScatterLines()); > if ($callLineStyles) { > $this->writeLineStyles($objWriter, $plotSeriesValues, $nofill); > $this->writeEffects($objWriter, $plotSeriesValues); > } > $objWriter->endElement(); // c:spPr
if ($plotSeriesValues) { $plotSeriesMarker = $plotSeriesValues->getPointMarker();
< if ($plotSeriesMarker) {
> $markerFillColor = $plotSeriesValues->getMarkerFillColor(); > $fillUsed = $markerFillColor->IsUsable(); > $markerBorderColor = $plotSeriesValues->getMarkerBorderColor(); > $borderUsed = $markerBorderColor->isUsable(); > if ($plotSeriesMarker || $fillUsed || $borderUsed) {
$objWriter->startElement('c:marker'); $objWriter->startElement('c:symbol');
> if ($plotSeriesMarker) {
$objWriter->writeAttribute('val', $plotSeriesMarker);
> }
$objWriter->endElement(); if ($plotSeriesMarker !== 'none') { $objWriter->startElement('c:size');
< $objWriter->writeAttribute('val', 3); < $objWriter->endElement();
> $objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointSize()); > $objWriter->endElement(); // c:size > $objWriter->startElement('c:spPr'); > $this->writeColor($objWriter, $markerFillColor); > if ($borderUsed) { > $objWriter->startElement('a:ln'); > $this->writeColor($objWriter, $markerBorderColor); > $objWriter->endElement(); // a:ln > } > $objWriter->endElement(); // spPr
} $objWriter->endElement(); } } if (($groupType === DataSeries::TYPE_BARCHART) || ($groupType === DataSeries::TYPE_BARCHART_3D) || ($groupType === DataSeries::TYPE_BUBBLECHART)) { $objWriter->startElement('c:invertIfNegative');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', '0'); > $objWriter->endElement(); > } > // Trendlines > if ($plotSeriesValues !== false) { > foreach ($plotSeriesValues->getTrendLines() as $trendLine) { > $trendLineType = $trendLine->getTrendLineType(); > $order = $trendLine->getOrder(); > $period = $trendLine->getPeriod(); > $dispRSqr = $trendLine->getDispRSqr(); > $dispEq = $trendLine->getDispEq(); > $forward = $trendLine->getForward(); > $backward = $trendLine->getBackward(); > $intercept = $trendLine->getIntercept(); > $name = $trendLine->getName(); > $trendLineColor = $trendLine->getLineColor(); // ChartColor > > $objWriter->startElement('c:trendline'); // N.B. lowercase 'ell' > if ($name !== '') { > $objWriter->startElement('c:name'); > $objWriter->writeRawData($name); > $objWriter->endElement(); // c:name > } > $objWriter->startElement('c:spPr'); > > if (!$trendLineColor->isUsable()) { > // use dataSeriesValues line color as a backup if $trendLineColor is null > $dsvLineColor = $plotSeriesValues->getLineColor(); > if ($dsvLineColor->isUsable()) { > $trendLine > ->getLineColor() > ->setColorProperties($dsvLineColor->getValue(), $dsvLineColor->getAlpha(), $dsvLineColor->getType()); > } > } // otherwise, hope Excel does the right thing > > $this->writeLineStyles($objWriter, $trendLine, false); // suppress noFill > > $objWriter->endElement(); // spPr > > $objWriter->startElement('c:trendlineType'); // N.B lowercase 'ell' > $objWriter->writeAttribute('val', $trendLineType); > $objWriter->endElement(); // trendlineType > if ($backward !== 0.0) { > $objWriter->startElement('c:backward'); > $objWriter->writeAttribute('val', "$backward"); > $objWriter->endElement(); // c:backward > } > if ($forward !== 0.0) { > $objWriter->startElement('c:forward'); > $objWriter->writeAttribute('val', "$forward"); > $objWriter->endElement(); // c:forward > } > if ($intercept !== 0.0) { > $objWriter->startElement('c:intercept'); > $objWriter->writeAttribute('val', "$intercept"); > $objWriter->endElement(); // c:intercept > } > if ($trendLineType == TrendLine::TRENDLINE_POLYNOMIAL) { > $objWriter->startElement('c:order'); > $objWriter->writeAttribute('val', $order); > $objWriter->endElement(); // order > } > if ($trendLineType == TrendLine::TRENDLINE_MOVING_AVG) { > $objWriter->startElement('c:period'); > $objWriter->writeAttribute('val', $period); > $objWriter->endElement(); // period > } > $objWriter->startElement('c:dispRSqr'); > $objWriter->writeAttribute('val', $dispRSqr ? '1' : '0'); > $objWriter->endElement(); > $objWriter->startElement('c:dispEq'); > $objWriter->writeAttribute('val', $dispEq ? '1' : '0');
$objWriter->endElement();
> if ($groupType === DataSeries::TYPE_SCATTERCHART || $groupType === DataSeries::TYPE_LINECHART) { } > $objWriter->startElement('c:trendlineLbl'); > $objWriter->startElement('c:numFmt'); // Category Labels > $objWriter->writeAttribute('formatCode', 'General'); $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); > $objWriter->writeAttribute('sourceLinked', '0'); if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { > $objWriter->endElement(); // numFmt $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); > $objWriter->endElement(); // trendlineLbl > } if (($groupType == DataSeries::TYPE_PIECHART) || ($groupType == DataSeries::TYPE_PIECHART_3D) || ($groupType == DataSeries::TYPE_DONUTCHART)) { > if ($plotGroup->getPlotStyle() !== null) { > $objWriter->endElement(); // trendline $plotStyle = $plotGroup->getPlotStyle(); > }
< $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef);
> $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesIdx);
< if ($plotGroup->getPlotStyle() !== null) {
< if ($plotStyle) {
> if (is_numeric($plotStyle)) {
< $objWriter->writeAttribute('val', 25);
> $objWriter->writeAttribute('val', $plotStyle);
} }
< }
if (($groupType === DataSeries::TYPE_BUBBLECHART) || ($groupType === DataSeries::TYPE_SCATTERCHART)) { $objWriter->startElement('c:xVal'); } else { $objWriter->startElement('c:cat'); }
> // xVals (Categories) are not always 'str' $this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str'); > // Test X-axis Label's Datatype to decide 'str' vs 'num' $objWriter->endElement(); > $CategoryDatatype = $plotSeriesCategory->getDataType(); } > if ($CategoryDatatype == DataSeriesValues::DATASERIES_TYPE_NUMBER) { > $this->writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'num'); // Values > } else {
if ($plotSeriesValues) {
> }
$valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); if (($groupType === DataSeries::TYPE_BUBBLECHART) || ($groupType === DataSeries::TYPE_SCATTERCHART)) { $objWriter->startElement('c:yVal'); } else { $objWriter->startElement('c:val'); } $this->writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num'); $objWriter->endElement();
> if ($groupType === DataSeries::TYPE_SCATTERCHART && $plotGroup->getPlotStyle() === 'smoothMarker') { } > $objWriter->startElement('c:smooth'); > $objWriter->writeAttribute('val', $plotSeriesValues->getSmoothLine() ? '1' : '0'); if ($groupType === DataSeries::TYPE_BUBBLECHART) { > $objWriter->endElement(); $this->writeBubbles($plotSeriesValues, $objWriter); > }
}
> if (!empty($plotGroup->getPlotBubbleSizes()[$plotSeriesIdx])) { > $objWriter->startElement('c:bubbleSize'); $objWriter->endElement(); > $this->writePlotSeriesValues( } > $plotGroup->getPlotBubbleSizes()[$plotSeriesIdx], > $objWriter, $this->seriesIndex += $plotSeriesIdx + 1; > $groupType, } > 'num' > ); /** > $objWriter->endElement(); * Write Plot Series Label. > if ($plotSeriesValues !== false) { * > $objWriter->startElement('c:bubble3D'); * @param DataSeriesValues $plotSeriesLabel > $objWriter->writeAttribute('val', $plotSeriesValues->getBubble3D() ? '1' : '0'); * @param XMLWriter $objWriter XML Writer > $objWriter->endElement(); */ > } private function writePlotSeriesLabel($plotSeriesLabel, $objWriter) > } elseif ($plotSeriesValues !== false) {
{
> }
< * < * @param DataSeriesValues $plotSeriesLabel < * @param XMLWriter $objWriter XML Writer
< private function writePlotSeriesLabel($plotSeriesLabel, $objWriter)
> private function writePlotSeriesLabel(?DataSeriesValues $plotSeriesLabel, XMLWriter $objWriter): void
$objWriter->startElement('c:f'); $objWriter->writeRawData($plotSeriesLabel->getDataSource()); $objWriter->endElement(); $objWriter->startElement('c:strCache'); $objWriter->startElement('c:ptCount');
< $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount());
> $objWriter->writeAttribute('val', (string) $plotSeriesLabel->getPointCount());
$objWriter->endElement(); foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotLabelKey); $objWriter->startElement('c:v'); $objWriter->writeRawData($plotLabelValue); $objWriter->endElement(); $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Plot Series Values. *
< * @param DataSeriesValues $plotSeriesValues < * @param XMLWriter $objWriter XML Writer
* @param string $groupType Type of plot for dataseries * @param string $dataType Datatype of series values */
< private function writePlotSeriesValues($plotSeriesValues, XMLWriter $objWriter, $groupType, $dataType = 'str')
> private function writePlotSeriesValues(?DataSeriesValues $plotSeriesValues, XMLWriter $objWriter, $groupType, $dataType = 'str'): void
{ if ($plotSeriesValues === null) { return; } if ($plotSeriesValues->isMultiLevelSeries()) { $levelCount = $plotSeriesValues->multiLevelCount(); $objWriter->startElement('c:multiLvlStrRef'); $objWriter->startElement('c:f'); $objWriter->writeRawData($plotSeriesValues->getDataSource()); $objWriter->endElement(); $objWriter->startElement('c:multiLvlStrCache'); $objWriter->startElement('c:ptCount');
< $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
> $objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointCount());
$objWriter->endElement(); for ($level = 0; $level < $levelCount; ++$level) { $objWriter->startElement('c:lvl'); foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { if (isset($plotSeriesValue[$level])) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotSeriesKey); $objWriter->startElement('c:v'); $objWriter->writeRawData($plotSeriesValue[$level]); $objWriter->endElement(); $objWriter->endElement(); } } $objWriter->endElement(); } $objWriter->endElement(); $objWriter->endElement(); } else { $objWriter->startElement('c:' . $dataType . 'Ref'); $objWriter->startElement('c:f'); $objWriter->writeRawData($plotSeriesValues->getDataSource()); $objWriter->endElement();
> $count = $plotSeriesValues->getPointCount(); $objWriter->startElement('c:' . $dataType . 'Cache'); > $source = $plotSeriesValues->getDataSource(); > $values = $plotSeriesValues->getDataValues(); if (($groupType != DataSeries::TYPE_PIECHART) && ($groupType != DataSeries::TYPE_PIECHART_3D) && ($groupType != DataSeries::TYPE_DONUTCHART)) { > if ($count > 1 || ($count === 1 && "=$source" !== (string) $values[0])) {
if (($plotSeriesValues->getFormatCode() !== null) && ($plotSeriesValues->getFormatCode() !== '')) { $objWriter->startElement('c:formatCode'); $objWriter->writeRawData($plotSeriesValues->getFormatCode()); $objWriter->endElement(); } } $objWriter->startElement('c:ptCount');
< $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
> $objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointCount());
$objWriter->endElement(); $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) {
< if (is_array($dataValues)) {
foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotSeriesKey); $objWriter->startElement('c:v'); $objWriter->writeRawData($plotSeriesValue); $objWriter->endElement(); $objWriter->endElement(); } }
< }
< $objWriter->endElement();
> $objWriter->endElement(); // *Cache > }
< $objWriter->endElement();
> $objWriter->endElement(); // *Ref
} }
> private const CUSTOM_COLOR_TYPES = [ /** > DataSeries::TYPE_BARCHART, * Write Bubble Chart Details. > DataSeries::TYPE_BARCHART_3D, * > DataSeries::TYPE_PIECHART, * @param DataSeriesValues $plotSeriesValues > DataSeries::TYPE_PIECHART_3D, * @param XMLWriter $objWriter XML Writer > DataSeries::TYPE_DONUTCHART, */ > ]; private function writeBubbles($plotSeriesValues, $objWriter) >
< * < * @param DataSeriesValues $plotSeriesValues < * @param XMLWriter $objWriter XML Writer
< private function writeBubbles($plotSeriesValues, $objWriter)
> private function writeBubbles(?DataSeriesValues $plotSeriesValues, XMLWriter $objWriter): void
$objWriter->startElement('c:bubbleSize'); $objWriter->startElement('c:numLit'); $objWriter->startElement('c:formatCode'); $objWriter->writeRawData('General'); $objWriter->endElement(); $objWriter->startElement('c:ptCount');
< $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
> $objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointCount());
$objWriter->endElement(); $dataValues = $plotSeriesValues->getDataValues(); if (!empty($dataValues)) {
< if (is_array($dataValues)) {
foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) { $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $plotSeriesKey); $objWriter->startElement('c:v');
< $objWriter->writeRawData(1);
> $objWriter->writeRawData('1');
$objWriter->endElement(); $objWriter->endElement(); } }
< }
$objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('c:bubble3D');
< $objWriter->writeAttribute('val', 0);
> $objWriter->writeAttribute('val', $plotSeriesValues->getBubble3D() ? '1' : '0');
$objWriter->endElement(); } /** * Write Layout.
< * < * @param XMLWriter $objWriter XML Writer < * @param Layout $layout
*/
< private function writeLayout(XMLWriter $objWriter, Layout $layout = null)
> private function writeLayout(XMLWriter $objWriter, ?Layout $layout = null): void
{ $objWriter->startElement('c:layout'); if ($layout !== null) { $objWriter->startElement('c:manualLayout'); $layoutTarget = $layout->getLayoutTarget(); if ($layoutTarget !== null) { $objWriter->startElement('c:layoutTarget'); $objWriter->writeAttribute('val', $layoutTarget); $objWriter->endElement(); } $xMode = $layout->getXMode(); if ($xMode !== null) { $objWriter->startElement('c:xMode'); $objWriter->writeAttribute('val', $xMode); $objWriter->endElement(); } $yMode = $layout->getYMode(); if ($yMode !== null) { $objWriter->startElement('c:yMode'); $objWriter->writeAttribute('val', $yMode); $objWriter->endElement(); } $x = $layout->getXPosition(); if ($x !== null) { $objWriter->startElement('c:x');
< $objWriter->writeAttribute('val', $x);
> $objWriter->writeAttribute('val', "$x");
$objWriter->endElement(); } $y = $layout->getYPosition(); if ($y !== null) { $objWriter->startElement('c:y');
< $objWriter->writeAttribute('val', $y);
> $objWriter->writeAttribute('val', "$y");
$objWriter->endElement(); } $w = $layout->getWidth(); if ($w !== null) { $objWriter->startElement('c:w');
< $objWriter->writeAttribute('val', $w);
> $objWriter->writeAttribute('val', "$w");
$objWriter->endElement(); } $h = $layout->getHeight(); if ($h !== null) { $objWriter->startElement('c:h');
< $objWriter->writeAttribute('val', $h);
> $objWriter->writeAttribute('val', "$h");
$objWriter->endElement(); } $objWriter->endElement(); } $objWriter->endElement(); } /** * Write Alternate Content block.
< * < * @param XMLWriter $objWriter XML Writer
*/
< private function writeAlternateContent($objWriter)
> private function writeAlternateContent(XMLWriter $objWriter): void
{ $objWriter->startElement('mc:AlternateContent');
< $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
> $objWriter->writeAttribute('xmlns:mc', Namespaces::COMPATIBILITY);
$objWriter->startElement('mc:Choice');
< $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart');
$objWriter->writeAttribute('Requires', 'c14');
> $objWriter->writeAttribute('xmlns:c14', Namespaces::CHART_ALTERNATE);
$objWriter->startElement('c14:style'); $objWriter->writeAttribute('val', '102'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->startElement('mc:Fallback'); $objWriter->startElement('c:style'); $objWriter->writeAttribute('val', '2'); $objWriter->endElement(); $objWriter->endElement(); $objWriter->endElement(); } /** * Write Printer Settings.
< * < * @param XMLWriter $objWriter XML Writer
*/
< private function writePrintSettings($objWriter)
> private function writePrintSettings(XMLWriter $objWriter): void
{ $objWriter->startElement('c:printSettings'); $objWriter->startElement('c:headerFooter'); $objWriter->endElement(); $objWriter->startElement('c:pageMargins');
< $objWriter->writeAttribute('footer', 0.3); < $objWriter->writeAttribute('header', 0.3); < $objWriter->writeAttribute('r', 0.7); < $objWriter->writeAttribute('l', 0.7); < $objWriter->writeAttribute('t', 0.75); < $objWriter->writeAttribute('b', 0.75);
> $objWriter->writeAttribute('footer', '0.3'); > $objWriter->writeAttribute('header', '0.3'); > $objWriter->writeAttribute('r', '0.7'); > $objWriter->writeAttribute('l', '0.7'); > $objWriter->writeAttribute('t', '0.75'); > $objWriter->writeAttribute('b', '0.75');
$objWriter->endElement(); $objWriter->startElement('c:pageSetup'); $objWriter->writeAttribute('orientation', 'portrait'); $objWriter->endElement(); $objWriter->endElement();
> } } > } > private function writeEffects(XMLWriter $objWriter, Properties $yAxis): void > { > if ( > !empty($yAxis->getSoftEdgesSize()) > || !empty($yAxis->getShadowProperty('effect')) > || !empty($yAxis->getGlowProperty('size')) > ) { > $objWriter->startElement('a:effectLst'); > $this->writeGlow($objWriter, $yAxis); > $this->writeShadow($objWriter, $yAxis); > $this->writeSoftEdge($objWriter, $yAxis); > $objWriter->endElement(); // effectLst > } > } > > private function writeShadow(XMLWriter $objWriter, Properties $xAxis): void > { > if (empty($xAxis->getShadowProperty('effect'))) { > return; > } > /** @var string */ > $effect = $xAxis->getShadowProperty('effect'); > $objWriter->startElement("a:$effect"); > > if (is_numeric($xAxis->getShadowProperty('blur'))) { > $objWriter->writeAttribute('blurRad', Properties::pointsToXml((float) $xAxis->getShadowProperty('blur'))); > } > if (is_numeric($xAxis->getShadowProperty('distance'))) { > $objWriter->writeAttribute('dist', Properties::pointsToXml((float) $xAxis->getShadowProperty('distance'))); > } > if (is_numeric($xAxis->getShadowProperty('direction'))) { > $objWriter->writeAttribute('dir', Properties::angleToXml((float) $xAxis->getShadowProperty('direction'))); > } > $algn = $xAxis->getShadowProperty('algn'); > if (is_string($algn) && $algn !== '') { > $objWriter->writeAttribute('algn', $algn); > } > foreach (['sx', 'sy'] as $sizeType) { > $sizeValue = $xAxis->getShadowProperty(['size', $sizeType]); > if (is_numeric($sizeValue)) { > $objWriter->writeAttribute($sizeType, Properties::tenthOfPercentToXml((float) $sizeValue)); > } > } > foreach (['kx', 'ky'] as $sizeType) { > $sizeValue = $xAxis->getShadowProperty(['size', $sizeType]); > if (is_numeric($sizeValue)) { > $objWriter->writeAttribute($sizeType, Properties::angleToXml((float) $sizeValue)); > } > } > $rotWithShape = $xAxis->getShadowProperty('rotWithShape'); > if (is_numeric($rotWithShape)) { > $objWriter->writeAttribute('rotWithShape', (string) (int) $rotWithShape); > } > > $this->writeColor($objWriter, $xAxis->getShadowColorObject(), false); > > $objWriter->endElement(); > } > > private function writeGlow(XMLWriter $objWriter, Properties $yAxis): void > { > $size = $yAxis->getGlowProperty('size'); > if (empty($size)) { > return; > } > $objWriter->startElement('a:glow'); > $objWriter->writeAttribute('rad', Properties::pointsToXml((float) $size)); > $this->writeColor($objWriter, $yAxis->getGlowColorObject(), false); > $objWriter->endElement(); // glow > } > > private function writeSoftEdge(XMLWriter $objWriter, Properties $yAxis): void > { > $softEdgeSize = $yAxis->getSoftEdgesSize(); > if (empty($softEdgeSize)) { > return; > } > $objWriter->startElement('a:softEdge'); > $objWriter->writeAttribute('rad', Properties::pointsToXml((float) $softEdgeSize)); > $objWriter->endElement(); //end softEdge > } > > private function writeLineStyles(XMLWriter $objWriter, Properties $gridlines, bool $noFill = false): void > { > $objWriter->startElement('a:ln'); > $widthTemp = $gridlines->getLineStyleProperty('width'); > if (is_numeric($widthTemp)) { > $objWriter->writeAttribute('w', Properties::pointsToXml((float) $widthTemp)); > } > $this->writeNotEmpty($objWriter, 'cap', $gridlines->getLineStyleProperty('cap')); > $this->writeNotEmpty($objWriter, 'cmpd', $gridlines->getLineStyleProperty('compound')); > if ($noFill) { > $objWriter->startElement('a:noFill'); > $objWriter->endElement(); > } else { > $this->writeColor($objWriter, $gridlines->getLineColor()); > } > > $dash = $gridlines->getLineStyleProperty('dash'); > if (!empty($dash)) { > $objWriter->startElement('a:prstDash'); > $this->writeNotEmpty($objWriter, 'val', $dash); > $objWriter->endElement(); > } > > if ($gridlines->getLineStyleProperty('join') === 'miter') { > $objWriter->startElement('a:miter'); > $objWriter->writeAttribute('lim', '800000'); > $objWriter->endElement(); > } elseif ($gridlines->getLineStyleProperty('join') === 'bevel') { > $objWriter->startElement('a:bevel'); > $objWriter->endElement(); > } > > if ($gridlines->getLineStyleProperty(['arrow', 'head', 'type'])) { > $objWriter->startElement('a:headEnd'); > $objWriter->writeAttribute('type', $gridlines->getLineStyleProperty(['arrow', 'head', 'type'])); > $this->writeNotEmpty($objWriter, 'w', $gridlines->getLineStyleArrowWidth('head')); > $this->writeNotEmpty($objWriter, 'len', $gridlines->getLineStyleArrowLength('head')); > $objWriter->endElement(); > } > > if ($gridlines->getLineStyleProperty(['arrow', 'end', 'type'])) { > $objWriter->startElement('a:tailEnd'); > $objWriter->writeAttribute('type', $gridlines->getLineStyleProperty(['arrow', 'end', 'type'])); > $this->writeNotEmpty($objWriter, 'w', $gridlines->getLineStyleArrowWidth('end')); > $this->writeNotEmpty($objWriter, 'len', $gridlines->getLineStyleArrowLength('end')); > $objWriter->endElement(); > } > $objWriter->endElement(); //end ln > } > > private function writeNotEmpty(XMLWriter $objWriter, string $name, ?string $value): void > { > if ($value !== null && $value !== '') { > $objWriter->writeAttribute($name, $value); > } > } > > private function writeColor(XMLWriter $objWriter, ChartColor $chartColor, bool $solidFill = true): void > { > $type = $chartColor->getType(); > $value = $chartColor->getValue(); > if (!empty($type) && !empty($value)) { > if ($solidFill) { > $objWriter->startElement('a:solidFill'); > } > $objWriter->startElement("a:$type"); > $objWriter->writeAttribute('val', $value); > $alpha = $chartColor->getAlpha(); > if (is_numeric($alpha)) { > $objWriter->startElement('a:alpha'); > $objWriter->writeAttribute('val', ChartColor::alphaToXml((int) $alpha)); > $objWriter->endElement(); // a:alpha > } > $brightness = $chartColor->getBrightness(); > if (is_numeric($brightness)) { > $brightness = (int) $brightness; > $lumOff = 100 - $brightness; > $objWriter->startElement('a:lumMod'); > $objWriter->writeAttribute('val', ChartColor::alphaToXml($brightness)); > $objWriter->endElement(); // a:lumMod > $objWriter->startElement('a:lumOff'); > $objWriter->writeAttribute('val', ChartColor::alphaToXml($lumOff)); > $objWriter->endElement(); // a:lumOff > } > $objWriter->endElement(); //a:srgbClr/schemeClr/prstClr > if ($solidFill) { > $objWriter->endElement(); //a:solidFill > } > }