Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
<?php

namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;

< use PhpOffice\PhpSpreadsheet\Calculation\Functions;
> use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; > use PhpOffice\PhpSpreadsheet\Chart\Axis; > use PhpOffice\PhpSpreadsheet\Chart\AxisText; > 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 as ChartProperties;
use PhpOffice\PhpSpreadsheet\Chart\Title;
> use PhpOffice\PhpSpreadsheet\Chart\TrendLine; use PhpOffice\PhpSpreadsheet\RichText\RichText; > use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
< use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Font; use SimpleXMLElement; class Chart {
> /** @var string */ /** > private $cNamespace; * @param string $name > * @param string $format > /** @var string */ * > private $aNamespace; * @return null|bool|float|int|string > */ > public function __construct(string $cNamespace = Namespaces::CHART, string $aNamespace = Namespaces::DRAWINGML) private static function getAttribute(SimpleXMLElement $component, $name, $format) > { { > $this->cNamespace = $cNamespace; $attributes = $component->attributes(); > $this->aNamespace = $aNamespace; if (isset($attributes[$name])) { > } if ($format == 'string') { >
< if (isset($attributes[$name])) {
> if (@isset($attributes[$name])) {
} elseif ($format == 'integer') { return (int) $attributes[$name]; } elseif ($format == 'boolean') {
< return (bool) ($attributes[$name] === '0' || $attributes[$name] !== 'true') ? false : true;
> $value = (string) $attributes[$name]; > > return $value === 'true' || $value === '1';
} return (float) $attributes[$name]; } return null; }
< private static function readColor($color, $background = false) < { < if (isset($color['rgb'])) { < return (string) $color['rgb']; < } elseif (isset($color['indexed'])) { < return Color::indexedColor($color['indexed'] - 7, $background)->getARGB(); < } < } <
/** * @param string $chartName * * @return \PhpOffice\PhpSpreadsheet\Chart\Chart */
< public static function readChart(SimpleXMLElement $chartElements, $chartName)
> public function readChart(SimpleXMLElement $chartElements, $chartName)
{
< $namespacesChartMeta = $chartElements->getNamespaces(true); < $chartElementsC = $chartElements->children($namespacesChartMeta['c']);
> $chartElementsC = $chartElements->children($this->cNamespace);
$XaxisLabel = $YaxisLabel = $legend = $title = null; $dispBlanksAs = $plotVisOnly = null;
<
> $plotArea = null; > $rotX = $rotY = $rAngAx = $perspective = null; > $xAxis = new Axis(); > $yAxis = new Axis(); > $autoTitleDeleted = null; > $chartNoFill = false; > $chartBorderLines = null; > $chartFillColor = null; > $gradientArray = []; > $gradientLin = null; > $roundedCorners = false; > $gapWidth = null; > $useUpBars = null; > $useDownBars = null;
foreach ($chartElementsC as $chartElementKey => $chartElement) { switch ($chartElementKey) {
> case 'spPr': case 'chart': > $children = $chartElementsC->spPr->children($this->aNamespace); foreach ($chartElement as $chartDetailsKey => $chartDetails) { > if (isset($children->noFill)) { $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); > $chartNoFill = true; switch ($chartDetailsKey) { > } case 'plotArea': > if (isset($children->solidFill)) { $plotAreaLayout = $XaxisLable = $YaxisLable = null; > $chartFillColor = $this->readColor($children->solidFill); $plotSeries = $plotAttributes = []; > } foreach ($chartDetails as $chartDetailKey => $chartDetail) { > if (isset($children->ln)) { switch ($chartDetailKey) { > $chartBorderLines = new GridLines(); case 'layout': > $this->readLineStyle($chartElementsC, $chartBorderLines); $plotAreaLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta); > } > break; > break; case 'catAx': > case 'roundedCorners': if (isset($chartDetail->title)) { > /** @var bool */ $XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta); > $roundedCorners = self::getAttribute($chartElementsC->roundedCorners, 'val', 'boolean'); } > > break;
< $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']);
> $chartDetails = Xlsx::testSimpleXml($chartDetails);
case 'dateAx':
> case 'autoTitleDeleted': if (isset($chartDetail->title)) { > /** @var bool */ $XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta); > $autoTitleDeleted = self::getAttribute($chartElementsC->chart->autoTitleDeleted, 'val', 'boolean'); } > > break; break; > case 'view3D': case 'valAx': > $rotX = self::getAttribute($chartDetails->rotX, 'val', 'integer'); if (isset($chartDetail->title)) { > $rotY = self::getAttribute($chartDetails->rotY, 'val', 'integer'); $YaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta); > $rAngAx = self::getAttribute($chartDetails->rAngAx, 'val', 'integer'); } > $perspective = self::getAttribute($chartDetails->perspective, 'val', 'integer'); > break; > break;
< $plotAreaLayout = $XaxisLable = $YaxisLable = null;
> $plotAreaLayout = $XaxisLabel = $YaxisLabel = null;
case 'bar3DChart':
> $catAxRead = false; $barDirection = self::getAttribute($chartDetail->barDir, 'val', 'string'); > $plotNoFill = false;
$plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey);
> $chartDetail = Xlsx::testSimpleXml($chartDetail);
$plotSer->setPlotDirection($barDirection);
> case 'spPr': $plotSeries[] = $plotSer; > $possibleNoFill = $chartDetails->spPr->children($this->aNamespace); $plotAttributes = self::readChartAttributes($chartDetail); > if (isset($possibleNoFill->noFill)) { > $plotNoFill = true; break; > } case 'lineChart': > if (isset($possibleNoFill->gradFill->gsLst)) { case 'line3DChart': > foreach ($possibleNoFill->gradFill->gsLst->gs as $gradient) { $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); > $gradient = Xlsx::testSimpleXml($gradient); $plotAttributes = self::readChartAttributes($chartDetail); > /** @var float */ > $pos = self::getAttribute($gradient, 'pos', 'float'); break; > $gradientArray[] = [ case 'areaChart': > $pos / ChartProperties::PERCENTAGE_MULTIPLIER, case 'area3DChart': > new ChartColor($this->readColor($gradient)), $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); > ]; $plotAttributes = self::readChartAttributes($chartDetail); > } > } break; > if (isset($possibleNoFill->gradFill->lin)) { case 'doughnutChart': > $gradientLin = ChartProperties::XmlToAngle((string) self::getAttribute($possibleNoFill->gradFill->lin, 'ang', 'string')); case 'pieChart': > } case 'pie3DChart': > $explosion = isset($chartDetail->ser->explosion); > break;
< $plotAreaLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta);
> $plotAreaLayout = $this->chartLayoutDetails($chartDetail);
< case 'catAx':
> case Axis::AXIS_TYPE_CATEGORY: > case Axis::AXIS_TYPE_DATE: > $catAxRead = true;
< $XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta);
> $XaxisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace));
$plotAttributes = self::readChartAttributes($chartDetail);
> $xAxis->setAxisType($chartDetailKey); > $this->readEffects($chartDetail, $xAxis); break; > $this->readLineStyle($chartDetail, $xAxis); case 'scatterChart': > if (isset($chartDetail->spPr)) { $scatterStyle = self::getAttribute($chartDetail->scatterStyle, 'val', 'string'); > $sppr = $chartDetail->spPr->children($this->aNamespace); $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); > if (isset($sppr->solidFill)) { $plotSer->setPlotStyle($scatterStyle); > $axisColorArray = $this->readColor($sppr->solidFill); $plotSeries[] = $plotSer; > $xAxis->setFillParameters($axisColorArray['value'], $axisColorArray['alpha'], $axisColorArray['type']); $plotAttributes = self::readChartAttributes($chartDetail); > } > if (isset($chartDetail->spPr->ln->noFill)) { break; > $xAxis->setNoFill(true); case 'bubbleChart': > } $bubbleScale = self::getAttribute($chartDetail->bubbleScale, 'val', 'integer'); > } $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); > if (isset($chartDetail->majorGridlines)) { $plotSer->setPlotStyle($bubbleScale); > $majorGridlines = new GridLines(); $plotSeries[] = $plotSer; > if (isset($chartDetail->majorGridlines->spPr)) { $plotAttributes = self::readChartAttributes($chartDetail); > $this->readEffects($chartDetail->majorGridlines, $majorGridlines); > $this->readLineStyle($chartDetail->majorGridlines, $majorGridlines); break; > } case 'radarChart': > $xAxis->setMajorGridlines($majorGridlines); $radarStyle = self::getAttribute($chartDetail->radarStyle, 'val', 'string'); > } $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); > if (isset($chartDetail->minorGridlines)) { $plotSer->setPlotStyle($radarStyle); > $minorGridlines = new GridLines(); $plotSeries[] = $plotSer; > $minorGridlines->activateObject(); $plotAttributes = self::readChartAttributes($chartDetail); > if (isset($chartDetail->minorGridlines->spPr)) { > $this->readEffects($chartDetail->minorGridlines, $minorGridlines); break; > $this->readLineStyle($chartDetail->minorGridlines, $minorGridlines); case 'surfaceChart': > } case 'surface3DChart': > $xAxis->setMinorGridlines($minorGridlines); $wireFrame = self::getAttribute($chartDetail->wireframe, 'val', 'boolean'); > } $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); > $this->setAxisProperties($chartDetail, $xAxis); $plotSer->setPlotStyle($wireFrame); > $plotSeries[] = $plotSer; > break; $plotAttributes = self::readChartAttributes($chartDetail); > case Axis::AXIS_TYPE_VALUE: > $whichAxis = null; break; > $axPos = null; case 'stockChart': > if (isset($chartDetail->axPos)) { $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); > $axPos = self::getAttribute($chartDetail->axPos, 'val', 'string'); $plotAttributes = self::readChartAttributes($plotAreaLayout); > } > if ($catAxRead) { break; > $whichAxis = $yAxis; } > $yAxis->setAxisType($chartDetailKey); } > } elseif (!empty($axPos)) { if ($plotAreaLayout == null) { > switch ($axPos) { $plotAreaLayout = new Layout(); > case 't': } > case 'b': $plotArea = new PlotArea($plotAreaLayout, $plotSeries); > $whichAxis = $xAxis; self::setChartAttributes($plotAreaLayout, $plotAttributes); > $xAxis->setAxisType($chartDetailKey); > break; > break; case 'plotVisOnly': > case 'r': $plotVisOnly = self::getAttribute($chartDetails, 'val', 'string'); > case 'l': > $whichAxis = $yAxis; break; > $yAxis->setAxisType($chartDetailKey);
< case 'dateAx': < if (isset($chartDetail->title)) { < $XaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta);
break;
> } case 'title': > if (isset($chartDetail->title)) { $title = self::chartTitle($chartDetails, $namespacesChartMeta); > $axisLabel = $this->chartTitle($chartDetail->title->children($this->cNamespace)); > break; > switch ($axPos) { case 'legend': > case 't': $legendPos = 'r'; > case 'b': $legendLayout = null; > $XaxisLabel = $axisLabel;
< case 'valAx': < if (isset($chartDetail->title)) { < $YaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta);
> case 'r': > case 'l': > $YaxisLabel = $axisLabel; > > break; > } > } > $this->readEffects($chartDetail, $whichAxis); > $this->readLineStyle($chartDetail, $whichAxis); > if ($whichAxis !== null && isset($chartDetail->spPr)) { > $sppr = $chartDetail->spPr->children($this->aNamespace); > if (isset($sppr->solidFill)) { > $axisColorArray = $this->readColor($sppr->solidFill); > $whichAxis->setFillParameters($axisColorArray['value'], $axisColorArray['alpha'], $axisColorArray['type']); > } > if (isset($sppr->ln->noFill)) { > $whichAxis->setNoFill(true); > }
case 'legendPos':
> if ($whichAxis !== null && isset($chartDetail->majorGridlines)) { $legendPos = self::getAttribute($chartDetail, 'val', 'string'); > $majorGridlines = new GridLines(); > if (isset($chartDetail->majorGridlines->spPr)) { break; > $this->readEffects($chartDetail->majorGridlines, $majorGridlines); case 'overlay': > $this->readLineStyle($chartDetail->majorGridlines, $majorGridlines); $legendOverlay = self::getAttribute($chartDetail, 'val', 'boolean'); > } > $whichAxis->setMajorGridlines($majorGridlines); break; > } case 'layout': > if ($whichAxis !== null && isset($chartDetail->minorGridlines)) { $legendLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta); > $minorGridlines = new GridLines(); > $minorGridlines->activateObject(); break; > if (isset($chartDetail->minorGridlines->spPr)) { } > $this->readEffects($chartDetail->minorGridlines, $minorGridlines); } > $this->readLineStyle($chartDetail->minorGridlines, $minorGridlines); $legend = new Legend($legendPos, $legendLayout, $legendOverlay); > } > $whichAxis->setMinorGridlines($minorGridlines); break; > } } > $this->setAxisProperties($chartDetail, $whichAxis);
< $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); < $plotSer->setPlotDirection($barDirection);
> $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey); > $plotSer->setPlotDirection("$barDirection");
< $plotAttributes = self::readChartAttributes($chartDetail);
> $plotAttributes = $this->readChartAttributes($chartDetail);
< $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); < $plotAttributes = self::readChartAttributes($chartDetail);
> $plotSeries[] = $this->chartDataSeries($chartDetail, $chartDetailKey); > $plotAttributes = $this->readChartAttributes($chartDetail);
< $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); < $plotAttributes = self::readChartAttributes($chartDetail);
> $plotSeries[] = $this->chartDataSeries($chartDetail, $chartDetailKey); > $plotAttributes = $this->readChartAttributes($chartDetail);
< $explosion = isset($chartDetail->ser->explosion); < $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); < $plotSer->setPlotStyle($explosion);
> $explosion = self::getAttribute($chartDetail->ser->explosion, 'val', 'string'); > $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey); > $plotSer->setPlotStyle("$explosion");
< $plotAttributes = self::readChartAttributes($chartDetail);
> $plotAttributes = $this->readChartAttributes($chartDetail);
$titleLayout = null;
> /** @var string */
< $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey);
> $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
< $plotAttributes = self::readChartAttributes($chartDetail);
> $plotAttributes = $this->readChartAttributes($chartDetail);
< $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); < $plotSer->setPlotStyle($bubbleScale);
> $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey); > $plotSer->setPlotStyle("$bubbleScale");
< $plotAttributes = self::readChartAttributes($chartDetail);
> $plotAttributes = $this->readChartAttributes($chartDetail);
switch ($titleKey) {
> /** @var string */
< $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey);
> $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey);
< $plotAttributes = self::readChartAttributes($chartDetail);
> $plotAttributes = $this->readChartAttributes($chartDetail);
< $plotSer = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); < $plotSer->setPlotStyle($wireFrame);
> $plotSer = $this->chartDataSeries($chartDetail, $chartDetailKey); > $plotSer->setPlotStyle("$wireFrame");
< $plotAttributes = self::readChartAttributes($chartDetail);
> $plotAttributes = $this->readChartAttributes($chartDetail);
< $plotSeries[] = self::chartDataSeries($chartDetail, $namespacesChartMeta, $chartDetailKey); < $plotAttributes = self::readChartAttributes($plotAreaLayout);
> $plotSeries[] = $this->chartDataSeries($chartDetail, $chartDetailKey); > if (isset($chartDetail->upDownBars->gapWidth)) { > $gapWidth = self::getAttribute($chartDetail->upDownBars->gapWidth, 'val', 'integer'); > } > if (isset($chartDetail->upDownBars->upBars)) { > $useUpBars = true; > } > if (isset($chartDetail->upDownBars->downBars)) { > $useDownBars = true; > } > $plotAttributes = $this->readChartAttributes($chartDetail);
< self::setChartAttributes($plotAreaLayout, $plotAttributes);
> $this->setChartAttributes($plotAreaLayout, $plotAttributes); > if ($plotNoFill) { > $plotArea->setNoFill(true); > } > if (!empty($gradientArray)) { > $plotArea->setGradientFillProperties($gradientArray, $gradientLin); > } > if (is_int($gapWidth)) { > $plotArea->setGapWidth($gapWidth); > } > if ($useUpBars === true) { > $plotArea->setUseUpBars(true); > } > if ($useDownBars === true) { > $plotArea->setUseDownBars(true); > }
< $title = self::chartTitle($chartDetails, $namespacesChartMeta);
> $title = $this->chartTitle($chartDetails);
> $legendBorderLines = null; break; > $legendFillColor = null; } > $legendText = null; } > $addLegendText = false;
> $chartDetail = Xlsx::testSimpleXml($chartDetail);
< $legendLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta);
> $legendLayout = $this->chartLayoutDetails($chartDetail);
}
> case 'spPr': > $children = $chartDetails->spPr->children($this->aNamespace); private static function chartLayoutDetails($chartDetail, $namespacesChartMeta) > if (isset($children->solidFill)) { { > $legendFillColor = $this->readColor($children->solidFill);
if (!isset($chartDetail->manualLayout)) {
> if (isset($children->ln)) { return null; > $legendBorderLines = new GridLines(); } > $this->readLineStyle($chartDetails, $legendBorderLines);
< $legend = new Legend($legendPos, $legendLayout, $legendOverlay);
if ($details === null) {
> case 'txPr': return null; > $children = $chartDetails->txPr->children($this->aNamespace); } > $addLegendText = false; $layout = []; > $legendText = new AxisText(); foreach ($details as $detailKey => $detail) { > if (isset($children->p->pPr->defRPr->solidFill)) { $layout[$detailKey] = self::getAttribute($detail, 'val', 'string'); > $colorArray = $this->readColor($children->p->pPr->defRPr->solidFill); } > $legendText->getFillColorObject()->setColorPropertiesArray($colorArray); > $addLegendText = true; return new Layout($layout); > } } > if (isset($children->p->pPr->defRPr->effectLst)) { > $this->readEffects($children->p->pPr->defRPr, $legendText, false); private static function chartDataSeries($chartDetail, $namespacesChartMeta, $plotType) > $addLegendText = true;
{
> $multiSeriesType = null; > break;
$smoothLine = false;
> $legend = new Legend("$legendPos", $legendLayout, (bool) $legendOverlay); $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = []; > if ($legendFillColor !== null) { > $legend->getFillColor()->setColorPropertiesArray($legendFillColor); $seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']); > } foreach ($seriesDetailSet as $seriesDetailKey => $seriesDetails) { > if ($legendBorderLines !== null) { switch ($seriesDetailKey) { > $legend->setBorderLines($legendBorderLines); case 'grouping': > } $multiSeriesType = self::getAttribute($chartDetail->grouping, 'val', 'string'); > if ($addLegendText) { > $legend->setLegendText($legendText); break; > } case 'ser': > $marker = null; > break; $seriesIndex = ''; > } foreach ($seriesDetails as $seriesKey => $seriesDetail) { > } switch ($seriesKey) { > } case 'idx': > } $seriesIndex = self::getAttribute($seriesDetail, 'val', 'integer'); > $chart = new \PhpOffice\PhpSpreadsheet\Chart\Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, (string) $dispBlanksAs, $XaxisLabel, $YaxisLabel, $xAxis, $yAxis); > if ($chartNoFill) { break; > $chart->setNoFill(true); case 'order': > } $seriesOrder = self::getAttribute($seriesDetail, 'val', 'integer'); > if ($chartFillColor !== null) { $plotOrder[$seriesIndex] = $seriesOrder; > $chart->getFillColor()->setColorPropertiesArray($chartFillColor); > } break; > if ($chartBorderLines !== null) { case 'tx': > $chart->setBorderLines($chartBorderLines); $seriesLabel[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); > } > $chart->setRoundedCorners($roundedCorners); break; > if (is_bool($autoTitleDeleted)) { case 'marker': > $chart->setAutoTitleDeleted($autoTitleDeleted); $marker = self::getAttribute($seriesDetail->symbol, 'val', 'string'); > } > if (is_int($rotX)) { break; > $chart->setRotX($rotX); case 'smooth': > } $smoothLine = self::getAttribute($seriesDetail, 'val', 'boolean'); > if (is_int($rotY)) { > $chart->setRotY($rotY); break; > } case 'cat': > if (is_int($rAngAx)) { $seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta); > $chart->setRAngAx($rAngAx); > } break; > if (is_int($perspective)) { case 'val': > $chart->setPerspective($perspective);
< $chart = new \PhpOffice\PhpSpreadsheet\Chart\Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, $dispBlanksAs, $XaxisLabel, $YaxisLabel);
< private static function chartTitle(SimpleXMLElement $titleDetails, array $namespacesChartMeta)
> private function chartTitle(SimpleXMLElement $titleDetails): Title
break;
> $titleOverlay = false;
case 'xVal':
> $chartDetail = Xlsx::testSimpleXml($chartDetail);
< $titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']);
> if (isset($chartDetail->rich)) { > $titleDetails = $chartDetail->rich->children($this->aNamespace);
> $titleDetail = Xlsx::testSimpleXml($titleDetail);
< $titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); < $caption[] = self::parseRichText($titleDetailPart);
> $titleDetailPart = $titleDetail->children($this->aNamespace); > $caption[] = $this->parseRichText($titleDetailPart); > } > } > } elseif (isset($chartDetail->strRef->strCache)) { > foreach ($chartDetail->strRef->strCache->pt as $pt) { > if (isset($pt->v)) { > $caption[] = (string) $pt->v; > }
$seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker);
> case 'overlay': > $titleOverlay = self::getAttribute($chartDetail, 'val', 'boolean'); break; > } > break;
< $titleLayout = self::chartLayoutDetails($chartDetail, $namespacesChartMeta);
> $titleLayout = $this->chartLayoutDetails($chartDetail);
< return new Title($caption, $titleLayout);
> return new Title($caption, $titleLayout, (bool) $titleOverlay);
< private static function chartLayoutDetails($chartDetail, $namespacesChartMeta)
> private function chartLayoutDetails(SimpleXMLElement $chartDetail): ?Layout
< $details = $chartDetail->manualLayout->children($namespacesChartMeta['c']);
> $details = $chartDetail->manualLayout->children($this->cNamespace);
return new DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine);
> $detail = Xlsx::testSimpleXml($detail);
< private static function chartDataSeries($chartDetail, $namespacesChartMeta, $plotType)
> private function chartDataSeries(SimpleXMLElement $chartDetail, string $plotType): DataSeries
< $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = [];
> $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = $seriesBubbles = [];
< $seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']);
> $seriesDetailSet = $chartDetail->children($this->cNamespace);
{
> $fillColor = null; if (isset($seriesDetail->strRef)) { > $pointSize = null; $seriesSource = (string) $seriesDetail->strRef->f; > $noFill = false; $seriesData = self::chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's'); > $bubble3D = false; > $dptColors = []; return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker); > $markerFillColor = null; } elseif (isset($seriesDetail->numRef)) { > $markerBorderColor = null; $seriesSource = (string) $seriesDetail->numRef->f; > $lineStyle = null; $seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); > $labelLayout = null; > $trendLines = [];
return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
> $seriesDetail = Xlsx::testSimpleXml($seriesDetail);
< $seriesLabel[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta);
> $seriesLabel[$seriesIndex] = $this->chartDataSeriesValueSet($seriesDetail); > > break; > case 'spPr': > $children = $seriesDetail->children($this->aNamespace); > if (isset($children->ln)) { > $ln = $children->ln; > if (is_countable($ln->noFill) && count($ln->noFill) === 1) { > $noFill = true; > } > $lineStyle = new GridLines(); > $this->readLineStyle($seriesDetails, $lineStyle); > } > if (isset($children->effectLst)) { > if ($lineStyle === null) { > $lineStyle = new GridLines(); > } > $this->readEffects($seriesDetails, $lineStyle); > } > if (isset($children->solidFill)) { > $fillColor = new ChartColor($this->readColor($children->solidFill)); > } > > break; > case 'dPt': > $dptIdx = (int) self::getAttribute($seriesDetail->idx, 'val', 'string'); > if (isset($seriesDetail->spPr)) { > $children = $seriesDetail->spPr->children($this->aNamespace); > if (isset($children->solidFill)) { > $arrayColors = $this->readColor($children->solidFill); > $dptColors[$dptIdx] = new ChartColor($arrayColors); > } > } > > break; > case 'trendline': > $trendLine = new TrendLine(); > $this->readLineStyle($seriesDetail, $trendLine); > /** @var ?string */ > $trendLineType = self::getAttribute($seriesDetail->trendlineType, 'val', 'string'); > /** @var ?bool */ > $dispRSqr = self::getAttribute($seriesDetail->dispRSqr, 'val', 'boolean'); > /** @var ?bool */ > $dispEq = self::getAttribute($seriesDetail->dispEq, 'val', 'boolean'); > /** @var ?int */ > $order = self::getAttribute($seriesDetail->order, 'val', 'integer'); > /** @var ?int */ > $period = self::getAttribute($seriesDetail->period, 'val', 'integer'); > /** @var ?float */ > $forward = self::getAttribute($seriesDetail->forward, 'val', 'float'); > /** @var ?float */ > $backward = self::getAttribute($seriesDetail->backward, 'val', 'float'); > /** @var ?float */ > $intercept = self::getAttribute($seriesDetail->intercept, 'val', 'float'); > /** @var ?string */ > $name = (string) $seriesDetail->name; > $trendLine->setTrendLineProperties( > $trendLineType, > $order, > $period, > $dispRSqr, > $dispEq, > $backward, > $forward, > $intercept, > $name > ); > $trendLines[] = $trendLine;
$seriesSource = (string) $seriesDetail->multiLvlStrRef->f;
> $pointSize = self::getAttribute($seriesDetail->size, 'val', 'string'); $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's'); > $pointSize = is_numeric($pointSize) ? ((int) $pointSize) : null; $seriesData['pointCount'] = count($seriesData['dataValues']); > if (isset($seriesDetail->spPr)) { > $children = $seriesDetail->spPr->children($this->aNamespace); return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker); > if (isset($children->solidFill)) { } elseif (isset($seriesDetail->multiLvlNumRef)) { > $markerFillColor = $this->readColor($children->solidFill); $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; > } $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's'); > if (isset($children->ln->solidFill)) { $seriesData['pointCount'] = count($seriesData['dataValues']); > $markerBorderColor = $this->readColor($children->ln->solidFill); > } return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker); > }
< $seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta);
> $seriesCategory[$seriesIndex] = $this->chartDataSeriesValueSet($seriesDetail);
< $seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker);
> $seriesValues[$seriesIndex] = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize");
< $seriesCategory[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker);
> $seriesCategory[$seriesIndex] = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize");
< $seriesValues[$seriesIndex] = self::chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker);
> $seriesValues[$seriesIndex] = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize"); > > break; > case 'bubbleSize': > $seriesBubbles[$seriesIndex] = $this->chartDataSeriesValueSet($seriesDetail, "$marker", $fillColor, "$pointSize");
> case 'bubble3D': private static function chartDataSeriesValues($seriesValueSet, $dataType = 'n') > $bubble3D = self::getAttribute($seriesDetail, 'val', 'boolean'); { > $seriesVal = []; > break; $formatCode = ''; > case 'dLbls': $pointCount = 0; > $labelLayout = new Layout($this->readChartAttributes($seriesDetails)); > foreach ($seriesValueSet as $seriesValueIdx => $seriesValue) { > break; switch ($seriesValueIdx) { > } case 'ptCount': > } $pointCount = self::getAttribute($seriesValue, 'val', 'integer'); > if ($labelLayout) { > if (isset($seriesLabel[$seriesIndex])) { break; > $seriesLabel[$seriesIndex]->setLabelLayout($labelLayout); case 'formatCode': > } $formatCode = (string) $seriesValue; > if (isset($seriesCategory[$seriesIndex])) { > $seriesCategory[$seriesIndex]->setLabelLayout($labelLayout); break; > } case 'pt': > if (isset($seriesValues[$seriesIndex])) { $pointVal = self::getAttribute($seriesValue, 'idx', 'integer'); > $seriesValues[$seriesIndex]->setLabelLayout($labelLayout); if ($dataType == 's') { > } $seriesVal[$pointVal] = (string) $seriesValue->v; > } } elseif ($seriesValue->v === Functions::NA()) { > if ($noFill) { $seriesVal[$pointVal] = null; > if (isset($seriesLabel[$seriesIndex])) { } else { > $seriesLabel[$seriesIndex]->setScatterLines(false); $seriesVal[$pointVal] = (float) $seriesValue->v; > } } > if (isset($seriesCategory[$seriesIndex])) { > $seriesCategory[$seriesIndex]->setScatterLines(false); break; > } } > if (isset($seriesValues[$seriesIndex])) { } > $seriesValues[$seriesIndex]->setScatterLines(false); > } return [ > } 'formatCode' => $formatCode, > if ($lineStyle !== null) { 'pointCount' => $pointCount, > if (isset($seriesLabel[$seriesIndex])) { 'dataValues' => $seriesVal, > $seriesLabel[$seriesIndex]->copyLineStyles($lineStyle); ]; > } } > if (isset($seriesCategory[$seriesIndex])) { > $seriesCategory[$seriesIndex]->copyLineStyles($lineStyle); private static function chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType = 'n') > } { > if (isset($seriesValues[$seriesIndex])) { $seriesVal = []; > $seriesValues[$seriesIndex]->copyLineStyles($lineStyle); $formatCode = ''; > } $pointCount = 0; > } > if ($bubble3D) { foreach ($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { > if (isset($seriesLabel[$seriesIndex])) { foreach ($seriesLevel as $seriesValueIdx => $seriesValue) { > $seriesLabel[$seriesIndex]->setBubble3D($bubble3D); switch ($seriesValueIdx) { > } case 'ptCount': > if (isset($seriesCategory[$seriesIndex])) { $pointCount = self::getAttribute($seriesValue, 'val', 'integer'); > $seriesCategory[$seriesIndex]->setBubble3D($bubble3D); > } break; > if (isset($seriesValues[$seriesIndex])) { case 'formatCode': > $seriesValues[$seriesIndex]->setBubble3D($bubble3D); $formatCode = (string) $seriesValue; > } > } break; > if (!empty($dptColors)) { case 'pt': > if (isset($seriesLabel[$seriesIndex])) { $pointVal = self::getAttribute($seriesValue, 'idx', 'integer'); > $seriesLabel[$seriesIndex]->setFillColor($dptColors); if ($dataType == 's') { > } $seriesVal[$pointVal][] = (string) $seriesValue->v; > if (isset($seriesCategory[$seriesIndex])) { } elseif ($seriesValue->v === Functions::NA()) { > $seriesCategory[$seriesIndex]->setFillColor($dptColors); $seriesVal[$pointVal] = null; > } } else { > if (isset($seriesValues[$seriesIndex])) { $seriesVal[$pointVal][] = (float) $seriesValue->v; > $seriesValues[$seriesIndex]->setFillColor($dptColors); } > } > } break; > if ($markerFillColor !== null) { } > if (isset($seriesLabel[$seriesIndex])) { } > $seriesLabel[$seriesIndex]->getMarkerFillColor()->setColorPropertiesArray($markerFillColor); } > } > if (isset($seriesCategory[$seriesIndex])) { return [ > $seriesCategory[$seriesIndex]->getMarkerFillColor()->setColorPropertiesArray($markerFillColor); 'formatCode' => $formatCode, > } 'pointCount' => $pointCount, > if (isset($seriesValues[$seriesIndex])) { 'dataValues' => $seriesVal, > $seriesValues[$seriesIndex]->getMarkerFillColor()->setColorPropertiesArray($markerFillColor); ]; > } } > } > if ($markerBorderColor !== null) { private static function parseRichText(SimpleXMLElement $titleDetailPart) > if (isset($seriesLabel[$seriesIndex])) { { > $seriesLabel[$seriesIndex]->getMarkerBorderColor()->setColorPropertiesArray($markerBorderColor); $value = new RichText(); > } $objText = null; > if (isset($seriesCategory[$seriesIndex])) { foreach ($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { > $seriesCategory[$seriesIndex]->getMarkerBorderColor()->setColorPropertiesArray($markerBorderColor); if (isset($titleDetailElement->t)) { > } $objText = $value->createTextRun((string) $titleDetailElement->t); > if (isset($seriesValues[$seriesIndex])) { } > $seriesValues[$seriesIndex]->getMarkerBorderColor()->setColorPropertiesArray($markerBorderColor); if (isset($titleDetailElement->rPr)) { > } if (isset($titleDetailElement->rPr->rFont['val'])) { > } $objText->getFont()->setName((string) $titleDetailElement->rPr->rFont['val']); > if ($smoothLine) { } > if (isset($seriesLabel[$seriesIndex])) { > $seriesLabel[$seriesIndex]->setSmoothLine(true); $fontSize = (self::getAttribute($titleDetailElement->rPr, 'sz', 'integer')); > } if ($fontSize !== null) { > if (isset($seriesCategory[$seriesIndex])) { $objText->getFont()->setSize(floor($fontSize / 100)); > $seriesCategory[$seriesIndex]->setSmoothLine(true); } > } > if (isset($seriesValues[$seriesIndex])) { $fontColor = (self::getAttribute($titleDetailElement->rPr, 'color', 'string')); > $seriesValues[$seriesIndex]->setSmoothLine(true); if ($fontColor !== null) { > } $objText->getFont()->setColor(new Color(self::readColor($fontColor))); > } } > if (!empty($trendLines)) { > if (isset($seriesLabel[$seriesIndex])) { $bold = self::getAttribute($titleDetailElement->rPr, 'b', 'boolean'); > $seriesLabel[$seriesIndex]->setTrendLines($trendLines);
if ($bold !== null) {
> if (isset($seriesCategory[$seriesIndex])) { $objText->getFont()->setBold($bold); > $seriesCategory[$seriesIndex]->setTrendLines($trendLines);
}
> if (isset($seriesValues[$seriesIndex])) { > $seriesValues[$seriesIndex]->setTrendLines($trendLines);
$italic = self::getAttribute($titleDetailElement->rPr, 'i', 'boolean');
> } if ($italic !== null) { > } $objText->getFont()->setItalic($italic); > /** @phpstan-ignore-next-line */ } > $series = new DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine); > $series->setPlotBubbleSizes($seriesBubbles);
< return new DataSeries($plotType, $multiSeriesType, $plotOrder, $seriesLabel, $seriesCategory, $seriesValues, $smoothLine);
> return $series;
< private static function chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null)
> /** > * @return mixed > */ > private function chartDataSeriesValueSet(SimpleXMLElement $seriesDetail, ?string $marker = null, ?ChartColor $fillColor = null, ?string $pointSize = null)
< $seriesData = self::chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's');
> $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize");
< return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
> if (isset($seriesDetail->strRef->strCache)) { > $seriesData = $this->chartDataSeriesValues($seriesDetail->strRef->strCache->children($this->cNamespace), 's'); > $seriesValues > ->setFormatCode($seriesData['formatCode']) > ->setDataValues($seriesData['dataValues']); > } > > return $seriesValues;
< $seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c']));
> $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize"); > if (isset($seriesDetail->numRef->numCache)) { > $seriesData = $this->chartDataSeriesValues($seriesDetail->numRef->numCache->children($this->cNamespace)); > $seriesValues > ->setFormatCode($seriesData['formatCode']) > ->setDataValues($seriesData['dataValues']); > }
< return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
> return $seriesValues;
< $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's'); < $seriesData['pointCount'] = count($seriesData['dataValues']);
> $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize");
< return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
> if (isset($seriesDetail->multiLvlStrRef->multiLvlStrCache)) { > $seriesData = $this->chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($this->cNamespace), 's'); > $seriesValues > ->setFormatCode($seriesData['formatCode']) > ->setDataValues($seriesData['dataValues']); > } > > return $seriesValues;
< $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's'); < $seriesData['pointCount'] = count($seriesData['dataValues']);
> $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, 0, null, $marker, $fillColor, "$pointSize");
< return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
> if (isset($seriesDetail->multiLvlNumRef->multiLvlNumCache)) { > $seriesData = $this->chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($this->cNamespace), 's'); > $seriesValues > ->setFormatCode($seriesData['formatCode']) > ->setDataValues($seriesData['dataValues']); > } > > return $seriesValues; > } > > if (isset($seriesDetail->v)) { > return new DataSeriesValues( > DataSeriesValues::DATASERIES_TYPE_STRING, > null, > null, > 1, > [(string) $seriesDetail->v] > );
< private static function chartDataSeriesValues($seriesValueSet, $dataType = 'n')
> private function chartDataSeriesValues(SimpleXMLElement $seriesValueSet, string $dataType = 'n'): array
} elseif ($underscore == 'dbl') {
> $seriesValue = Xlsx::testSimpleXml($seriesValue);
< } elseif ($seriesValue->v === Functions::NA()) {
> } elseif ((string) $seriesValue->v === ExcelError::NA()) {
< private static function chartDataSeriesValuesMultiLevel($seriesValueSet, $dataType = 'n')
> private function chartDataSeriesValuesMultiLevel(SimpleXMLElement $seriesValueSet, string $dataType = 'n'): array
$objText->getFont()->setUnderline(Font::UNDERLINE_NONE);
> $seriesValue = Xlsx::testSimpleXml($seriesValue);
< } elseif ($seriesValue->v === Functions::NA()) {
> } elseif ((string) $seriesValue->v === ExcelError::NA()) {
< private static function parseRichText(SimpleXMLElement $titleDetailPart)
> private function parseRichText(SimpleXMLElement $titleDetailPart): RichText
< $objText = null;
> $defaultFontSize = null; > $defaultBold = null; > $defaultItalic = null; > $defaultUnderscore = null; > $defaultStrikethrough = null; > $defaultBaseline = null; > $defaultFontName = null; > $defaultLatin = null; > $defaultEastAsian = null; > $defaultComplexScript = null; > $defaultFontColor = null; > if (isset($titleDetailPart->pPr->defRPr)) { > /** @var ?int */ > $defaultFontSize = self::getAttribute($titleDetailPart->pPr->defRPr, 'sz', 'integer'); > /** @var ?bool */ > $defaultBold = self::getAttribute($titleDetailPart->pPr->defRPr, 'b', 'boolean'); > /** @var ?bool */ > $defaultItalic = self::getAttribute($titleDetailPart->pPr->defRPr, 'i', 'boolean'); > /** @var ?string */ > $defaultUnderscore = self::getAttribute($titleDetailPart->pPr->defRPr, 'u', 'string'); > /** @var ?string */ > $defaultStrikethrough = self::getAttribute($titleDetailPart->pPr->defRPr, 'strike', 'string'); > /** @var ?int */ > $defaultBaseline = self::getAttribute($titleDetailPart->pPr->defRPr, 'baseline', 'integer'); > if (isset($titleDetailPart->defRPr->rFont['val'])) { > $defaultFontName = (string) $titleDetailPart->defRPr->rFont['val']; > } > if (isset($titleDetailPart->pPr->defRPr->latin)) { > /** @var ?string */ > $defaultLatin = self::getAttribute($titleDetailPart->pPr->defRPr->latin, 'typeface', 'string'); > } > if (isset($titleDetailPart->pPr->defRPr->ea)) { > /** @var ?string */ > $defaultEastAsian = self::getAttribute($titleDetailPart->pPr->defRPr->ea, 'typeface', 'string'); > } > if (isset($titleDetailPart->pPr->defRPr->cs)) { > /** @var ?string */ > $defaultComplexScript = self::getAttribute($titleDetailPart->pPr->defRPr->cs, 'typeface', 'string'); > } > if (isset($titleDetailPart->pPr->defRPr->solidFill)) { > $defaultFontColor = $this->readColor($titleDetailPart->pPr->defRPr->solidFill); > } > }
< if (isset($titleDetailElement->t)) { < $objText = $value->createTextRun((string) $titleDetailElement->t);
> if ( > (string) $titleDetailElementKey !== 'r' > || !isset($titleDetailElement->t) > ) { > continue;
if ($strikethrough == 'noStrike') {
> $objText = $value->createTextRun((string) $titleDetailElement->t); $objText->getFont()->setStrikethrough(false); > if ($objText->getFont() === null) { } else { > // @codeCoverageIgnoreStart $objText->getFont()->setStrikethrough(true); > continue; } > // @codeCoverageIgnoreEnd } > } } > $fontSize = null; } > $bold = null; > $italic = null; return $value; > $underscore = null; } > $strikethrough = null; > $baseline = null; private static function readChartAttributes($chartDetail) > $fontName = null; { > $latinName = null; $plotAttributes = []; > $eastAsian = null; if (isset($chartDetail->dLbls)) { > $complexScript = null; if (isset($chartDetail->dLbls->howLegendKey)) { > $fontColor = null; $plotAttributes['showLegendKey'] = self::getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); > $underlineColor = null;
}
> // not used now, not sure it ever was, grandfathering
< $objText->getFont()->setName((string) $titleDetailElement->rPr->rFont['val']);
> // @codeCoverageIgnoreStart > $fontName = (string) $titleDetailElement->rPr->rFont['val']; > // @codeCoverageIgnoreEnd > } > if (isset($titleDetailElement->rPr->latin)) { > /** @var ?string */ > $latinName = self::getAttribute($titleDetailElement->rPr->latin, 'typeface', 'string');
$plotAttributes['showVal'] = self::getAttribute($chartDetail->dLbls->showVal, 'val', 'string');
> if (isset($titleDetailElement->rPr->ea)) { } > /** @var ?string */ if (isset($chartDetail->dLbls->showCatName)) { > $eastAsian = self::getAttribute($titleDetailElement->rPr->ea, 'typeface', 'string'); $plotAttributes['showCatName'] = self::getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); > } } > if (isset($titleDetailElement->rPr->cs)) { if (isset($chartDetail->dLbls->showSerName)) { > /** @var ?string */ $plotAttributes['showSerName'] = self::getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); > $complexScript = self::getAttribute($titleDetailElement->rPr->cs, 'typeface', 'string'); } > } if (isset($chartDetail->dLbls->showPercent)) { > /** @var ?int */ $plotAttributes['showPercent'] = self::getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); > $fontSize = self::getAttribute($titleDetailElement->rPr, 'sz', 'integer'); } > if (isset($chartDetail->dLbls->showBubbleSize)) { > // not used now, not sure it ever was, grandfathering $plotAttributes['showBubbleSize'] = self::getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); > if (isset($titleDetailElement->rPr->solidFill)) { } > $fontColor = $this->readColor($titleDetailElement->rPr->solidFill); if (isset($chartDetail->dLbls->showLeaderLines)) { > } $plotAttributes['showLeaderLines'] = self::getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); > } > /** @var ?bool */ } > $bold = self::getAttribute($titleDetailElement->rPr, 'b', 'boolean'); > return $plotAttributes; > /** @var ?bool */ } > $italic = self::getAttribute($titleDetailElement->rPr, 'i', 'boolean');
< $fontSize = (self::getAttribute($titleDetailElement->rPr, 'sz', 'integer')); < if ($fontSize !== null) {
> /** @var ?int */ > $baseline = self::getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); > > /** @var ?string */ > $underscore = self::getAttribute($titleDetailElement->rPr, 'u', 'string'); > if (isset($titleDetailElement->rPr->uFill->solidFill)) { > $underlineColor = $this->readColor($titleDetailElement->rPr->uFill->solidFill); > } > > /** @var ?string */ > $strikethrough = self::getAttribute($titleDetailElement->rPr, 'strike', 'string'); > } > > $fontFound = false; > $latinName = $latinName ?? $defaultLatin; > if ($latinName !== null) { > $objText->getFont()->setLatin($latinName); > $fontFound = true; > } > $eastAsian = $eastAsian ?? $defaultEastAsian; > if ($eastAsian !== null) { > $objText->getFont()->setEastAsian($eastAsian); > $fontFound = true; > } > $complexScript = $complexScript ?? $defaultComplexScript; > if ($complexScript !== null) { > $objText->getFont()->setComplexScript($complexScript); > $fontFound = true; > } > $fontName = $fontName ?? $defaultFontName; > if ($fontName !== null) { > // @codeCoverageIgnoreStart > $objText->getFont()->setName($fontName); > $fontFound = true; > // @codeCoverageIgnoreEnd > } > > $fontSize = $fontSize ?? $defaultFontSize; > if (is_int($fontSize)) {
* @param mixed $plotAttributes
> $fontFound = true; */ > } else { private static function setChartAttributes(Layout $plotArea, $plotAttributes): void > $objText->getFont()->setSize(null, true);
< $fontColor = (self::getAttribute($titleDetailElement->rPr, 'color', 'string')); < if ($fontColor !== null) { < $objText->getFont()->setColor(new Color(self::readColor($fontColor)));
> $fontColor = $fontColor ?? $defaultFontColor; > if (!empty($fontColor)) { > $objText->getFont()->setChartColor($fontColor); > $fontFound = true;
< $bold = self::getAttribute($titleDetailElement->rPr, 'b', 'boolean');
> $bold = $bold ?? $defaultBold;
$plotArea->setShowLegendKey($plotAttributeValue);
> $fontFound = true;
< $italic = self::getAttribute($titleDetailElement->rPr, 'i', 'boolean');
> $italic = $italic ?? $defaultItalic;
break;
> $fontFound = true;
< $baseline = self::getAttribute($titleDetailElement->rPr, 'baseline', 'integer');
> $baseline = $baseline ?? $defaultBaseline;
$plotArea->setShowVal($plotAttributeValue);
> $objText->getFont()->setBaseLine($baseline);
> $fontFound = true;
< $underscore = (self::getAttribute($titleDetailElement->rPr, 'u', 'string'));
> $underscore = $underscore ?? $defaultUnderscore;
case 'showCatName':
> } elseif ($underscore !== '') { $plotArea->setShowCatName($plotAttributeValue); > $objText->getFont()->setUnderline($underscore);
> $fontFound = true; break; > if ($underlineColor) { case 'showSerName': > $objText->getFont()->setUnderlineColor($underlineColor); $plotArea->setShowSerName($plotAttributeValue); > }
< $strikethrough = (self::getAttribute($titleDetailElement->rPr, 's', 'string'));
> $strikethrough = $strikethrough ?? $defaultStrikethrough;
break;
> $objText->getFont()->setStrikeType($strikethrough);
case 'showPercent':
> $fontFound = true;
$plotArea->setShowPercent($plotAttributeValue);
> if ($fontFound === false) { > $objText->setFont(null);
< private static function readChartAttributes($chartDetail)
> private function parseFont(SimpleXMLElement $titleDetailPart): ?Font > { > if (!isset($titleDetailPart->pPr->defRPr)) { > return null; > } > $fontArray = []; > $fontArray['size'] = self::getAttribute($titleDetailPart->pPr->defRPr, 'sz', 'integer'); > $fontArray['bold'] = self::getAttribute($titleDetailPart->pPr->defRPr, 'b', 'boolean'); > $fontArray['italic'] = self::getAttribute($titleDetailPart->pPr->defRPr, 'i', 'boolean'); > $fontArray['underscore'] = self::getAttribute($titleDetailPart->pPr->defRPr, 'u', 'string'); > $fontArray['strikethrough'] = self::getAttribute($titleDetailPart->pPr->defRPr, 'strike', 'string'); > > if (isset($titleDetailPart->pPr->defRPr->latin)) { > $fontArray['latin'] = self::getAttribute($titleDetailPart->pPr->defRPr->latin, 'typeface', 'string'); > } > if (isset($titleDetailPart->pPr->defRPr->ea)) { > $fontArray['eastAsian'] = self::getAttribute($titleDetailPart->pPr->defRPr->ea, 'typeface', 'string'); > } > if (isset($titleDetailPart->pPr->defRPr->cs)) { > $fontArray['complexScript'] = self::getAttribute($titleDetailPart->pPr->defRPr->cs, 'typeface', 'string'); > } > if (isset($titleDetailPart->pPr->defRPr->solidFill)) { > $fontArray['chartColor'] = new ChartColor($this->readColor($titleDetailPart->pPr->defRPr->solidFill)); > } > $font = new Font(); > $font->setSize(null, true); > $font->applyFromArray($fontArray); > > return $font; > } > > /** > * @param ?SimpleXMLElement $chartDetail > */ > private function readChartAttributes($chartDetail): array
< if (isset($chartDetail->dLbls->howLegendKey)) {
> if (isset($chartDetail->dLbls->dLblPos)) { > $plotAttributes['dLblPos'] = self::getAttribute($chartDetail->dLbls->dLblPos, 'val', 'string'); > } > if (isset($chartDetail->dLbls->numFmt)) { > $plotAttributes['numFmtCode'] = self::getAttribute($chartDetail->dLbls->numFmt, 'formatCode', 'string'); > $plotAttributes['numFmtLinked'] = self::getAttribute($chartDetail->dLbls->numFmt, 'sourceLinked', 'boolean'); > } > if (isset($chartDetail->dLbls->showLegendKey)) {
$plotArea->setShowBubbleSize($plotAttributeValue);
> if (isset($chartDetail->dLbls->spPr)) { > $sppr = $chartDetail->dLbls->spPr->children($this->aNamespace); break; > if (isset($sppr->solidFill)) { case 'showLeaderLines': > $plotAttributes['labelFillColor'] = new ChartColor($this->readColor($sppr->solidFill)); $plotArea->setShowLeaderLines($plotAttributeValue); > } > if (isset($sppr->ln->solidFill)) { break; > $plotAttributes['labelBorderColor'] = new ChartColor($this->readColor($sppr->ln->solidFill)); } > } } > } } > if (isset($chartDetail->dLbls->txPr)) { } > $txpr = $chartDetail->dLbls->txPr->children($this->aNamespace); > if (isset($txpr->p)) { > $plotAttributes['labelFont'] = $this->parseFont($txpr->p); > if (isset($txpr->p->pPr->defRPr->effectLst)) { > $labelEffects = new GridLines(); > $this->readEffects($txpr->p->pPr->defRPr, $labelEffects, false); > $plotAttributes['labelEffects'] = $labelEffects; > } > } > }
< private static function setChartAttributes(Layout $plotArea, $plotAttributes): void
> private function setChartAttributes(Layout $plotArea, $plotAttributes): void
> } > } > } > > private function readEffects(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject, bool $getSppr = true): void > { > if (!isset($chartObject)) { > return; > } > if ($getSppr) { > if (!isset($chartDetail->spPr)) { > return; > } > $sppr = $chartDetail->spPr->children($this->aNamespace); > } else { > $sppr = $chartDetail; > } > if (isset($sppr->effectLst->glow)) { > $axisGlowSize = (float) self::getAttribute($sppr->effectLst->glow, 'rad', 'integer') / ChartProperties::POINTS_WIDTH_MULTIPLIER; > if ($axisGlowSize != 0.0) { > $colorArray = $this->readColor($sppr->effectLst->glow); > $chartObject->setGlowProperties($axisGlowSize, $colorArray['value'], $colorArray['alpha'], $colorArray['type']); > } > } > > if (isset($sppr->effectLst->softEdge)) { > /** @var string */ > $softEdgeSize = self::getAttribute($sppr->effectLst->softEdge, 'rad', 'string'); > if (is_numeric($softEdgeSize)) { > $chartObject->setSoftEdges((float) ChartProperties::xmlToPoints($softEdgeSize)); > } > } > > $type = ''; > foreach (self::SHADOW_TYPES as $shadowType) { > if (isset($sppr->effectLst->$shadowType)) { > $type = $shadowType; > > break; > } > } > if ($type !== '') { > /** @var string */ > $blur = self::getAttribute($sppr->effectLst->$type, 'blurRad', 'string'); > $blur = is_numeric($blur) ? ChartProperties::xmlToPoints($blur) : null; > /** @var string */ > $dist = self::getAttribute($sppr->effectLst->$type, 'dist', 'string'); > $dist = is_numeric($dist) ? ChartProperties::xmlToPoints($dist) : null; > /** @var string */ > $direction = self::getAttribute($sppr->effectLst->$type, 'dir', 'string'); > $direction = is_numeric($direction) ? ChartProperties::xmlToAngle($direction) : null; > $algn = self::getAttribute($sppr->effectLst->$type, 'algn', 'string'); > $rot = self::getAttribute($sppr->effectLst->$type, 'rotWithShape', 'string'); > $size = []; > foreach (['sx', 'sy'] as $sizeType) { > $sizeValue = self::getAttribute($sppr->effectLst->$type, $sizeType, 'string'); > if (is_numeric($sizeValue)) { > $size[$sizeType] = ChartProperties::xmlToTenthOfPercent((string) $sizeValue); > } else { > $size[$sizeType] = null; > } > } > foreach (['kx', 'ky'] as $sizeType) { > $sizeValue = self::getAttribute($sppr->effectLst->$type, $sizeType, 'string'); > if (is_numeric($sizeValue)) { > $size[$sizeType] = ChartProperties::xmlToAngle((string) $sizeValue); > } else { > $size[$sizeType] = null; > } > } > $colorArray = $this->readColor($sppr->effectLst->$type); > $chartObject > ->setShadowProperty('effect', $type) > ->setShadowProperty('blur', $blur) > ->setShadowProperty('direction', $direction) > ->setShadowProperty('distance', $dist) > ->setShadowProperty('algn', $algn) > ->setShadowProperty('rotWithShape', $rot) > ->setShadowProperty('size', $size) > ->setShadowProperty('color', $colorArray); > } > } > > private const SHADOW_TYPES = [ > 'outerShdw', > 'innerShdw', > ]; > > private function readColor(SimpleXMLElement $colorXml): array > { > $result = [ > 'type' => null, > 'value' => null, > 'alpha' => null, > 'brightness' => null, > ]; > foreach (ChartColor::EXCEL_COLOR_TYPES as $type) { > if (isset($colorXml->$type)) { > $result['type'] = $type; > $result['value'] = self::getAttribute($colorXml->$type, 'val', 'string'); > if (isset($colorXml->$type->alpha)) { > /** @var string */ > $alpha = self::getAttribute($colorXml->$type->alpha, 'val', 'string'); > if (is_numeric($alpha)) { > $result['alpha'] = ChartColor::alphaFromXml($alpha); > } > } > if (isset($colorXml->$type->lumMod)) { > /** @var string */ > $brightness = self::getAttribute($colorXml->$type->lumMod, 'val', 'string'); > if (is_numeric($brightness)) { > $result['brightness'] = ChartColor::alphaFromXml($brightness); > } > } > > break; > } > } > > return $result; > } > > private function readLineStyle(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject): void > { > if (!isset($chartObject, $chartDetail->spPr)) { > return; > } > $sppr = $chartDetail->spPr->children($this->aNamespace); > > if (!isset($sppr->ln)) { > return; > } > $lineWidth = null; > /** @var string */ > $lineWidthTemp = self::getAttribute($sppr->ln, 'w', 'string'); > if (is_numeric($lineWidthTemp)) { > $lineWidth = ChartProperties::xmlToPoints($lineWidthTemp); > } > /** @var string */ > $compoundType = self::getAttribute($sppr->ln, 'cmpd', 'string'); > /** @var string */ > $dashType = self::getAttribute($sppr->ln->prstDash, 'val', 'string'); > /** @var string */ > $capType = self::getAttribute($sppr->ln, 'cap', 'string'); > if (isset($sppr->ln->miter)) { > $joinType = ChartProperties::LINE_STYLE_JOIN_MITER; > } elseif (isset($sppr->ln->bevel)) { > $joinType = ChartProperties::LINE_STYLE_JOIN_BEVEL; > } else { > $joinType = ''; > } > $headArrowSize = ''; > $endArrowSize = ''; > /** @var string */ > $headArrowType = self::getAttribute($sppr->ln->headEnd, 'type', 'string'); > /** @var string */ > $headArrowWidth = self::getAttribute($sppr->ln->headEnd, 'w', 'string'); > /** @var string */ > $headArrowLength = self::getAttribute($sppr->ln->headEnd, 'len', 'string'); > /** @var string */ > $endArrowType = self::getAttribute($sppr->ln->tailEnd, 'type', 'string'); > /** @var string */ > $endArrowWidth = self::getAttribute($sppr->ln->tailEnd, 'w', 'string'); > /** @var string */ > $endArrowLength = self::getAttribute($sppr->ln->tailEnd, 'len', 'string'); > $chartObject->setLineStyleProperties( > $lineWidth, > $compoundType, > $dashType, > $capType, > $joinType, > $headArrowType, > $headArrowSize, > $endArrowType, > $endArrowSize, > $headArrowWidth, > $headArrowLength, > $endArrowWidth, > $endArrowLength > ); > $colorArray = $this->readColor($sppr->ln->solidFill); > $chartObject->getLineColor()->setColorPropertiesArray($colorArray); > } > > private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAxis): void > { > if (!isset($whichAxis)) { > return; > } > if (isset($chartDetail->delete)) { > $whichAxis->setAxisOption('hidden', (string) self::getAttribute($chartDetail->delete, 'val', 'string')); > } > if (isset($chartDetail->numFmt)) { > $whichAxis->setAxisNumberProperties( > (string) self::getAttribute($chartDetail->numFmt, 'formatCode', 'string'), > null, > (int) self::getAttribute($chartDetail->numFmt, 'sourceLinked', 'int') > ); > } > if (isset($chartDetail->crossBetween)) { > $whichAxis->setCrossBetween((string) self::getAttribute($chartDetail->crossBetween, 'val', 'string')); > } > if (isset($chartDetail->majorTickMark)) { > $whichAxis->setAxisOption('major_tick_mark', (string) self::getAttribute($chartDetail->majorTickMark, 'val', 'string')); > } > if (isset($chartDetail->minorTickMark)) { > $whichAxis->setAxisOption('minor_tick_mark', (string) self::getAttribute($chartDetail->minorTickMark, 'val', 'string')); > } > if (isset($chartDetail->tickLblPos)) { > $whichAxis->setAxisOption('axis_labels', (string) self::getAttribute($chartDetail->tickLblPos, 'val', 'string')); > } > if (isset($chartDetail->crosses)) { > $whichAxis->setAxisOption('horizontal_crosses', (string) self::getAttribute($chartDetail->crosses, 'val', 'string')); > } > if (isset($chartDetail->crossesAt)) { > $whichAxis->setAxisOption('horizontal_crosses_value', (string) self::getAttribute($chartDetail->crossesAt, 'val', 'string')); > } > if (isset($chartDetail->scaling->orientation)) { > $whichAxis->setAxisOption('orientation', (string) self::getAttribute($chartDetail->scaling->orientation, 'val', 'string')); > } > if (isset($chartDetail->scaling->max)) { > $whichAxis->setAxisOption('maximum', (string) self::getAttribute($chartDetail->scaling->max, 'val', 'string')); > } > if (isset($chartDetail->scaling->min)) { > $whichAxis->setAxisOption('minimum', (string) self::getAttribute($chartDetail->scaling->min, 'val', 'string')); > } > if (isset($chartDetail->scaling->min)) { > $whichAxis->setAxisOption('minimum', (string) self::getAttribute($chartDetail->scaling->min, 'val', 'string')); > } > if (isset($chartDetail->majorUnit)) { > $whichAxis->setAxisOption('major_unit', (string) self::getAttribute($chartDetail->majorUnit, 'val', 'string')); > } > if (isset($chartDetail->minorUnit)) { > $whichAxis->setAxisOption('minor_unit', (string) self::getAttribute($chartDetail->minorUnit, 'val', 'string')); > } > if (isset($chartDetail->baseTimeUnit)) { > $whichAxis->setAxisOption('baseTimeUnit', (string) self::getAttribute($chartDetail->baseTimeUnit, 'val', 'string')); > } > if (isset($chartDetail->majorTimeUnit)) { > $whichAxis->setAxisOption('majorTimeUnit', (string) self::getAttribute($chartDetail->majorTimeUnit, 'val', 'string')); > } > if (isset($chartDetail->minorTimeUnit)) { > $whichAxis->setAxisOption('minorTimeUnit', (string) self::getAttribute($chartDetail->minorTimeUnit, 'val', 'string')); > } > if (isset($chartDetail->txPr)) { > $children = $chartDetail->txPr->children($this->aNamespace); > $addAxisText = false; > $axisText = new AxisText(); > if (isset($children->bodyPr)) { > /** @var string */ > $textRotation = self::getAttribute($children->bodyPr, 'rot', 'string'); > if (is_numeric($textRotation)) { > $axisText->setRotation((int) ChartProperties::xmlToAngle($textRotation)); > $addAxisText = true; > } > } > if (isset($children->p->pPr->defRPr)) { > $font = $this->parseFont($children->p); > if ($font !== null) { > $axisText->setFont($font); > $addAxisText = true; > } > } > if (isset($children->p->pPr->defRPr->effectLst)) { > $this->readEffects($children->p->pPr->defRPr, $axisText, false); > $addAxisText = true; > } > if ($addAxisText) { > $whichAxis->setAxisText($axisText);