Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Border for Charts #3462

Merged
merged 3 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samples/Chart/33_Chart_create_stock.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
$plotArea = new PlotArea(null, [$series]);
// Set the chart legend
$legend = new ChartLegend(ChartLegend::POSITION_RIGHT, null, false);
$legend->getBorderColor()->setColorProperties('ffc000');
$legend->getBorderLines()->setLineColorProperties('ffc000', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
$legend->getFillColor()->setColorProperties('cccccc');
$legendText = new AxisText();
$legendText->getFillColorObject()->setValue('008080')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
Expand Down
15 changes: 15 additions & 0 deletions src/PhpSpreadsheet/Chart/Axis.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ public function __construct()
Properties::FORMAT_CODE_DATE_ISO8601,
];

/** @var bool */
private $noFill = false;

/**
* Get Series Data Type.
*
Expand Down Expand Up @@ -318,4 +321,16 @@ public function setAxisText(?AxisText $axisText): self

return $this;
}

public function setNoFill(bool $noFill): self
{
$this->noFill = $noFill;

return $this;
}

public function getNoFill(): bool
{
return $this->noFill;
}
}
25 changes: 25 additions & 0 deletions src/PhpSpreadsheet/Chart/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ class Chart
/** @var bool */
private $roundedCorners = false;

/** @var GridLines */
private $borderLines;

/** @var ChartColor */
private $fillColor;

/**
* Create a new Chart.
* majorGridlines and minorGridlines are deprecated, moved to Axis.
Expand All @@ -176,6 +182,8 @@ public function __construct($name, ?Title $title = null, ?Legend $legend = null,
if ($minorGridlines !== null) {
$this->yAxis->setMinorGridlines($minorGridlines);
}
$this->fillColor = new ChartColor();
$this->borderLines = new GridLines();
}

/**
Expand Down Expand Up @@ -786,4 +794,21 @@ public function setRoundedCorners(?bool $roundedCorners): self

return $this;
}

public function getBorderLines(): GridLines
{
return $this->borderLines;
}

public function setBorderLines(GridLines $borderLines): self
{
$this->borderLines = $borderLines;

return $this;
}

public function getFillColor(): ChartColor
{
return $this->fillColor;
}
}
23 changes: 15 additions & 8 deletions src/PhpSpreadsheet/Chart/Legend.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class Legend
*/
private $layout;

/** @var ChartColor */
private $borderColor;
/** @var GridLines */
private $borderLines;

/** @var ChartColor */
private $fillColor;
Expand All @@ -69,15 +69,10 @@ public function __construct($position = self::POSITION_RIGHT, ?Layout $layout =
$this->setPosition($position);
$this->layout = $layout;
$this->setOverlay($overlay);
$this->borderColor = new ChartColor();
$this->borderLines = new GridLines();
$this->fillColor = new ChartColor();
}

public function getBorderColor(): ChartColor
{
return $this->borderColor;
}

public function getFillColor(): ChartColor
{
return $this->fillColor;
Expand Down Expand Up @@ -181,4 +176,16 @@ public function setLegendText(?AxisText $legendText): self

return $this;
}

public function getBorderLines(): GridLines
{
return $this->borderLines;
}

public function setBorderLines(GridLines $borderLines): self
{
$this->borderLines = $borderLines;

return $this;
}
}
36 changes: 29 additions & 7 deletions src/PhpSpreadsheet/Reader/Xlsx/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,25 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
$yAxis = new Axis();
$autoTitleDeleted = null;
$chartNoFill = false;
$chartBorderLines = null;
$chartFillColor = null;
$gradientArray = [];
$gradientLin = null;
$roundedCorners = false;
foreach ($chartElementsC as $chartElementKey => $chartElement) {
switch ($chartElementKey) {
case 'spPr':
$possibleNoFill = $chartElementsC->spPr->children($this->aNamespace);
if (isset($possibleNoFill->noFill)) {
$children = $chartElementsC->spPr->children($this->aNamespace);
if (isset($children->noFill)) {
$chartNoFill = true;
}
if (isset($children->solidFill)) {
$chartFillColor = $this->readColor($children->solidFill);
}
if (isset($children->ln)) {
$chartBorderLines = new GridLines();
$this->readLineStyle($chartElementsC, $chartBorderLines);
}

break;
case 'roundedCorners':
Expand Down Expand Up @@ -158,6 +167,9 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
$axisColorArray = $this->readColor($sppr->solidFill);
$xAxis->setFillParameters($axisColorArray['value'], $axisColorArray['alpha'], $axisColorArray['type']);
}
if (isset($chartDetail->spPr->ln->noFill)) {
$xAxis->setNoFill(true);
}
}
if (isset($chartDetail->majorGridlines)) {
$majorGridlines = new GridLines();
Expand Down Expand Up @@ -228,6 +240,9 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
$axisColorArray = $this->readColor($sppr->solidFill);
$whichAxis->setFillParameters($axisColorArray['value'], $axisColorArray['alpha'], $axisColorArray['type']);
}
if (isset($sppr->ln->noFill)) {
$whichAxis->setNoFill(true);
}
}
if ($whichAxis !== null && isset($chartDetail->majorGridlines)) {
$majorGridlines = new GridLines();
Expand Down Expand Up @@ -351,7 +366,7 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
$legendPos = 'r';
$legendLayout = null;
$legendOverlay = false;
$legendBorderColor = null;
$legendBorderLines = null;
$legendFillColor = null;
$legendText = null;
$addLegendText = false;
Expand All @@ -375,8 +390,9 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
if (isset($children->solidFill)) {
$legendFillColor = $this->readColor($children->solidFill);
}
if (isset($children->ln->solidFill)) {
$legendBorderColor = $this->readColor($children->ln->solidFill);
if (isset($children->ln)) {
$legendBorderLines = new GridLines();
$this->readLineStyle($chartDetails, $legendBorderLines);
}

break;
Expand All @@ -401,8 +417,8 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
if ($legendFillColor !== null) {
$legend->getFillColor()->setColorPropertiesArray($legendFillColor);
}
if ($legendBorderColor !== null) {
$legend->getBorderColor()->setColorPropertiesArray($legendBorderColor);
if ($legendBorderLines !== null) {
$legend->setBorderLines($legendBorderLines);
}
if ($addLegendText) {
$legend->setLegendText($legendText);
Expand All @@ -417,6 +433,12 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
if ($chartNoFill) {
$chart->setNoFill(true);
}
if ($chartFillColor !== null) {
$chart->getFillColor()->setColorPropertiesArray($chartFillColor);
}
if ($chartBorderLines !== null) {
$chart->setBorderLines($chartBorderLines);
}
$chart->setRoundedCorners($roundedCorners);
if (is_bool($autoTitleDeleted)) {
$chart->setAutoTitleDeleted($autoTitleDeleted);
Expand Down
35 changes: 19 additions & 16 deletions src/PhpSpreadsheet/Writer/Xlsx/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,20 @@ public function writeChart(\PhpOffice\PhpSpreadsheet\Chart\Chart $chart, $calcul
$objWriter->endElement();

$objWriter->endElement(); // c:chart

$objWriter->startElement('c:spPr');
if ($chart->getNoFill()) {
$objWriter->startElement('c:spPr');
$objWriter->startElement('a:noFill');
$objWriter->endElement(); // a:noFill
$objWriter->endElement(); // c:spPr
}
$fillColor = $chart->getFillColor();
if ($fillColor->isUsable()) {
$this->writeColor($objWriter, $fillColor);
}
$borderLines = $chart->getBorderLines();
$this->writeLineStyles($objWriter, $borderLines);
$this->writeEffects($objWriter, $borderLines);
$objWriter->endElement(); // c:spPr

$this->writePrintSettings($objWriter);

Expand Down Expand Up @@ -201,20 +209,15 @@ private function writeLegend(XMLWriter $objWriter, ?Legend $legend = null): void
$objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0');
$objWriter->endElement();

$objWriter->startElement('c:spPr');
$fillColor = $legend->getFillColor();
$borderColor = $legend->getBorderColor();
if ($fillColor->isUsable() || $borderColor->isUsable()) {
$objWriter->startElement('c:spPr');
if ($fillColor->isUsable()) {
$this->writeColor($objWriter, $fillColor);
}
if ($borderColor->isUsable()) {
$objWriter->startElement('a:ln');
$this->writeColor($objWriter, $borderColor);
$objWriter->endElement(); // a:ln
}
$objWriter->endElement(); // c:spPr
if ($fillColor->isUsable()) {
$this->writeColor($objWriter, $fillColor);
}
$borderLines = $legend->getBorderLines();
$this->writeLineStyles($objWriter, $borderLines);
$this->writeEffects($objWriter, $borderLines);
$objWriter->endElement(); // c:spPr

$legendText = $legend->getLegendText();
$objWriter->startElement('c:txPr');
Expand Down Expand Up @@ -654,7 +657,7 @@ private function writeCategoryAxis(XMLWriter $objWriter, ?Title $xAxisLabel, $id

$objWriter->startElement('c:spPr');
$this->writeColor($objWriter, $yAxis->getFillColorObject());
$this->writeLineStyles($objWriter, $yAxis);
$this->writeLineStyles($objWriter, $yAxis, $yAxis->getNoFill());
$this->writeEffects($objWriter, $yAxis);
$objWriter->endElement(); // spPr

Expand Down Expand Up @@ -880,7 +883,7 @@ private function writeValueAxis(XMLWriter $objWriter, ?Title $yAxisLabel, $group

$objWriter->startElement('c:spPr');
$this->writeColor($objWriter, $xAxis->getFillColorObject());
$this->writeLineStyles($objWriter, $xAxis);
$this->writeLineStyles($objWriter, $xAxis, $xAxis->getNoFill());
$this->writeEffects($objWriter, $xAxis);
$objWriter->endElement(); //end spPr

Expand Down
54 changes: 54 additions & 0 deletions tests/PhpSpreadsheetTests/Chart/ChartBorderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace PhpOffice\PhpSpreadsheetTests\Chart;

use PhpOffice\PhpSpreadsheet\Chart\Properties;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;

class ChartBorderTest 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 testChartBorder(): void
{
$file = self::DIRECTORY . '32readwriteLineChart5.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);
self::assertSame('ffffff', $chart->getFillColor()->getValue());
self::assertSame('srgbClr', $chart->getFillColor()->getType());
self::assertSame('d9d9d9', $chart->getBorderLines()->getLineColorProperty('value'));
self::assertSame('srgbClr', $chart->getBorderLines()->getLineColorProperty('type'));
self::assertEqualsWithDelta(9360 / Properties::POINTS_WIDTH_MULTIPLIER, $chart->getBorderLines()->getLineStyleProperty('width'), 1.0E-8);
self::assertTrue($chart->getChartAxisY()->getNoFill());
self::assertFalse($chart->getChartAxisX()->getNoFill());

$reloadedSpreadsheet->disconnectWorksheets();
}
}
4 changes: 2 additions & 2 deletions tests/PhpSpreadsheetTests/Chart/LegendColorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public function testLegend(): void
$plotArea = new PlotArea(null, [$series]);
// Set the chart legend
$legend = new ChartLegend(ChartLegend::POSITION_RIGHT, null, false);
$legend->getBorderColor()->setColorProperties('ffc000');
$legend->getBorderLines()->setLineColorProperties('ffc000', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
$legend->getFillColor()->setColorProperties('cccccc');
$legendText = new AxisText();
$legendText->getFillColorObject()->setValue('008080')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
Expand Down Expand Up @@ -146,7 +146,7 @@ public function testLegend(): void
if ($legend2 === null) {
self::fail('Unexpected null legend');
} else {
self::assertSame('ffc000', $legend2->getBorderColor()->getValue());
self::assertSame('ffc000', $legend2->getBorderLines()->getLineColorProperty('value'));
self::assertSame('cccccc', $legend2->getFillColor()->getValue());
$legendText2 = $legend2->getLegendText();
if ($legendText2 === null) {
Expand Down