See Release Notes
Long Term Support Release
<?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 Chartif (($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:spPrif ($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 > } > }