Skip to content

Commit

Permalink
More Display Options for Chart Axis and Legend (#3434)
Browse files Browse the repository at this point in the history
* Allow Color and Effects on Data Points on Chart Axis

Fix #3414. There had been no way to do this. It is now supported via a new AxisText class, which derives from Properties, and has FillColor and effects (glow/shadow/softEdges) properties. The code changes in chart sample 33_Chart_create_scatter2 illustrate usage.

* Minor Performance Improvement

May also get rid of Scrutinizer complaint.

* Eliminate New Spacing Patch

No need for it.

* Add Legend Formatting to Change

Much in common with Data Point formatting.
  • Loading branch information
oleibman authored Mar 9, 2023
1 parent 64f32d8 commit 2034864
Show file tree
Hide file tree
Showing 9 changed files with 617 additions and 18 deletions.
13 changes: 10 additions & 3 deletions samples/Chart/33_Chart_create_scatter2.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use PhpOffice\PhpSpreadsheet\Chart\Axis as ChartAxis;
use PhpOffice\PhpSpreadsheet\Chart\AxisText;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
Expand Down Expand Up @@ -89,9 +90,9 @@
Properties::LINE_STYLE_CAP_SQUARE, // cap
Properties::LINE_STYLE_JOIN_MITER, // join
Properties::LINE_STYLE_ARROW_TYPE_OPEN, // head type
Properties::LINE_STYLE_ARROW_SIZE_4, // head size preset index
(string) Properties::LINE_STYLE_ARROW_SIZE_4, // head size preset index
Properties::LINE_STYLE_ARROW_TYPE_ARROW, // end type
Properties::LINE_STYLE_ARROW_SIZE_6 // end size preset index
(string) Properties::LINE_STYLE_ARROW_SIZE_6 // end size preset index
);

// series 2 - straight line - no special effects, connected, straight line
Expand Down Expand Up @@ -124,7 +125,10 @@
$xAxis = new ChartAxis();
//$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE );
$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE_ISO8601, true);
$xAxis->setAxisOption('textRotation', '45');
//$xAxis->setAxisOption('textRotation', '45');
$xAxisText = new AxisText();
$xAxisText->setRotation(45)->getFillColorObject()->setValue('00FF00')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
$xAxis->setAxisText($xAxisText);

$yAxis = new ChartAxis();
$yAxis->setLineStyleProperties(
Expand All @@ -135,6 +139,9 @@
Properties::LINE_STYLE_JOIN_BEVEL
);
$yAxis->setLineColorProperties('ffc000', null, ChartColor::EXCEL_COLOR_TYPE_RGB);
$yAxisText = new AxisText();
$yAxisText->setGlowProperties(20.0, 'accent1', 20, ChartColor::EXCEL_COLOR_TYPE_SCHEME);
$yAxis->setAxisText($yAxisText);

// Build the dataseries
$series = new DataSeries(
Expand Down
9 changes: 9 additions & 0 deletions samples/Chart/33_Chart_create_stock.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

use PhpOffice\PhpSpreadsheet\Chart\AxisText;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\ChartColor;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend;
Expand Down Expand Up @@ -80,6 +82,12 @@
$plotArea = new PlotArea(null, [$series]);
// Set the chart legend
$legend = new ChartLegend(ChartLegend::POSITION_RIGHT, null, false);
$legend->getBorderColor()->setColorProperties('ffc000');
$legend->getFillColor()->setColorProperties('cccccc');
$legendText = new AxisText();
$legendText->getFillColorObject()->setValue('008080')->setType(ChartColor::EXCEL_COLOR_TYPE_RGB);
$legendText->setShadowProperties(1);
$legend->setLegendText($legendText);

$title = new Title('Test Stock Chart');
$xAxisLabel = new Title('Counts');
Expand All @@ -103,6 +111,7 @@

// Add the chart to the worksheet
$worksheet->addChart($chart);
$worksheet->setSelectedCells('G2');

// Save Excel 2007 file
$filename = $helper->getFilename(__FILE__);
Expand Down
23 changes: 23 additions & 0 deletions src/PhpSpreadsheet/Chart/Axis.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public function __construct()
/** @var string */
private $axisType = '';

/** @var ?AxisText */
private $axisText;

/**
* Axis Options.
*
Expand Down Expand Up @@ -183,6 +186,14 @@ public function setAxisOptionsProperties(
*/
public function getAxisOptionsProperty($property)
{
if ($property === 'textRotation') {
if ($this->axisText !== null) {
if ($this->axisText->getRotation() !== null) {
return (string) $this->axisText->getRotation();
}
}
}

return $this->axisOptions[$property];
}

Expand Down Expand Up @@ -295,4 +306,16 @@ public function setMinorGridlines(?GridLines $gridlines): self

return $this;
}

public function getAxisText(): ?AxisText
{
return $this->axisText;
}

public function setAxisText(?AxisText $axisText): self
{
$this->axisText = $axisText;

return $this;
}
}
35 changes: 35 additions & 0 deletions src/PhpSpreadsheet/Chart/AxisText.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace PhpOffice\PhpSpreadsheet\Chart;

class AxisText extends Properties
{
/** @var ?int */
private $rotation;

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

public function __construct()
{
parent::__construct();
$this->fillColor = new ChartColor();
}

public function setRotation(?int $rotation): self
{
$this->rotation = $rotation;

return $this;
}

public function getRotation(): ?int
{
return $this->rotation;
}

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

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

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

/** @var ?AxisText */
private $legendText;

/**
* Create a new Legend.
*
Expand All @@ -60,6 +69,18 @@ public function __construct($position = self::POSITION_RIGHT, ?Layout $layout =
$this->setPosition($position);
$this->layout = $layout;
$this->setOverlay($overlay);
$this->borderColor = new ChartColor();
$this->fillColor = new ChartColor();
}

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

public function getFillColor(): ChartColor
{
return $this->fillColor;
}

/**
Expand Down Expand Up @@ -148,4 +169,16 @@ public function getLayout()
{
return $this->layout;
}

public function getLegendText(): ?AxisText
{
return $this->legendText;
}

public function setLegendText(?AxisText $legendText): self
{
$this->legendText = $legendText;

return $this;
}
}
70 changes: 65 additions & 5 deletions src/PhpSpreadsheet/Reader/Xlsx/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

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;
Expand Down Expand Up @@ -350,6 +351,10 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
$legendPos = 'r';
$legendLayout = null;
$legendOverlay = false;
$legendBorderColor = null;
$legendFillColor = null;
$legendText = null;
$addLegendText = false;
foreach ($chartDetails as $chartDetailKey => $chartDetail) {
$chartDetail = Xlsx::testSimpleXml($chartDetail);
switch ($chartDetailKey) {
Expand All @@ -364,10 +369,44 @@ public function readChart(SimpleXMLElement $chartElements, $chartName)
case 'layout':
$legendLayout = $this->chartLayoutDetails($chartDetail);

break;
case 'spPr':
$children = $chartDetails->spPr->children($this->aNamespace);
if (isset($children->solidFill)) {
$legendFillColor = $this->readColor($children->solidFill);
}
if (isset($children->ln->solidFill)) {
$legendBorderColor = $this->readColor($children->ln->solidFill);
}

break;
case 'txPr':
$children = $chartDetails->txPr->children($this->aNamespace);
$addLegendText = false;
$legendText = new AxisText();
if (isset($children->p->pPr->defRPr->solidFill)) {
$colorArray = $this->readColor($children->p->pPr->defRPr->solidFill);
$legendText->getFillColorObject()->setColorPropertiesArray($colorArray);
$addLegendText = true;
}
if (isset($children->p->pPr->defRPr->effectLst)) {
$this->readEffects($children->p->pPr->defRPr, $legendText, false);
$addLegendText = true;
}

break;
}
}
$legend = new Legend("$legendPos", $legendLayout, (bool) $legendOverlay);
if ($legendFillColor !== null) {
$legend->getFillColor()->setColorPropertiesArray($legendFillColor);
}
if ($legendBorderColor !== null) {
$legend->getBorderColor()->setColorPropertiesArray($legendBorderColor);
}
if ($addLegendText) {
$legend->setLegendText($legendText);
}

break;
}
Expand Down Expand Up @@ -1176,13 +1215,19 @@ private function setChartAttributes(Layout $plotArea, $plotAttributes): void
}
}

private function readEffects(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject): void
private function readEffects(SimpleXMLElement $chartDetail, ?ChartProperties $chartObject, bool $getSppr = true): void
{
if (!isset($chartObject, $chartDetail->spPr)) {
if (!isset($chartObject)) {
return;
}
$sppr = $chartDetail->spPr->children($this->aNamespace);

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) {
Expand Down Expand Up @@ -1412,13 +1457,28 @@ private function setAxisProperties(SimpleXMLElement $chartDetail, ?Axis $whichAx
}
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)) {
$whichAxis->setAxisOption('textRotation', (string) ChartProperties::xmlToAngle($textRotation));
$axisText->setRotation((int) ChartProperties::xmlToAngle($textRotation));
$addAxisText = true;
}
}
if (isset($children->p->pPr->defRPr->solidFill)) {
$colorArray = $this->readColor($children->p->pPr->defRPr->solidFill);
$axisText->getFillColorObject()->setColorPropertiesArray($colorArray);
$addAxisText = true;
}
if (isset($children->p->pPr->defRPr->effectLst)) {
$this->readEffects($children->p->pPr->defRPr, $axisText, false);
$addAxisText = true;
}
if ($addAxisText) {
$whichAxis->setAxisText($axisText);
}
}
}
}
Loading

0 comments on commit 2034864

Please sign in to comment.