Skip to content

Commit d111522

Browse files
authored
Eliminate Corruption in Surface Chart Samples (#2846)
* Eliminate Corruption in Surface Chart Samples Fix #2763 (bubble charts were fixed earlier). * Improvement in Testing for Numeric Values The original proposal was to test for numeric values by checking whether the format was NUMERIC or DATE. This is pretty inflexible, and left open a wide gap concerning what to do with GENERAL. Changed to allow the user to set a `numeric` property at the same time as `axisNumberProperties`, eliminating these concerns. User can set property when chart is created (new test member Charts32CatAxValAxTest), or can set it when spreadsheet with chart is read (new method testCatAxValAx in Charts32XmlTest). Sample 33_Chart_create_scatter2 creates a slightly wider chart when `numeric` is set to true than it does when unset, but chart is otherwise the same. Corrected a bug which occured twice in Chart. Methods getChartAxisX and getChartAxisY created a new Axis object if the chart pointer was null, but neglected to attach the new object to the chart. Thus, subsequent calls to the methods return different objects. Code is changed to attach the new Axis to the Chart.
1 parent a54d1c1 commit d111522

File tree

9 files changed

+434
-42
lines changed

9 files changed

+434
-42
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4775,26 +4775,6 @@ parameters:
47754775
count: 2
47764776
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
47774777

4778-
-
4779-
message: "#^Parameter \\#3 \\$id1 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects string, int\\|string given\\.$#"
4780-
count: 1
4781-
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
4782-
4783-
-
4784-
message: "#^Parameter \\#4 \\$id1 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects string, int\\|string given\\.$#"
4785-
count: 2
4786-
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
4787-
4788-
-
4789-
message: "#^Parameter \\#4 \\$id2 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects string, int\\|string given\\.$#"
4790-
count: 1
4791-
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
4792-
4793-
-
4794-
message: "#^Parameter \\#5 \\$id2 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects string, int\\|string given\\.$#"
4795-
count: 2
4796-
path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
4797-
47984778
-
47994779
message: "#^Parameter \\#6 \\$yAxis of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\|null given\\.$#"
48004780
count: 1

samples/Chart/33_Chart_create_scatter2.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
['=DATEVALUE("2021-01-10")', 30.2, 32.2, 0.2],
2626
]
2727
);
28-
$worksheet->getStyle('A2:A5')->getNumberFormat()->setFormatCode('yyyy-mm-dd');
28+
$worksheet->getStyle('A2:A5')->getNumberFormat()->setFormatCode(Properties::FORMAT_CODE_DATE_ISO8601);
2929
$worksheet->getColumnDimension('A')->setAutoSize(true);
3030
$worksheet->setSelectedCells('A1');
3131

@@ -67,7 +67,7 @@
6767
// Added so that Xaxis shows dates instead of Excel-equivalent-year1900-numbers
6868
$xAxis = new Axis();
6969
//$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE );
70-
$xAxis->setAxisNumberProperties('yyyy-mm-dd');
70+
$xAxis->setAxisNumberProperties(Properties::FORMAT_CODE_DATE_ISO8601, true);
7171

7272
// Build the dataseries
7373
$series = new DataSeries(
@@ -78,7 +78,7 @@
7878
$xAxisTickValues, // plotCategory
7979
$dataSeriesValues, // plotValues
8080
null, // plotDirection
81-
null, // smooth line
81+
false, // smooth line
8282
//DataSeries::STYLE_LINEMARKER // plotStyle
8383
DataSeries::STYLE_MARKER // plotStyle
8484
);
@@ -107,7 +107,7 @@
107107

108108
// Set the position where the chart should appear in the worksheet
109109
$chart->setTopLeftPosition('A7');
110-
$chart->setBottomRightPosition('N20');
110+
$chart->setBottomRightPosition('P20');
111111
// Add the chart to the worksheet
112112
$worksheet->addChart($chart);
113113

src/PhpSpreadsheet/Chart/Axis.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Axis extends Properties
1818
private $axisNumber = [
1919
'format' => self::FORMAT_CODE_GENERAL,
2020
'source_linked' => 1,
21+
'numeric' => null,
2122
];
2223

2324
/**
@@ -131,15 +132,26 @@ class Axis extends Properties
131132
'size' => null,
132133
];
133134

135+
private const NUMERIC_FORMAT = [
136+
Properties::FORMAT_CODE_NUMBER,
137+
Properties::FORMAT_CODE_DATE,
138+
];
139+
134140
/**
135141
* Get Series Data Type.
136142
*
137143
* @param mixed $format_code
138144
*/
139-
public function setAxisNumberProperties($format_code): void
145+
public function setAxisNumberProperties($format_code, ?bool $numeric = null): void
140146
{
141-
$this->axisNumber['format'] = (string) $format_code;
147+
$format = (string) $format_code;
148+
$this->axisNumber['format'] = $format;
142149
$this->axisNumber['source_linked'] = 0;
150+
if (is_bool($numeric)) {
151+
$this->axisNumber['numeric'] = $numeric;
152+
} elseif (in_array($format, self::NUMERIC_FORMAT, true)) {
153+
$this->axisNumber['numeric'] = true;
154+
}
143155
}
144156

145157
/**
@@ -162,6 +174,11 @@ public function getAxisNumberSourceLinked()
162174
return (string) $this->axisNumber['source_linked'];
163175
}
164176

177+
public function getAxisIsNumericFormat(): bool
178+
{
179+
return (bool) $this->axisNumber['numeric'];
180+
}
181+
165182
/**
166183
* Set Axis Options Properties.
167184
*

src/PhpSpreadsheet/Chart/Chart.php

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,18 @@ class Chart
140140
*/
141141
private $bottomRightYOffset = 10;
142142

143+
/** @var ?int */
144+
private $rotX;
145+
146+
/** @var ?int */
147+
private $rotY;
148+
149+
/** @var ?int */
150+
private $rAngAx;
151+
152+
/** @var ?int */
153+
private $perspective;
154+
143155
/**
144156
* Create a new Chart.
145157
*
@@ -351,8 +363,9 @@ public function getChartAxisY()
351363
if ($this->yAxis !== null) {
352364
return $this->yAxis;
353365
}
366+
$this->yAxis = new Axis();
354367

355-
return new Axis();
368+
return $this->yAxis;
356369
}
357370

358371
/**
@@ -365,8 +378,9 @@ public function getChartAxisX()
365378
if ($this->xAxis !== null) {
366379
return $this->xAxis;
367380
}
381+
$this->xAxis = new Axis();
368382

369-
return new Axis();
383+
return $this->xAxis;
370384
}
371385

372386
/**
@@ -681,4 +695,52 @@ public function render($outputDestination = null)
681695

682696
return $renderer->render($outputDestination);
683697
}
698+
699+
public function getRotX(): ?int
700+
{
701+
return $this->rotX;
702+
}
703+
704+
public function setRotX(?int $rotX): self
705+
{
706+
$this->rotX = $rotX;
707+
708+
return $this;
709+
}
710+
711+
public function getRotY(): ?int
712+
{
713+
return $this->rotY;
714+
}
715+
716+
public function setRotY(?int $rotY): self
717+
{
718+
$this->rotY = $rotY;
719+
720+
return $this;
721+
}
722+
723+
public function getRAngAx(): ?int
724+
{
725+
return $this->rAngAx;
726+
}
727+
728+
public function setRAngAx(?int $rAngAx): self
729+
{
730+
$this->rAngAx = $rAngAx;
731+
732+
return $this;
733+
}
734+
735+
public function getPerspective(): ?int
736+
{
737+
return $this->perspective;
738+
}
739+
740+
public function setPerspective(?int $perspective): self
741+
{
742+
$this->perspective = $perspective;
743+
744+
return $this;
745+
}
684746
}

src/PhpSpreadsheet/Chart/Properties.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ abstract class Properties
3737
const FORMAT_CODE_CURRENCY = '$#,##0.00';
3838
const FORMAT_CODE_ACCOUNTING = '_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)';
3939
const FORMAT_CODE_DATE = 'm/d/yyyy';
40+
const FORMAT_CODE_DATE_ISO8601 = 'yyyy-mm-dd';
4041
const FORMAT_CODE_TIME = '[$-F400]h:mm:ss AM/PM';
4142
const FORMAT_CODE_PERCENTAGE = '0.00%';
4243
const FORMAT_CODE_FRACTION = '# ?/?';

src/PhpSpreadsheet/Reader/Xlsx/Chart.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,20 @@ public static function readChart(SimpleXMLElement $chartElements, $chartName)
5555
$XaxisLabel = $YaxisLabel = $legend = $title = null;
5656
$dispBlanksAs = $plotVisOnly = null;
5757
$plotArea = null;
58+
$rotX = $rotY = $rAngAx = $perspective = null;
5859
foreach ($chartElementsC as $chartElementKey => $chartElement) {
5960
switch ($chartElementKey) {
6061
case 'chart':
6162
foreach ($chartElement as $chartDetailsKey => $chartDetails) {
6263
$chartDetailsC = $chartDetails->children($namespacesChartMeta['c']);
6364
switch ($chartDetailsKey) {
65+
case 'view3D':
66+
$rotX = self::getAttribute($chartDetails->rotX, 'val', 'integer');
67+
$rotY = self::getAttribute($chartDetails->rotY, 'val', 'integer');
68+
$rAngAx = self::getAttribute($chartDetails->rAngAx, 'val', 'integer');
69+
$perspective = self::getAttribute($chartDetails->perspective, 'val', 'integer');
70+
71+
break;
6472
case 'plotArea':
6573
$plotAreaLayout = $XaxisLabel = $YaxisLabel = null;
6674
$plotSeries = $plotAttributes = [];
@@ -220,6 +228,18 @@ public static function readChart(SimpleXMLElement $chartElements, $chartName)
220228
}
221229
}
222230
$chart = new \PhpOffice\PhpSpreadsheet\Chart\Chart($chartName, $title, $legend, $plotArea, $plotVisOnly, $dispBlanksAs, $XaxisLabel, $YaxisLabel);
231+
if (is_int($rotX)) {
232+
$chart->setRotX($rotX);
233+
}
234+
if (is_int($rotY)) {
235+
$chart->setRotY($rotY);
236+
}
237+
if (is_int($rAngAx)) {
238+
$chart->setRAngAx($rAngAx);
239+
}
240+
if (is_int($perspective)) {
241+
$chart->setPerspective($perspective);
242+
}
223243

224244
return $chart;
225245
}

0 commit comments

Comments
 (0)