Skip to content

Commit 7f626d9

Browse files
authored
Merge pull request #659 from Progi1984/displayBlankAs
Support for managing missing values in Chart
2 parents 543e19a + b933174 commit 7f626d9

File tree

12 files changed

+335
-61
lines changed

12 files changed

+335
-61
lines changed

docs/changes/1.0.0.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
- Support for rotation for axis label - @Progi1986 GH-410
4141
- ODPresentation Writer
4242
- PowerPoint2007 Writer
43+
- Support for managing missing values in Chart - @TonisOrmisson GH-581 & @Progi1986 GH-659
44+
- ODPresentation Writer
45+
- PowerPoint2007 Writer
4346

4447
## Project Management
4548
- Migrated from Travis CI to Github Actions - @Progi1984 GH-635
18.3 KB
Loading

docs/usage/presentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ $state = $presentation->isMarkedAsFinal();
138138

139139
You can define the type of slideshow you can with the method `setSlideshowType`.
140140

141-
![Slideshow type](/PHPPresentation/images/presentation_slideshow_type.png)
141+
![Slideshow type](/images/presentation_slideshow_type.png)
142142

143143
Differents types are available:
144144

docs/usage/shapes/chart.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,31 @@ To create a chart, use `createChartShape` method of Slide.
88
$chartShape = $slide->createChartShape();
99
```
1010

11+
## Customization
12+
13+
### Manage how blank values are displayed
14+
15+
You can define how blank values are displayed with the method `setDisplayBlankAs`.
16+
17+
![Slideshow type](/images/libreoffice_chart_displayblankas.png)
18+
19+
Differents types are available:
20+
21+
* `Chart::BLANKAS_GAP` for **Leave a gap**
22+
* `Chart::BLANKAS_ZERO` for **Assume zero** (default)
23+
* `Chart::BLANKAS_SPAN` for **Continue line**
24+
25+
``` php
26+
<?php
27+
28+
use PhpOffice\PhpPresentation\Shape\Chart;
29+
30+
// Set the behavior
31+
$chart->setDisplayBlankAs(Chart::BLANKAS_GAP);
32+
// Get the behavior
33+
echo $chart->getDisplayBlankAs();
34+
```
35+
1136
## Parts
1237

1338
### Axis

samples/Sample_05_Chart_Line.php

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
include_once 'Sample_Header.php';
44

55
use PhpOffice\PhpPresentation\PhpPresentation;
6+
use PhpOffice\PhpPresentation\Shape\Chart;
7+
use PhpOffice\PhpPresentation\Shape\Chart\Gridlines;
8+
use PhpOffice\PhpPresentation\Shape\Chart\Marker;
69
use PhpOffice\PhpPresentation\Shape\Chart\Series;
710
use PhpOffice\PhpPresentation\Shape\Chart\Type\Line;
811
use PhpOffice\PhpPresentation\Style\Border;
912
use PhpOffice\PhpPresentation\Style\Color;
1013
use PhpOffice\PhpPresentation\Style\Fill;
14+
use PhpOffice\PhpPresentation\Style\Outline;
1115
use PhpOffice\PhpPresentation\Style\Shadow;
1216

1317
// Create new PHPPresentation object
@@ -73,7 +77,7 @@
7377
$currentSlide = createTemplatedSlide($objPHPPresentation);
7478

7579
// Create a line chart (that should be inserted in a shape)
76-
$oOutline = new \PhpOffice\PhpPresentation\Style\Outline();
80+
$oOutline = new Outline();
7781
$oOutline->getFill()->setFillType(Fill::FILL_SOLID);
7882
$oOutline->getFill()->setStartColor(new Color(Color::COLOR_YELLOW));
7983
$oOutline->setWidth(2);
@@ -82,7 +86,7 @@
8286
$lineChart1 = clone $lineChart;
8387
$series1 = $lineChart1->getSeries();
8488
$series1[0]->setOutline($oOutline);
85-
$series1[0]->getMarker()->setSymbol(\PhpOffice\PhpPresentation\Shape\Chart\Marker::SYMBOL_DIAMOND);
89+
$series1[0]->getMarker()->setSymbol(Marker::SYMBOL_DIAMOND);
8690
$series1[0]->getMarker()->setSize(7);
8791
$lineChart1->setSeries($series1);
8892

@@ -106,7 +110,7 @@
106110
$lineChart2 = clone $lineChart;
107111
$series2 = $lineChart2->getSeries();
108112
$series2[0]->getFont()->setSize(25);
109-
$series2[0]->getMarker()->setSymbol(\PhpOffice\PhpPresentation\Shape\Chart\Marker::SYMBOL_TRIANGLE);
113+
$series2[0]->getMarker()->setSymbol(Marker::SYMBOL_TRIANGLE);
110114
$series2[0]->getMarker()->setSize(10);
111115
$lineChart2->setSeries($series2);
112116

@@ -129,11 +133,11 @@
129133
echo date('H:i:s') . ' Create a line chart (that should be inserted in a chart shape)' . EOL;
130134
$lineChart3 = clone $lineChart;
131135

132-
$oGridLines1 = new \PhpOffice\PhpPresentation\Shape\Chart\Gridlines();
136+
$oGridLines1 = new Gridlines();
133137
$oGridLines1->getOutline()->setWidth(10);
134138
$oGridLines1->getOutline()->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_BLUE));
135139

136-
$oGridLines2 = new \PhpOffice\PhpPresentation\Shape\Chart\Gridlines();
140+
$oGridLines2 = new Gridlines();
137141
$oGridLines2->getOutline()->setWidth(1);
138142
$oGridLines2->getOutline()->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKGREEN));
139143

@@ -156,12 +160,12 @@
156160
echo date('H:i:s') . ' Create a line chart (that should be inserted in a chart shape)' . EOL;
157161
$lineChart4 = clone $lineChart;
158162

159-
$oOutlineAxisX = new \PhpOffice\PhpPresentation\Style\Outline();
163+
$oOutlineAxisX = new Outline();
160164
$oOutlineAxisX->setWidth(2);
161165
$oOutlineAxisX->getFill()->setFillType(Fill::FILL_SOLID);
162166
$oOutlineAxisX->getFill()->getStartColor()->setRGB('012345');
163167

164-
$oOutlineAxisY = new \PhpOffice\PhpPresentation\Style\Outline();
168+
$oOutlineAxisY = new Outline();
165169
$oOutlineAxisY->setWidth(5);
166170
$oOutlineAxisY->getFill()->setFillType(Fill::FILL_SOLID);
167171
$oOutlineAxisY->getFill()->getStartColor()->setRGB('ABCDEF');
@@ -190,6 +194,26 @@
190194
$shape5->getPlotArea()->getAxisY()->setMinBounds(5);
191195
$shape5->getPlotArea()->getAxisY()->setMaxBounds(20);
192196
$currentSlide->addShape($shape5);
197+
198+
// Create templated slide
199+
echo EOL . date('H:i:s') . ' Create templated slide #6' . EOL;
200+
$currentSlide = createTemplatedSlide($objPHPPresentation);
201+
202+
// Create a shape (chart)
203+
echo date('H:i:s') . ' Create a shape (chart6)' . EOL;
204+
echo date('H:i:s') . ' Feature : DisplayBlankAs' . EOL;
205+
$shape6 = clone $shape;
206+
$lineChart6 = clone $lineChart;
207+
$series6 = clone $series;
208+
$seriesData6 = $seriesData;
209+
$seriesData6['Thursday'] = null;
210+
211+
$series6->setValues($seriesData6);
212+
$lineChart6->setSeries([$series6]);
213+
$shape6->getPlotArea()->setType($lineChart6);
214+
$shape6->setDisplayBlankAs(Chart::BLANKAS_GAP);
215+
$currentSlide->addShape($shape6);
216+
193217
// Save file
194218
echo EOL . write($objPHPPresentation, basename(__FILE__, '.php'), $writers);
195219

src/PhpPresentation/Shape/Chart.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
*/
3030
class Chart extends AbstractGraphic implements ComparableInterface
3131
{
32+
public const BLANKAS_GAP = 'gap';
33+
public const BLANKAS_ZERO = 'zero';
34+
public const BLANKAS_SPAN = 'span';
35+
3236
/**
3337
* Title.
3438
*
@@ -64,6 +68,13 @@ class Chart extends AbstractGraphic implements ComparableInterface
6468
*/
6569
private $includeSpreadsheet = false;
6670

71+
/**
72+
* How to display blank (missing) values? Not set by default.
73+
*
74+
* @var string
75+
*/
76+
private $displayBlankAs = self::BLANKAS_ZERO;
77+
6778
/**
6879
* Create a new Chart.
6980
*/
@@ -89,6 +100,16 @@ public function __clone()
89100
$this->view3D = clone $this->view3D;
90101
}
91102

103+
/**
104+
* How missing/blank values are displayed on chart (dispBlanksAs property)
105+
*
106+
* @return string
107+
*/
108+
public function getDisplayBlankAs(): string
109+
{
110+
return $this->displayBlankAs;
111+
}
112+
92113
/**
93114
* Get Title.
94115
*
@@ -139,6 +160,22 @@ public function hasIncludedSpreadsheet(): bool
139160
return $this->includeSpreadsheet;
140161
}
141162

163+
/**
164+
* Define a way to display missing/blank values (dispBlanksAs property)
165+
*
166+
* @param string $value
167+
*
168+
* @return self
169+
*/
170+
public function setDisplayBlankAs(string $value): self
171+
{
172+
if (in_array($value, [self::BLANKAS_GAP, self::BLANKAS_SPAN, self::BLANKAS_ZERO])) {
173+
$this->displayBlankAs = $value;
174+
}
175+
176+
return $this;
177+
}
178+
142179
/**
143180
* Is the spreadsheet included for editing data ?
144181
*

src/PhpPresentation/Shape/Chart/Series.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class Series implements ComparableInterface
132132
/**
133133
* Values (key/value).
134134
*
135-
* @var array<string, string>
135+
* @var array<string, string|null>
136136
*/
137137
private $values = [];
138138

@@ -144,17 +144,19 @@ class Series implements ComparableInterface
144144
private $hashIndex;
145145

146146
/**
147-
* @param array<string, string> $values
147+
* @param string $title
148+
* @param array<string, string|null> $values
148149
*/
149150
public function __construct(string $title = 'Series Title', array $values = [])
150151
{
151152
$this->fill = new Fill();
152153
$this->font = new Font();
153154
$this->font->setName('Calibri');
154155
$this->font->setSize(9);
156+
$this->marker = new Marker();
157+
155158
$this->title = $title;
156159
$this->values = $values;
157-
$this->marker = new Marker();
158160
}
159161

160162
/**
@@ -239,7 +241,7 @@ public function getDataPointFills(): array
239241
/**
240242
* Get Values.
241243
*
242-
* @return array<string, string>
244+
* @return array<string, string|null>
243245
*/
244246
public function getValues(): array
245247
{
@@ -249,7 +251,7 @@ public function getValues(): array
249251
/**
250252
* Set Values.
251253
*
252-
* @param array<string, string> $values
254+
* @param array<string, string|null> $values
253255
*/
254256
public function setValues(array $values = []): self
255257
{
@@ -260,8 +262,13 @@ public function setValues(array $values = []): self
260262

261263
/**
262264
* Add Value.
265+
*
266+
* @param string $key
267+
* @param string|null $value
268+
*
269+
* @return self
263270
*/
264-
public function addValue(string $key, string $value): self
271+
public function addValue(string $key, ?string $value): self
265272
{
266273
$this->values[$key] = $value;
267274

src/PhpPresentation/Writer/ODPresentation/ObjectsChart.php

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,17 @@ private function writePlotAreaStyle(Chart $chart): void
544544
$this->xmlContent->writeAttribute('chart:three-dimensional', 'true');
545545
$this->xmlContent->writeAttribute('chart:right-angled-axes', 'true');
546546
}
547+
switch ($chart->getDisplayBlankAs()) {
548+
case Chart::BLANKAS_ZERO:
549+
$this->xmlContent->writeAttribute('chart:treat-empty-cells', 'use-zero');
550+
break;
551+
case Chart::BLANKAS_GAP:
552+
$this->xmlContent->writeAttribute('chart:treat-empty-cells', 'leave-gap');
553+
break;
554+
case Chart::BLANKAS_SPAN:
555+
$this->xmlContent->writeAttribute('chart:treat-empty-cells', 'ignore');
556+
break;
557+
}
547558
if ($chartType instanceof AbstractTypeBar) {
548559
$chartVertical = 'false';
549560
if (AbstractTypeBar::DIRECTION_HORIZONTAL == $chartType->getBarDirection()) {
@@ -809,40 +820,6 @@ private function writeTable(): void
809820
// > table:table-header-columns
810821
$this->xmlContent->endElement();
811822

812-
// table:table-rows
813-
$this->xmlContent->startElement('table:table-rows');
814-
if (empty($this->arrayData)) {
815-
$this->xmlContent->startElement('table:table-row');
816-
$this->xmlContent->startElement('table:table-cell');
817-
$this->xmlContent->endElement();
818-
$this->xmlContent->endElement();
819-
} else {
820-
foreach ($this->arrayData as $row) {
821-
// table:table-row
822-
$this->xmlContent->startElement('table:table-row');
823-
foreach ($row as $cell) {
824-
// table:table-cell
825-
$this->xmlContent->startElement('table:table-cell');
826-
827-
$cellNumeric = is_numeric($cell);
828-
$this->xmlContent->writeAttributeIf(!$cellNumeric, 'office:value-type', 'string');
829-
$this->xmlContent->writeAttributeIf($cellNumeric, 'office:value-type', 'float');
830-
$this->xmlContent->writeAttributeIf($cellNumeric, 'office:value', $cell);
831-
// text:p
832-
$this->xmlContent->startElement('text:p');
833-
$this->xmlContent->text($cell);
834-
// > text:p
835-
$this->xmlContent->endElement();
836-
// > table:table-cell
837-
$this->xmlContent->endElement();
838-
}
839-
// > table:table-row
840-
$this->xmlContent->endElement();
841-
}
842-
}
843-
// > table:table-rows
844-
$this->xmlContent->endElement();
845-
846823
// table:table-header-rows
847824
$this->xmlContent->startElement('table:table-header-rows');
848825
// table:table-row
@@ -874,6 +851,39 @@ private function writeTable(): void
874851
// > table:table-header-rows
875852
$this->xmlContent->endElement();
876853

854+
// table:table-rows
855+
$this->xmlContent->startElement('table:table-rows');
856+
if (empty($this->arrayData)) {
857+
$this->xmlContent->startElement('table:table-row');
858+
$this->xmlContent->startElement('table:table-cell');
859+
$this->xmlContent->endElement();
860+
$this->xmlContent->endElement();
861+
} else {
862+
foreach ($this->arrayData as $row) {
863+
// table:table-row
864+
$this->xmlContent->startElement('table:table-row');
865+
foreach ($row as $cell) {
866+
// table:table-cell
867+
$this->xmlContent->startElement('table:table-cell');
868+
869+
$cellValueTypeFloat = is_null($cell) ? true : is_numeric($cell);
870+
$this->xmlContent->writeAttributeIf(!$cellValueTypeFloat, 'office:value-type', 'string');
871+
$this->xmlContent->writeAttributeIf($cellValueTypeFloat, 'office:value-type', 'float');
872+
$this->xmlContent->writeAttributeIf($cellValueTypeFloat, 'office:value', is_null($cell) ? 'NaN' : $cell);
873+
// text:p
874+
$this->xmlContent->startElement('text:p');
875+
$this->xmlContent->text(is_null($cell) ? 'NaN' : $cell);
876+
$this->xmlContent->endElement();
877+
// > table:table-cell
878+
$this->xmlContent->endElement();
879+
}
880+
// > table:table-row
881+
$this->xmlContent->endElement();
882+
}
883+
}
884+
// > table:table-rows
885+
$this->xmlContent->endElement();
886+
877887
// > table:table
878888
$this->xmlContent->endElement();
879889
}

src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ public function writeChart(Chart $chart): string
146146
$objWriter->writeAttribute('val', '1');
147147
$objWriter->endElement();
148148

149+
// c:dispBlanksAs
150+
$objWriter->startElement('c:dispBlanksAs');
151+
$objWriter->writeAttribute('val', $chart->getDisplayBlankAs());
152+
$objWriter->endElement();
153+
149154
$objWriter->endElement();
150155

151156
// c:spPr

0 commit comments

Comments
 (0)