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 for managing missing values in Chart #659

Merged
merged 1 commit into from
Jul 27, 2021
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
3 changes: 3 additions & 0 deletions docs/changes/1.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
- Support for rotation for axis label - @Progi1986 GH-410
- ODPresentation Writer
- PowerPoint2007 Writer
- Support for managing missing values in Chart - @TonisOrmisson GH-581 & @Progi1986 GH-659
- ODPresentation Writer
- PowerPoint2007 Writer

## Project Management
- Migrated from Travis CI to Github Actions - @Progi1984 GH-635
Expand Down
Binary file added docs/images/libreoffice_chart_displayblankas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/usage/presentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ $state = $presentation->isMarkedAsFinal();

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

![Slideshow type](/PHPPresentation/images/presentation_slideshow_type.png)
![Slideshow type](/images/presentation_slideshow_type.png)

Differents types are available:

Expand Down
25 changes: 25 additions & 0 deletions docs/usage/shapes/chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@ To create a chart, use `createChartShape` method of Slide.
$chartShape = $slide->createChartShape();
```

## Customization

### Manage how blank values are displayed

You can define how blank values are displayed with the method `setDisplayBlankAs`.

![Slideshow type](/images/libreoffice_chart_displayblankas.png)

Differents types are available:

* `Chart::BLANKAS_GAP` for **Leave a gap**
* `Chart::BLANKAS_ZERO` for **Assume zero** (default)
* `Chart::BLANKAS_SPAN` for **Continue line**

``` php
<?php

use PhpOffice\PhpPresentation\Shape\Chart;

// Set the behavior
$chart->setDisplayBlankAs(Chart::BLANKAS_GAP);
// Get the behavior
echo $chart->getDisplayBlankAs();
```

## Parts

### Axis
Expand Down
38 changes: 31 additions & 7 deletions samples/Sample_05_Chart_Line.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
include_once 'Sample_Header.php';

use PhpOffice\PhpPresentation\PhpPresentation;
use PhpOffice\PhpPresentation\Shape\Chart;
use PhpOffice\PhpPresentation\Shape\Chart\Gridlines;
use PhpOffice\PhpPresentation\Shape\Chart\Marker;
use PhpOffice\PhpPresentation\Shape\Chart\Series;
use PhpOffice\PhpPresentation\Shape\Chart\Type\Line;
use PhpOffice\PhpPresentation\Style\Border;
use PhpOffice\PhpPresentation\Style\Color;
use PhpOffice\PhpPresentation\Style\Fill;
use PhpOffice\PhpPresentation\Style\Outline;
use PhpOffice\PhpPresentation\Style\Shadow;

// Create new PHPPresentation object
Expand Down Expand Up @@ -73,7 +77,7 @@
$currentSlide = createTemplatedSlide($objPHPPresentation);

// Create a line chart (that should be inserted in a shape)
$oOutline = new \PhpOffice\PhpPresentation\Style\Outline();
$oOutline = new Outline();
$oOutline->getFill()->setFillType(Fill::FILL_SOLID);
$oOutline->getFill()->setStartColor(new Color(Color::COLOR_YELLOW));
$oOutline->setWidth(2);
Expand All @@ -82,7 +86,7 @@
$lineChart1 = clone $lineChart;
$series1 = $lineChart1->getSeries();
$series1[0]->setOutline($oOutline);
$series1[0]->getMarker()->setSymbol(\PhpOffice\PhpPresentation\Shape\Chart\Marker::SYMBOL_DIAMOND);
$series1[0]->getMarker()->setSymbol(Marker::SYMBOL_DIAMOND);
$series1[0]->getMarker()->setSize(7);
$lineChart1->setSeries($series1);

Expand All @@ -106,7 +110,7 @@
$lineChart2 = clone $lineChart;
$series2 = $lineChart2->getSeries();
$series2[0]->getFont()->setSize(25);
$series2[0]->getMarker()->setSymbol(\PhpOffice\PhpPresentation\Shape\Chart\Marker::SYMBOL_TRIANGLE);
$series2[0]->getMarker()->setSymbol(Marker::SYMBOL_TRIANGLE);
$series2[0]->getMarker()->setSize(10);
$lineChart2->setSeries($series2);

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

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

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

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

$oOutlineAxisX = new \PhpOffice\PhpPresentation\Style\Outline();
$oOutlineAxisX = new Outline();
$oOutlineAxisX->setWidth(2);
$oOutlineAxisX->getFill()->setFillType(Fill::FILL_SOLID);
$oOutlineAxisX->getFill()->getStartColor()->setRGB('012345');

$oOutlineAxisY = new \PhpOffice\PhpPresentation\Style\Outline();
$oOutlineAxisY = new Outline();
$oOutlineAxisY->setWidth(5);
$oOutlineAxisY->getFill()->setFillType(Fill::FILL_SOLID);
$oOutlineAxisY->getFill()->getStartColor()->setRGB('ABCDEF');
Expand Down Expand Up @@ -190,6 +194,26 @@
$shape5->getPlotArea()->getAxisY()->setMinBounds(5);
$shape5->getPlotArea()->getAxisY()->setMaxBounds(20);
$currentSlide->addShape($shape5);

// Create templated slide
echo EOL . date('H:i:s') . ' Create templated slide #6' . EOL;
$currentSlide = createTemplatedSlide($objPHPPresentation);

// Create a shape (chart)
echo date('H:i:s') . ' Create a shape (chart6)' . EOL;
echo date('H:i:s') . ' Feature : DisplayBlankAs' . EOL;
$shape6 = clone $shape;
$lineChart6 = clone $lineChart;
$series6 = clone $series;
$seriesData6 = $seriesData;
$seriesData6['Thursday'] = null;

$series6->setValues($seriesData6);
$lineChart6->setSeries([$series6]);
$shape6->getPlotArea()->setType($lineChart6);
$shape6->setDisplayBlankAs(Chart::BLANKAS_GAP);
$currentSlide->addShape($shape6);

// Save file
echo EOL . write($objPHPPresentation, basename(__FILE__, '.php'), $writers);

Expand Down
37 changes: 37 additions & 0 deletions src/PhpPresentation/Shape/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
*/
class Chart extends AbstractGraphic implements ComparableInterface
{
public const BLANKAS_GAP = 'gap';
public const BLANKAS_ZERO = 'zero';
public const BLANKAS_SPAN = 'span';

/**
* Title.
*
Expand Down Expand Up @@ -64,6 +68,13 @@ class Chart extends AbstractGraphic implements ComparableInterface
*/
private $includeSpreadsheet = false;

/**
* How to display blank (missing) values? Not set by default.
*
* @var string
*/
private $displayBlankAs = self::BLANKAS_ZERO;

/**
* Create a new Chart.
*/
Expand All @@ -89,6 +100,16 @@ public function __clone()
$this->view3D = clone $this->view3D;
}

/**
* How missing/blank values are displayed on chart (dispBlanksAs property)
*
* @return string
*/
public function getDisplayBlankAs(): string
{
return $this->displayBlankAs;
}

/**
* Get Title.
*
Expand Down Expand Up @@ -139,6 +160,22 @@ public function hasIncludedSpreadsheet(): bool
return $this->includeSpreadsheet;
}

/**
* Define a way to display missing/blank values (dispBlanksAs property)
*
* @param string $value
*
* @return self
*/
public function setDisplayBlankAs(string $value): self
{
if (in_array($value, [self::BLANKAS_GAP, self::BLANKAS_SPAN, self::BLANKAS_ZERO])) {
$this->displayBlankAs = $value;
}

return $this;
}

/**
* Is the spreadsheet included for editing data ?
*
Expand Down
19 changes: 13 additions & 6 deletions src/PhpPresentation/Shape/Chart/Series.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class Series implements ComparableInterface
/**
* Values (key/value).
*
* @var array<string, string>
* @var array<string, string|null>
*/
private $values = [];

Expand All @@ -144,17 +144,19 @@ class Series implements ComparableInterface
private $hashIndex;

/**
* @param array<string, string> $values
* @param string $title
* @param array<string, string|null> $values
*/
public function __construct(string $title = 'Series Title', array $values = [])
{
$this->fill = new Fill();
$this->font = new Font();
$this->font->setName('Calibri');
$this->font->setSize(9);
$this->marker = new Marker();

$this->title = $title;
$this->values = $values;
$this->marker = new Marker();
}

/**
Expand Down Expand Up @@ -239,7 +241,7 @@ public function getDataPointFills(): array
/**
* Get Values.
*
* @return array<string, string>
* @return array<string, string|null>
*/
public function getValues(): array
{
Expand All @@ -249,7 +251,7 @@ public function getValues(): array
/**
* Set Values.
*
* @param array<string, string> $values
* @param array<string, string|null> $values
*/
public function setValues(array $values = []): self
{
Expand All @@ -260,8 +262,13 @@ public function setValues(array $values = []): self

/**
* Add Value.
*
* @param string $key
* @param string|null $value
*
* @return self
*/
public function addValue(string $key, string $value): self
public function addValue(string $key, ?string $value): self
{
$this->values[$key] = $value;

Expand Down
78 changes: 44 additions & 34 deletions src/PhpPresentation/Writer/ODPresentation/ObjectsChart.php
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,17 @@ private function writePlotAreaStyle(Chart $chart): void
$this->xmlContent->writeAttribute('chart:three-dimensional', 'true');
$this->xmlContent->writeAttribute('chart:right-angled-axes', 'true');
}
switch ($chart->getDisplayBlankAs()) {
case Chart::BLANKAS_ZERO:
$this->xmlContent->writeAttribute('chart:treat-empty-cells', 'use-zero');
break;
case Chart::BLANKAS_GAP:
$this->xmlContent->writeAttribute('chart:treat-empty-cells', 'leave-gap');
break;
case Chart::BLANKAS_SPAN:
$this->xmlContent->writeAttribute('chart:treat-empty-cells', 'ignore');
break;
}
if ($chartType instanceof AbstractTypeBar) {
$chartVertical = 'false';
if (AbstractTypeBar::DIRECTION_HORIZONTAL == $chartType->getBarDirection()) {
Expand Down Expand Up @@ -809,40 +820,6 @@ private function writeTable(): void
// > table:table-header-columns
$this->xmlContent->endElement();

// table:table-rows
$this->xmlContent->startElement('table:table-rows');
if (empty($this->arrayData)) {
$this->xmlContent->startElement('table:table-row');
$this->xmlContent->startElement('table:table-cell');
$this->xmlContent->endElement();
$this->xmlContent->endElement();
} else {
foreach ($this->arrayData as $row) {
// table:table-row
$this->xmlContent->startElement('table:table-row');
foreach ($row as $cell) {
// table:table-cell
$this->xmlContent->startElement('table:table-cell');

$cellNumeric = is_numeric($cell);
$this->xmlContent->writeAttributeIf(!$cellNumeric, 'office:value-type', 'string');
$this->xmlContent->writeAttributeIf($cellNumeric, 'office:value-type', 'float');
$this->xmlContent->writeAttributeIf($cellNumeric, 'office:value', $cell);
// text:p
$this->xmlContent->startElement('text:p');
$this->xmlContent->text($cell);
// > text:p
$this->xmlContent->endElement();
// > table:table-cell
$this->xmlContent->endElement();
}
// > table:table-row
$this->xmlContent->endElement();
}
}
// > table:table-rows
$this->xmlContent->endElement();

// table:table-header-rows
$this->xmlContent->startElement('table:table-header-rows');
// table:table-row
Expand Down Expand Up @@ -874,6 +851,39 @@ private function writeTable(): void
// > table:table-header-rows
$this->xmlContent->endElement();

// table:table-rows
$this->xmlContent->startElement('table:table-rows');
if (empty($this->arrayData)) {
$this->xmlContent->startElement('table:table-row');
$this->xmlContent->startElement('table:table-cell');
$this->xmlContent->endElement();
$this->xmlContent->endElement();
} else {
foreach ($this->arrayData as $row) {
// table:table-row
$this->xmlContent->startElement('table:table-row');
foreach ($row as $cell) {
// table:table-cell
$this->xmlContent->startElement('table:table-cell');

$cellValueTypeFloat = is_null($cell) ? true : is_numeric($cell);
$this->xmlContent->writeAttributeIf(!$cellValueTypeFloat, 'office:value-type', 'string');
$this->xmlContent->writeAttributeIf($cellValueTypeFloat, 'office:value-type', 'float');
$this->xmlContent->writeAttributeIf($cellValueTypeFloat, 'office:value', is_null($cell) ? 'NaN' : $cell);
// text:p
$this->xmlContent->startElement('text:p');
$this->xmlContent->text(is_null($cell) ? 'NaN' : $cell);
$this->xmlContent->endElement();
// > table:table-cell
$this->xmlContent->endElement();
}
// > table:table-row
$this->xmlContent->endElement();
}
}
// > table:table-rows
$this->xmlContent->endElement();

// > table:table
$this->xmlContent->endElement();
}
Expand Down
5 changes: 5 additions & 0 deletions src/PhpPresentation/Writer/PowerPoint2007/PptCharts.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ public function writeChart(Chart $chart): string
$objWriter->writeAttribute('val', '1');
$objWriter->endElement();

// c:dispBlanksAs
$objWriter->startElement('c:dispBlanksAs');
$objWriter->writeAttribute('val', $chart->getDisplayBlankAs());
$objWriter->endElement();

$objWriter->endElement();

// c:spPr
Expand Down
Loading