Charts Additional Support for Layout and DataSeriesValues (#2922)

* Charts Additional Support for Layout and DataSeriesValues

The dLbls tag in more or less the Xml equivalent of the Layout class. It is currently read and written only for the Chart as a whole. It can, however, also be applied to DataSeriesValues. Further it has properties which are currently ignored, namely label fill, border, and font colors. All of these omissions are handled by this PR. There are other properties which can be applied to the labels, but, for now, only the 3 colors are added.

DataSeriesValues can have effects (like glow). Since DSV now descends from Properties, these are already supported, but support needs to be added to the Reader and Writer to handle them. This PR adds the support.

* Add Unit Tests

Based on new samples.

* Minor Improvements

Slight increase to coverage.
This commit is contained in:
oleibman 2022-07-04 08:43:54 -07:00 committed by GitHub
parent faf6d819c6
commit c22c6df5b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 493 additions and 331 deletions

View File

@ -49,7 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Time interval formatting [Issue #2768](https://github.com/PHPOffice/PhpSpreadsheet/issues/2768) [PR #2772](https://github.com/PHPOffice/PhpSpreadsheet/pull/2772)
- Copy from Xls(x) to Html/Pdf loses drawings [PR #2788](https://github.com/PHPOffice/PhpSpreadsheet/pull/2788)
- Html Reader converting cell containing 0 to null string [Issue #2810](https://github.com/PHPOffice/PhpSpreadsheet/issues/2810) [PR #2813](https://github.com/PHPOffice/PhpSpreadsheet/pull/2813)
- Many fixes for Charts, especially, but not limited to, Scatter, Bubble, and Surface charts. [Issue #2762](https://github.com/PHPOffice/PhpSpreadsheet/issues/2762) [Issue #2299](https://github.com/PHPOffice/PhpSpreadsheet/issues/2299) [Issue #2700](https://github.com/PHPOffice/PhpSpreadsheet/issues/2700) [Issue #2817](https://github.com/PHPOffice/PhpSpreadsheet/issues/2817) [Issue #2763](https://github.com/PHPOffice/PhpSpreadsheet/issues/2763) [Issue #2219](https://github.com/PHPOffice/PhpSpreadsheet/issues/2219) [Issue #2863](https://github.com/PHPOffice/PhpSpreadsheet/issues/2863) [PR #2828](https://github.com/PHPOffice/PhpSpreadsheet/pull/2828) [PR #2841](https://github.com/PHPOffice/PhpSpreadsheet/pull/2841) [PR #2846](https://github.com/PHPOffice/PhpSpreadsheet/pull/2846) [PR #2852](https://github.com/PHPOffice/PhpSpreadsheet/pull/2852) [PR #2856](https://github.com/PHPOffice/PhpSpreadsheet/pull/2856) [PR #2865](https://github.com/PHPOffice/PhpSpreadsheet/pull/2865) [PR #2872](https://github.com/PHPOffice/PhpSpreadsheet/pull/2872) [PR #2879](https://github.com/PHPOffice/PhpSpreadsheet/pull/2879) [PR #2898](https://github.com/PHPOffice/PhpSpreadsheet/pull/2898) [PR #2906](https://github.com/PHPOffice/PhpSpreadsheet/pull/2906)
- Many fixes for Charts, especially, but not limited to, Scatter, Bubble, and Surface charts. [Issue #2762](https://github.com/PHPOffice/PhpSpreadsheet/issues/2762) [Issue #2299](https://github.com/PHPOffice/PhpSpreadsheet/issues/2299) [Issue #2700](https://github.com/PHPOffice/PhpSpreadsheet/issues/2700) [Issue #2817](https://github.com/PHPOffice/PhpSpreadsheet/issues/2817) [Issue #2763](https://github.com/PHPOffice/PhpSpreadsheet/issues/2763) [Issue #2219](https://github.com/PHPOffice/PhpSpreadsheet/issues/2219) [Issue #2863](https://github.com/PHPOffice/PhpSpreadsheet/issues/2863) [PR #2828](https://github.com/PHPOffice/PhpSpreadsheet/pull/2828) [PR #2841](https://github.com/PHPOffice/PhpSpreadsheet/pull/2841) [PR #2846](https://github.com/PHPOffice/PhpSpreadsheet/pull/2846) [PR #2852](https://github.com/PHPOffice/PhpSpreadsheet/pull/2852) [PR #2856](https://github.com/PHPOffice/PhpSpreadsheet/pull/2856) [PR #2865](https://github.com/PHPOffice/PhpSpreadsheet/pull/2865) [PR #2872](https://github.com/PHPOffice/PhpSpreadsheet/pull/2872) [PR #2879](https://github.com/PHPOffice/PhpSpreadsheet/pull/2879) [PR #2898](https://github.com/PHPOffice/PhpSpreadsheet/pull/2898) [PR #2906](https://github.com/PHPOffice/PhpSpreadsheet/pull/2906) [PR #2922](https://github.com/PHPOffice/PhpSpreadsheet/pull/2922)
- Calculating Engine regexp for Column/Row references when there are multiple quoted worksheet references in the formula [Issue #2874](https://github.com/PHPOffice/PhpSpreadsheet/issues/2874) [PR #2899](https://github.com/PHPOffice/PhpSpreadsheet/pull/2899)
## 1.23.0 - 2022-04-24

View File

@ -1185,46 +1185,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Chart/PlotArea.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has parameter \\$elements with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has parameter \\$properties with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has parameter \\$arrayKaySelector with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has parameter \\$arraySelector with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getShadowPresetsMap\\(\\) has no return type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getShadowPresetsMap\\(\\) has parameter \\$presetsOption with no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Chart/Properties.php
-
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\:\\:\\$layout \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\|null\\.$#"
count: 1
@ -4020,61 +3980,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx.php
-
message: "#^Parameter \\#1 \\$plotSeriesValues of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeBubbles\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\|null, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\|false given\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#1 \\$rawTextData of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\XMLWriter\\:\\:writeRawData\\(\\) expects array\\<string\\>\\|string\\|null, int given\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float given\\.$#"
count: 6
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float\\|int given\\.$#"
count: 4
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
count: 41
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#6 \\$yAxis of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\|null given\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#7 \\$xAxis of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\|null given\\.$#"
count: 2
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#8 \\$majorGridlines of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\|null given\\.$#"
count: 2
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#9 \\$minorGridlines of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\|null given\\.$#"
count: 2
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:\\$calculateCellValues has no type specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\PlotArea and null will always evaluate to false\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
-
message: "#^Parameter \\#1 \\$string of function substr expects string, int given\\.$#"
count: 1

View File

@ -89,7 +89,8 @@ $series = new DataSeries(
$series->setPlotBubbleSizes($dataSeriesBubbles);
// Set the series in the plot area
$plotArea = new PlotArea(null, [$series]);
$plotArea = new PlotArea();
$plotArea->setPlotSeries([$series]);
// Set the chart legend
$legend = new ChartLegend(ChartLegend::POSITION_RIGHT, null, false);

Binary file not shown.

Binary file not shown.

View File

@ -85,6 +85,9 @@ class DataSeriesValues extends Properties
/** @var bool */
private $bubble3D = false;
/** @var ?Layout */
private $labelLayout;
/**
* Create a new DataSeriesValues object.
*
@ -562,4 +565,16 @@ class DataSeriesValues extends Properties
return $this;
}
public function getLabelLayout(): ?Layout
{
return $this->labelLayout;
}
public function setLabelLayout(?Layout $labelLayout): self
{
$this->labelLayout = $labelLayout;
return $this;
}
}

View File

@ -57,7 +57,7 @@ class Layout
* show legend key
* Specifies that legend keys should be shown in data labels.
*
* @var bool
* @var ?bool
*/
private $showLegendKey;
@ -65,7 +65,7 @@ class Layout
* show value
* Specifies that the value should be shown in a data label.
*
* @var bool
* @var ?bool
*/
private $showVal;
@ -73,7 +73,7 @@ class Layout
* show category name
* Specifies that the category name should be shown in the data label.
*
* @var bool
* @var ?bool
*/
private $showCatName;
@ -81,7 +81,7 @@ class Layout
* show data series name
* Specifies that the series name should be shown in the data label.
*
* @var bool
* @var ?bool
*/
private $showSerName;
@ -89,14 +89,14 @@ class Layout
* show percentage
* Specifies that the percentage should be shown in the data label.
*
* @var bool
* @var ?bool
*/
private $showPercent;
/**
* show bubble size.
*
* @var bool
* @var ?bool
*/
private $showBubbleSize;
@ -104,10 +104,19 @@ class Layout
* show leader lines
* Specifies that leader lines should be shown for the data label.
*
* @var bool
* @var ?bool
*/
private $showLeaderLines;
/** @var ?ChartColor */
private $labelFillColor;
/** @var ?ChartColor */
private $labelBorderColor;
/** @var ?ChartColor */
private $labelFontColor;
/**
* Create a new Layout.
*/
@ -134,6 +143,30 @@ class Layout
if (isset($layout['h'])) {
$this->height = (float) $layout['h'];
}
$this->initBoolean($layout, 'showLegendKey');
$this->initBoolean($layout, 'showVal');
$this->initBoolean($layout, 'showCatName');
$this->initBoolean($layout, 'showSerName');
$this->initBoolean($layout, 'showPercent');
$this->initBoolean($layout, 'showBubbleSize');
$this->initBoolean($layout, 'showLeaderLines');
$this->initColor($layout, 'labelFillColor');
$this->initColor($layout, 'labelBorderColor');
$this->initColor($layout, 'labelFontColor');
}
private function initBoolean(array $layout, string $name): void
{
if (isset($layout[$name])) {
$this->$name = (bool) $layout[$name];
}
}
private function initColor(array $layout, string $name): void
{
if (isset($layout[$name]) && $layout[$name] instanceof ChartColor) {
$this->$name = $layout[$name];
}
}
/**
@ -304,12 +337,7 @@ class Layout
return $this;
}
/**
* Get show legend key.
*
* @return bool
*/
public function getShowLegendKey()
public function getShowLegendKey(): ?bool
{
return $this->showLegendKey;
}
@ -317,24 +345,15 @@ class Layout
/**
* Set show legend key
* Specifies that legend keys should be shown in data labels.
*
* @param bool $showLegendKey Show legend key
*
* @return $this
*/
public function setShowLegendKey($showLegendKey)
public function setShowLegendKey(?bool $showLegendKey): self
{
$this->showLegendKey = $showLegendKey;
return $this;
}
/**
* Get show value.
*
* @return bool
*/
public function getShowVal()
public function getShowVal(): ?bool
{
return $this->showVal;
}
@ -342,24 +361,15 @@ class Layout
/**
* Set show val
* Specifies that the value should be shown in data labels.
*
* @param bool $showDataLabelValues Show val
*
* @return $this
*/
public function setShowVal($showDataLabelValues)
public function setShowVal(?bool $showDataLabelValues): self
{
$this->showVal = $showDataLabelValues;
return $this;
}
/**
* Get show category name.
*
* @return bool
*/
public function getShowCatName()
public function getShowCatName(): ?bool
{
return $this->showCatName;
}
@ -367,115 +377,111 @@ class Layout
/**
* Set show cat name
* Specifies that the category name should be shown in data labels.
*
* @param bool $showCategoryName Show cat name
*
* @return $this
*/
public function setShowCatName($showCategoryName)
public function setShowCatName(?bool $showCategoryName): self
{
$this->showCatName = $showCategoryName;
return $this;
}
/**
* Get show data series name.
*
* @return bool
*/
public function getShowSerName()
public function getShowSerName(): ?bool
{
return $this->showSerName;
}
/**
* Set show ser name
* Set show data series name.
* Specifies that the series name should be shown in data labels.
*
* @param bool $showSeriesName Show series name
*
* @return $this
*/
public function setShowSerName($showSeriesName)
public function setShowSerName(?bool $showSeriesName): self
{
$this->showSerName = $showSeriesName;
return $this;
}
/**
* Get show percentage.
*
* @return bool
*/
public function getShowPercent()
public function getShowPercent(): ?bool
{
return $this->showPercent;
}
/**
* Set show percentage
* Set show percentage.
* Specifies that the percentage should be shown in data labels.
*
* @param bool $showPercentage Show percentage
*
* @return $this
*/
public function setShowPercent($showPercentage)
public function setShowPercent(?bool $showPercentage): self
{
$this->showPercent = $showPercentage;
return $this;
}
/**
* Get show bubble size.
*
* @return bool
*/
public function getShowBubbleSize()
public function getShowBubbleSize(): ?bool
{
return $this->showBubbleSize;
}
/**
* Set show bubble size
* Set show bubble size.
* Specifies that the bubble size should be shown in data labels.
*
* @param bool $showBubbleSize Show bubble size
*
* @return $this
*/
public function setShowBubbleSize($showBubbleSize)
public function setShowBubbleSize(?bool $showBubbleSize): self
{
$this->showBubbleSize = $showBubbleSize;
return $this;
}
/**
* Get show leader lines.
*
* @return bool
*/
public function getShowLeaderLines()
public function getShowLeaderLines(): ?bool
{
return $this->showLeaderLines;
}
/**
* Set show leader lines
* Set show leader lines.
* Specifies that leader lines should be shown in data labels.
*
* @param bool $showLeaderLines Show leader lines
*
* @return $this
*/
public function setShowLeaderLines($showLeaderLines)
public function setShowLeaderLines(?bool $showLeaderLines): self
{
$this->showLeaderLines = $showLeaderLines;
return $this;
}
public function getLabelFillColor(): ?ChartColor
{
return $this->labelFillColor;
}
public function setLabelFillColor(?ChartColor $chartColor): self
{
$this->labelFillColor = $chartColor;
return $this;
}
public function getLabelBorderColor(): ?ChartColor
{
return $this->labelBorderColor;
}
public function setLabelBorderColor(?ChartColor $chartColor): self
{
$this->labelBorderColor = $chartColor;
return $this;
}
public function getLabelFontColor(): ?ChartColor
{
return $this->labelFontColor;
}
public function setLabelFontColor(?ChartColor $chartColor): self
{
$this->labelFontColor = $chartColor;
return $this;
}
}

View File

@ -421,11 +421,19 @@ abstract class Properties
],
];
protected function getShadowPresetsMap($presetsOption)
protected function getShadowPresetsMap(int $presetsOption): array
{
return self::PRESETS_OPTIONS[$presetsOption] ?? self::PRESETS_OPTIONS[0];
}
/**
* Get value of array element.
*
* @param mixed $properties
* @param mixed $elements
*
* @return mixed
*/
protected function getArrayElementsValue($properties, $elements)
{
$reference = &$properties;
@ -718,6 +726,16 @@ abstract class Properties
return $this->getArrayElementsValue($this->shadowProperties, $elements);
}
public function getShadowArray(): array
{
$array = $this->shadowProperties;
if ($this->getShadowColorObject()->isUsable()) {
$array['color'] = $this->getShadowProperty('color');
}
return $array;
}
/** @var ChartColor */
protected $lineColor;
@ -748,6 +766,10 @@ abstract class Properties
{
$this->lineStyleProperties = $otherProperties->lineStyleProperties;
$this->lineColor = $otherProperties->lineColor;
$this->glowSize = $otherProperties->glowSize;
$this->glowColor = $otherProperties->glowColor;
$this->softEdges = $otherProperties->softEdges;
$this->shadowProperties = $otherProperties->shadowProperties;
}
public function getLineColor(): ChartColor
@ -875,6 +897,14 @@ abstract class Properties
9 => ['w' => 'lg', 'len' => 'lg'],
];
/**
* Get Line Style Arrow Size.
*
* @param int $arraySelector
* @param string $arrayKaySelector
*
* @return string
*/
protected function getLineStyleArrowSize($arraySelector, $arrayKaySelector)
{
return self::ARROW_SIZES[$arraySelector][$arrayKaySelector] ?? '';

View File

@ -389,6 +389,7 @@ class Chart
$markerFillColor = null;
$markerBorderColor = null;
$lineStyle = null;
$labelLayout = null;
foreach ($seriesDetails as $seriesKey => $seriesDetail) {
switch ($seriesKey) {
case 'idx':
@ -415,6 +416,12 @@ class Chart
$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));
}
@ -474,6 +481,21 @@ class Chart
$bubble3D = self::getAttribute($seriesDetail, 'val', 'boolean');
break;
case 'dLbls':
$labelLayout = new Layout($this->readChartAttributes($seriesDetails));
break;
}
}
if ($labelLayout) {
if (isset($seriesLabel[$seriesIndex])) {
$seriesLabel[$seriesIndex]->setLabelLayout($labelLayout);
}
if (isset($seriesCategory[$seriesIndex])) {
$seriesCategory[$seriesIndex]->setLabelLayout($labelLayout);
}
if (isset($seriesValues[$seriesIndex])) {
$seriesValues[$seriesIndex]->setLabelLayout($labelLayout);
}
}
if ($noFill) {
@ -947,6 +969,21 @@ class Chart
if (isset($chartDetail->dLbls->showLeaderLines)) {
$plotAttributes['showLeaderLines'] = self::getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string');
}
if (isset($chartDetail->dLbls->spPr)) {
$sppr = $chartDetail->dLbls->spPr->children($this->aNamespace);
if (isset($sppr->solidFill)) {
$plotAttributes['labelFillColor'] = new ChartColor($this->readColor($sppr->solidFill));
}
if (isset($sppr->ln->solidFill)) {
$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->pPr->defRPr->solidFill)) {
$plotAttributes['labelFontColor'] = new ChartColor($this->readColor($txpr->p->pPr->defRPr->solidFill));
}
}
}
return $plotAttributes;
@ -991,10 +1028,7 @@ class Chart
}
}
/**
* @param null|Axis|GridLines $chartObject may be extended to include other types
*/
private function readEffects(SimpleXMLElement $chartDetail, $chartObject): void
private function readEffects(SimpleXMLElement $chartDetail, ?Properties $chartObject): void
{
if (!isset($chartObject, $chartDetail->spPr)) {
return;

View File

@ -17,8 +17,6 @@ use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
class Chart extends WriterPart
{
protected $calculateCellValues;
/**
* @var int
*/
@ -33,8 +31,6 @@ class Chart extends WriterPart
*/
public function writeChart(\PhpOffice\PhpSpreadsheet\Chart\Chart $chart, $calculateCellValues = true)
{
$this->calculateCellValues = $calculateCellValues;
// Create XML writer
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
@ -43,7 +39,7 @@ class Chart extends WriterPart
$objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
}
// Ensure that data series values are up-to-date before we save
if ($this->calculateCellValues) {
if ($calculateCellValues) {
$chart->refresh();
}
@ -57,13 +53,13 @@ class Chart extends WriterPart
$objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
$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', '0');
$objWriter->endElement();
$this->writeAlternateContent($objWriter);
@ -73,7 +69,7 @@ class Chart extends WriterPart
$this->writeTitle($objWriter, $chart->getTitle());
$objWriter->startElement('c:autoTitleDeleted');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
$objWriter->startElement('c:view3D');
@ -108,7 +104,7 @@ class Chart extends WriterPart
$this->writeLegend($objWriter, $chart->getLegend());
$objWriter->startElement('c:plotVisOnly');
$objWriter->writeAttribute('val', (int) $chart->getPlotVisibleOnly());
$objWriter->writeAttribute('val', (string) (int) $chart->getPlotVisibleOnly());
$objWriter->endElement();
$objWriter->startElement('c:dispBlanksAs');
@ -116,7 +112,7 @@ class Chart extends WriterPart
$objWriter->endElement();
$objWriter->startElement('c:showDLblsOverMax');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
$objWriter->endElement();
@ -167,7 +163,7 @@ class Chart extends WriterPart
$this->writeLayout($objWriter, $title->getLayout());
$objWriter->startElement('c:overlay');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
$objWriter->endElement();
@ -203,7 +199,7 @@ class Chart extends WriterPart
$objWriter->startElement('a:p');
$objWriter->startElement('a:pPr');
$objWriter->writeAttribute('rtl', 0);
$objWriter->writeAttribute('rtl', '0');
$objWriter->startElement('a:defRPr');
$objWriter->endElement();
@ -222,7 +218,7 @@ class Chart extends WriterPart
/**
* Write Chart Plot Area.
*/
private function writePlotArea(XMLWriter $objWriter, PlotArea $plotArea, ?Title $xAxisLabel = null, ?Title $yAxisLabel = null, ?Axis $xAxis = null, ?Axis $yAxis = null, ?GridLines $majorGridlines = null, ?GridLines $minorGridlines = null): void
private function writePlotArea(XMLWriter $objWriter, ?PlotArea $plotArea, ?Title $xAxisLabel = null, ?Title $yAxisLabel = null, ?Axis $xAxis = null, ?Axis $yAxis = null, ?GridLines $majorGridlines = null, ?GridLines $minorGridlines = null): void
{
if ($plotArea === null) {
return;
@ -273,16 +269,16 @@ class Chart extends WriterPart
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) {
@ -294,7 +290,7 @@ class Chart extends WriterPart
}
$objWriter->startElement('c:showNegBubbles');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
} elseif ($chartType === DataSeries::TYPE_STOCKCHART) {
$objWriter->startElement('c:hiLowLines');
@ -303,7 +299,7 @@ class Chart extends WriterPart
$objWriter->startElement('c:upDownBars');
$objWriter->startElement('c:gapWidth');
$objWriter->writeAttribute('val', 300);
$objWriter->writeAttribute('val', '300');
$objWriter->endElement();
$objWriter->startElement('c:upBars');
@ -334,12 +330,12 @@ class Chart extends WriterPart
}
} else {
$objWriter->startElement('c:firstSliceAng');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
if ($chartType === DataSeries::TYPE_DONUTCHART) {
$objWriter->startElement('c:holeSize');
$objWriter->writeAttribute('val', 50);
$objWriter->writeAttribute('val', '50');
$objWriter->endElement();
}
}
@ -349,12 +345,12 @@ class Chart extends WriterPart
if (($chartType !== DataSeries::TYPE_PIECHART) && ($chartType !== DataSeries::TYPE_PIECHART_3D) && ($chartType !== DataSeries::TYPE_DONUTCHART)) {
if ($chartType === DataSeries::TYPE_BUBBLECHART) {
$this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id2, $id1, $catIsMultiLevelSeries, $xAxis, $majorGridlines, $minorGridlines);
$this->writeValueAxis($objWriter, $xAxisLabel, $chartType, $id2, $id1, $catIsMultiLevelSeries, $xAxis ?? new Axis(), $majorGridlines, $minorGridlines);
} else {
$this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $xAxis);
$this->writeCategoryAxis($objWriter, $xAxisLabel, $id1, $id2, $catIsMultiLevelSeries, $xAxis ?? new Axis());
}
$this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $yAxis, $majorGridlines, $minorGridlines);
$this->writeValueAxis($objWriter, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $yAxis ?? new Axis(), $majorGridlines, $minorGridlines);
if ($chartType === DataSeries::TYPE_SURFACECHART_3D || $chartType === DataSeries::TYPE_SURFACECHART) {
$this->writeSerAxis($objWriter, $id2, $id3);
}
@ -363,49 +359,75 @@ class Chart extends WriterPart
$objWriter->endElement();
}
private function writeDataLabelsBool(XMLWriter $objWriter, string $name, ?bool $value): void
{
if ($value !== null) {
$objWriter->startElement("c:$name");
$objWriter->writeAttribute('val', $value ? '1' : '0');
$objWriter->endElement();
}
}
/**
* Write Data Labels.
*/
private function writeDataLabels(XMLWriter $objWriter, ?Layout $chartLayout = null): void
{
if (!isset($chartLayout)) {
return;
}
$objWriter->startElement('c:dLbls');
$objWriter->startElement('c:showLegendKey');
$showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey();
$objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 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:showVal');
$showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal();
$objWriter->writeAttribute('val', ((empty($showVal)) ? 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:showCatName');
$showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName();
$objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1));
$objWriter->endElement();
$objWriter->startElement('a:lstStyle');
$objWriter->endElement(); // a:lstStyle
$objWriter->startElement('c:showSerName');
$showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName();
$objWriter->writeAttribute('val', ((empty($showSerName)) ? 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:showPercent');
$showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent();
$objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1));
$objWriter->endElement();
$objWriter->endElement(); // c:txPr
}
$objWriter->startElement('c:showBubbleSize');
$showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize();
$objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1));
$objWriter->endElement();
$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->startElement('c:showLeaderLines');
$showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines();
$objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1));
$objWriter->endElement();
$objWriter->endElement();
$objWriter->endElement(); // c:dLbls
}
/**
@ -452,7 +474,7 @@ class Chart extends WriterPart
$objWriter->endElement(); // c:scaling
$objWriter->startElement('c:delete');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
$objWriter->startElement('c:axPos');
@ -486,7 +508,7 @@ class Chart extends WriterPart
$this->writeLayout($objWriter, $layout);
$objWriter->startElement('c:overlay');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
$objWriter->endElement();
@ -517,12 +539,7 @@ class Chart extends WriterPart
$objWriter->startElement('c:spPr');
$this->writeColor($objWriter, $yAxis->getFillColorObject());
$objWriter->startElement('a:effectLst');
$this->writeGlow($objWriter, $yAxis);
$this->writeShadow($objWriter, $yAxis);
$this->writeSoftEdge($objWriter, $yAxis);
$objWriter->endElement(); // effectLst
$this->writeEffects($objWriter, $yAxis);
$objWriter->endElement(); // spPr
if ($yAxis->getAxisOptionsProperty('major_unit') !== null) {
@ -550,7 +567,7 @@ class Chart extends WriterPart
}
$objWriter->startElement('c:auto');
$objWriter->writeAttribute('val', 1);
$objWriter->writeAttribute('val', '1');
$objWriter->endElement();
$objWriter->startElement('c:lblAlgn');
@ -558,12 +575,12 @@ class Chart extends WriterPart
$objWriter->endElement();
$objWriter->startElement('c:lblOffset');
$objWriter->writeAttribute('val', 100);
$objWriter->writeAttribute('val', '100');
$objWriter->endElement();
if ($isMultiLevelSeries) {
$objWriter->startElement('c:noMultiLvlLbl');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
}
$objWriter->endElement();
@ -577,7 +594,7 @@ class Chart extends WriterPart
* @param string $id2
* @param bool $isMultiLevelSeries
*/
private function writeValueAxis(XMLWriter $objWriter, ?Title $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis, GridLines $majorGridlines, GridLines $minorGridlines): void
private function writeValueAxis(XMLWriter $objWriter, ?Title $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, Axis $xAxis, ?GridLines $majorGridlines, ?GridLines $minorGridlines): void
{
$objWriter->startElement('c:valAx');
@ -610,39 +627,27 @@ class Chart extends WriterPart
$objWriter->endElement(); // c:scaling
$objWriter->startElement('c:delete');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
$objWriter->startElement('c:axPos');
$objWriter->writeAttribute('val', 'l');
$objWriter->endElement();
$objWriter->startElement('c:majorGridlines');
$objWriter->startElement('c:spPr');
if ($majorGridlines !== null) {
$objWriter->startElement('c:majorGridlines');
$objWriter->startElement('c:spPr');
$this->writeLineStyles($objWriter, $majorGridlines);
$this->writeEffects($objWriter, $majorGridlines);
$objWriter->endElement(); //end spPr
$objWriter->endElement(); //end majorGridLines
}
$this->writeLineStyles($objWriter, $majorGridlines);
$objWriter->startElement('a:effectLst');
$this->writeGlow($objWriter, $majorGridlines);
$this->writeShadow($objWriter, $majorGridlines);
$this->writeSoftEdge($objWriter, $majorGridlines);
$objWriter->endElement(); //end effectLst
$objWriter->endElement(); //end spPr
$objWriter->endElement(); //end majorGridLines
if ($minorGridlines->getObjectState()) {
if ($minorGridlines !== null && $minorGridlines->getObjectState()) {
$objWriter->startElement('c:minorGridlines');
$objWriter->startElement('c:spPr');
$this->writeLineStyles($objWriter, $minorGridlines);
$objWriter->startElement('a:effectLst');
$this->writeGlow($objWriter, $minorGridlines);
$this->writeShadow($objWriter, $minorGridlines);
$this->writeSoftEdge($objWriter, $minorGridlines);
$objWriter->endElement(); //end effectLst
$this->writeEffects($objWriter, $minorGridlines);
$objWriter->endElement(); //end spPr
$objWriter->endElement(); //end minorGridLines
}
@ -676,7 +681,7 @@ class Chart extends WriterPart
}
$objWriter->startElement('c:overlay');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
$objWriter->endElement();
@ -706,17 +711,9 @@ class Chart extends WriterPart
}
$objWriter->startElement('c:spPr');
$this->writeColor($objWriter, $xAxis->getFillColorObject());
$this->writeLineStyles($objWriter, $xAxis);
$objWriter->startElement('a:effectLst');
$this->writeGlow($objWriter, $xAxis);
$this->writeShadow($objWriter, $xAxis);
$this->writeSoftEdge($objWriter, $xAxis);
$objWriter->endElement(); //effectList
$this->writeEffects($objWriter, $xAxis);
$objWriter->endElement(); //end spPr
if ($id1 !== '0') {
@ -760,7 +757,7 @@ class Chart extends WriterPart
if ($isMultiLevelSeries) {
if ($groupType !== DataSeries::TYPE_BUBBLECHART) {
$objWriter->startElement('c:noMultiLvlLbl');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement();
}
}
@ -852,11 +849,11 @@ class Chart extends WriterPart
$objWriter->startElement('c:dPt');
$objWriter->startElement('c:idx');
$objWriter->writeAttribute('val', $val);
$objWriter->writeAttribute('val', "$val");
$objWriter->endElement(); // c:idx
$objWriter->startElement('c:bubble3D');
$objWriter->writeAttribute('val', 0);
$objWriter->writeAttribute('val', '0');
$objWriter->endElement(); // c:bubble3D
$objWriter->startElement('c:spPr');
@ -901,11 +898,11 @@ class Chart extends WriterPart
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();
}
}
@ -916,11 +913,11 @@ class Chart extends WriterPart
$objWriter->startElement('c:ser');
$objWriter->startElement('c:idx');
$objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesIdx);
$objWriter->writeAttribute('val', (string) ($this->seriesIndex + $plotSeriesIdx));
$objWriter->endElement();
$objWriter->startElement('c:order');
$objWriter->writeAttribute('val', $this->seriesIndex + $plotSeriesRef);
$objWriter->writeAttribute('val', (string) ($this->seriesIndex + $plotSeriesRef));
$objWriter->endElement();
$plotLabel = $plotGroup->getPlotLabelByIndex($plotSeriesIdx);
@ -949,6 +946,9 @@ class Chart extends WriterPart
}
}
}
if ($plotSeriesValues !== false && $plotSeriesValues->getLabelLayout()) {
$this->writeDataLabels($objWriter, $plotSeriesValues->getLabelLayout());
}
// Labels
$plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesIdx);
@ -980,6 +980,7 @@ class Chart extends WriterPart
$nofill = $groupType == DataSeries::TYPE_STOCKCHART || ($groupType === DataSeries::TYPE_SCATTERCHART && !$plotSeriesValues->getScatterLines());
if ($callLineStyles) {
$this->writeLineStyles($objWriter, $plotSeriesValues, $nofill);
$this->writeEffects($objWriter, $plotSeriesValues);
}
$objWriter->endElement(); // c:spPr
}
@ -1018,7 +1019,7 @@ class Chart extends WriterPart
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();
}
@ -1032,7 +1033,7 @@ class Chart extends WriterPart
$plotStyle = $plotGroup->getPlotStyle();
if ($plotStyle) {
$objWriter->startElement('c:explosion');
$objWriter->writeAttribute('val', 25);
$objWriter->writeAttribute('val', '25');
$objWriter->endElement();
}
}
@ -1089,7 +1090,7 @@ class Chart extends WriterPart
$objWriter->writeAttribute('val', $plotSeriesValues->getBubble3D() ? '1' : '0');
$objWriter->endElement();
}
} else {
} elseif ($plotSeriesValues !== false) {
$this->writeBubbles($plotSeriesValues, $objWriter);
}
}
@ -1115,7 +1116,7 @@ class Chart extends WriterPart
$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) {
@ -1154,7 +1155,7 @@ class Chart extends WriterPart
$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) {
@ -1200,7 +1201,7 @@ class Chart extends WriterPart
}
$objWriter->startElement('c:ptCount');
$objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
$objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointCount());
$objWriter->endElement();
$dataValues = $plotSeriesValues->getDataValues();
@ -1250,7 +1251,7 @@ class Chart extends WriterPart
$objWriter->endElement();
$objWriter->startElement('c:ptCount');
$objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());
$objWriter->writeAttribute('val', (string) $plotSeriesValues->getPointCount());
$objWriter->endElement();
$dataValues = $plotSeriesValues->getDataValues();
@ -1260,7 +1261,7 @@ class Chart extends WriterPart
$objWriter->startElement('c:pt');
$objWriter->writeAttribute('idx', $plotSeriesKey);
$objWriter->startElement('c:v');
$objWriter->writeRawData(1);
$objWriter->writeRawData('1');
$objWriter->endElement();
$objWriter->endElement();
}
@ -1309,28 +1310,28 @@ class Chart extends WriterPart
$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();
}
@ -1377,12 +1378,12 @@ class Chart extends WriterPart
$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');
@ -1392,12 +1393,22 @@ class Chart extends WriterPart
$objWriter->endElement();
}
/**
* Write shadow properties.
*
* @param Axis|GridLines $xAxis
*/
private function writeShadow(XMLWriter $objWriter, $xAxis): void
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;
@ -1441,12 +1452,7 @@ class Chart extends WriterPart
$objWriter->endElement();
}
/**
* Write glow properties.
*
* @param Axis|GridLines $yAxis
*/
private function writeGlow(XMLWriter $objWriter, $yAxis): void
private function writeGlow(XMLWriter $objWriter, Properties $yAxis): void
{
$size = $yAxis->getGlowProperty('size');
if (empty($size)) {
@ -1458,12 +1464,7 @@ class Chart extends WriterPart
$objWriter->endElement(); // glow
}
/**
* Write soft edge properties.
*
* @param Axis|GridLines $yAxis
*/
private function writeSoftEdge(XMLWriter $objWriter, $yAxis): void
private function writeSoftEdge(XMLWriter $objWriter, Properties $yAxis): void
{
$softEdgeSize = $yAxis->getSoftEdgesSize();
if (empty($softEdgeSize)) {

View File

@ -0,0 +1,58 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class Charts32DsvGlowTest extends AbstractFunctional
{
private const DIRECTORY = 'samples' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
public function readCharts(XlsxReader $reader): void
{
$reader->setIncludeCharts(true);
}
public function writeCharts(XlsxWriter $writer): void
{
$writer->setIncludeCharts(true);
}
public function testLine4(): void
{
$file = self::DIRECTORY . '32readwriteLineChart4.xlsx';
$reader = new XlsxReader();
$reader->setIncludeCharts(true);
$spreadsheet = $reader->load($file);
$sheet = $spreadsheet->getActiveSheet();
self::assertSame(1, $sheet->getChartCount());
/** @var callable */
$callableReader = [$this, 'readCharts'];
/** @var callable */
$callableWriter = [$this, 'writeCharts'];
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
$spreadsheet->disconnectWorksheets();
$sheet = $reloadedSpreadsheet->getActiveSheet();
$charts = $sheet->getChartCollection();
self::assertCount(1, $charts);
$chart = $charts[0];
self::assertNotNull($chart);
$plotArea = $chart->getPlotArea();
$dataSeriesArray = $plotArea->getPlotGroup();
self::assertCount(1, $dataSeriesArray);
$dataSeries = $dataSeriesArray[0];
$dataSeriesValuesArray = $dataSeries->getPlotValues();
self::assertCount(3, $dataSeriesValuesArray);
$dataSeriesValues = $dataSeriesValuesArray[1];
self::assertEquals(5, $dataSeriesValues->getGlowSize());
self::assertSame('schemeClr', $dataSeriesValues->getGlowProperty(['color', 'type']));
self::assertSame('accent2', $dataSeriesValues->getGlowProperty(['color', 'value']));
self::assertSame(60, $dataSeriesValues->getGlowProperty(['color', 'alpha']));
$reloadedSpreadsheet->disconnectWorksheets();
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class Charts32DsvLabelsTest extends AbstractFunctional
{
private const DIRECTORY = 'samples' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
public function readCharts(XlsxReader $reader): void
{
$reader->setIncludeCharts(true);
}
public function writeCharts(XlsxWriter $writer): void
{
$writer->setIncludeCharts(true);
}
public function testBar4(): void
{
$file = self::DIRECTORY . '32readwriteBarChart4.xlsx';
$reader = new XlsxReader();
$reader->setIncludeCharts(true);
$spreadsheet = $reader->load($file);
$sheet = $spreadsheet->getActiveSheet();
self::assertSame(1, $sheet->getChartCount());
/** @var callable */
$callableReader = [$this, 'readCharts'];
/** @var callable */
$callableWriter = [$this, 'writeCharts'];
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx', $callableReader, $callableWriter);
$spreadsheet->disconnectWorksheets();
$sheet = $reloadedSpreadsheet->getActiveSheet();
$charts = $sheet->getChartCollection();
self::assertCount(1, $charts);
$chart = $charts[0];
self::assertNotNull($chart);
$plotArea = $chart->getPlotArea();
$dataSeriesArray = $plotArea->getPlotGroup();
self::assertCount(1, $dataSeriesArray);
$dataSeries = $dataSeriesArray[0];
$dataSeriesValuesArray = $dataSeries->getPlotValues();
self::assertCount(1, $dataSeriesValuesArray);
$dataSeriesValues = $dataSeriesValuesArray[0];
$layout = $dataSeriesValues->getLabelLayout();
self::assertNotNull($layout);
self::assertTrue($layout->getShowVal());
$fillColor = $layout->getLabelFillColor();
self::assertNotNull($fillColor);
self::assertSame('schemeClr', $fillColor->getType());
self::assertSame('accent1', $fillColor->getValue());
$borderColor = $layout->getLabelBorderColor();
self::assertNotNull($borderColor);
self::assertSame('srgbClr', $borderColor->getType());
self::assertSame('FFC000', $borderColor->getValue());
$fontColor = $layout->getLabelFontColor();
self::assertNotNull($fontColor);
self::assertSame('srgbClr', $fontColor->getType());
self::assertSame('FFFF00', $fontColor->getValue());
self::assertEquals(
[15, 73, 61, 32],
$dataSeriesValues->getDataValues()
);
$reloadedSpreadsheet->disconnectWorksheets();
}
}

View File

@ -129,6 +129,11 @@ class GridlinesShadowGlowTest extends AbstractFunctional
foreach ($expectedShadow as $key => $value) {
self::assertEquals($value, $minorGridlines->getShadowProperty($key), $key);
}
$testShadow2 = $minorGridlines->getShadowArray();
self::assertNull($testShadow2['presets']);
self::assertEquals(['sx' => null, 'sy' => null, 'kx' => null, 'ky' => null], $testShadow2['size']);
unset($testShadow2['presets'], $testShadow2['size']);
self::assertEquals($expectedShadow, $testShadow2);
// Create the chart
$chart = new Chart(

View File

@ -2,6 +2,7 @@
namespace PhpOffice\PhpSpreadsheetTests\Chart;
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
use PhpOffice\PhpSpreadsheet\Chart\Layout;
use PHPUnit\Framework\TestCase;
@ -27,4 +28,37 @@ class LayoutTest extends TestCase
$result = $testInstance->getLayoutTarget();
self::assertEquals($LayoutTargetValue, $result);
}
public function testConstructorVsMethods(): void
{
$fillColor = new ChartColor('FF0000', 20, 'srgbClr');
$borderColor = new ChartColor('accent1', 20, 'schemeClr');
$fontColor = new ChartColor('red', 20, 'prstClr');
$array = [
'xMode' => 'factor',
'yMode' => 'edge',
'x' => 1.0,
'y' => 2.0,
'w' => 3.0,
'h' => 4.0,
'showVal' => true,
'labelFillColor' => $fillColor,
'labelBorderColor' => $borderColor,
'labelFontColor' => $fontColor,
];
$layout1 = new Layout($array);
$layout2 = new Layout();
$layout2
->setXMode('factor')
->setYMode('edge')
->setXposition(1.0)
->setYposition(2.0)
->setWidth(3.0)
->setHeight(4.0)
->setShowVal(true)
->setLabelFillColor($fillColor)
->setLabelBorderColor($borderColor)
->setLabelFontColor($fontColor);
self::assertEquals($layout1, $layout2);
}
}