Skip to content
Open
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
4 changes: 3 additions & 1 deletion docs/changes/1.x/1.5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

## Enhancements

- adds the setDisplayBlanksAs option to the Chart Style, allowing users to handle null values in series data. You can choose 'gap' (break line), 'span' (connect line), or 'zero' (display nulls as zero, as it the current default).

### Bug fixes

- Set writeAttribute return type by [@radarhere](https://github.com/radarhere) fixing [#2204](https://github.com/PHPOffice/PHPWord/issues/2204) in [#2776](https://github.com/PHPOffice/PHPWord/pull/2776)
Expand All @@ -16,4 +18,4 @@

### BC Breaks

### Notes
### Notes
3 changes: 2 additions & 1 deletion docs/usage/styles/chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ Available Chart style options:
- ``majorTickMarkPos``. The position for major tick marks, *in*, *out*, *cross*, *none* (default).
- ``showAxisLabels``. Show labels for axis, *true* or *false*.
- ``gridX``. Show Gridlines for X-Axis, *true* or *false*.
- ``gridY``. Show Gridlines for Y-Axis, *true* or *false*.
- ``gridY``. Show Gridlines for Y-Axis, *true* or *false*.
- ``setDisplayBlanksAs``. How to display null values, *zero*, *span*, *gap* (default).
Binary file added header-footer-images-test-result.docx
Binary file not shown.
35 changes: 35 additions & 0 deletions src/PhpWord/Style/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ class Chart extends AbstractStyle
*/
private $gridX = false;

/**
* How to display blank values (nulls) in series data.
* Options: 'gap' (break line), 'span' (connect line), 'zero' (plot as zero).
*
* @var string
*/
private $displayBlanksAs = 'gap'; // Default to gap

/**
* Create a new instance.
*
Expand Down Expand Up @@ -548,4 +556,31 @@ public function setShowGridX($value = true)

return $this;
}

/**
* Set display blanks as option.
*
* @param string $value 'gap', 'span', or 'zero'
*
* @return self
*/
public function setDisplayBlanksAs($value)
{
$validValues = ['gap', 'span', 'zero'];
if (in_array($value, $validValues)) {
$this->displayBlanksAs = $value;
}

return $this;
}

/**
* Get display blanks as option.
*
* @return string
*/
public function getDisplayBlanksAs()
{
return $this->displayBlanksAs;
}
}
26 changes: 20 additions & 6 deletions src/PhpWord/Writer/Word2007/Part/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,16 @@ private function writePlotArea(XMLWriter $xmlWriter): void
}

$xmlWriter->endElement(); // c:plotArea

$xmlWriter->startElement('c:plotVisOnly');
$xmlWriter->writeAttribute('val', '1');
$xmlWriter->endElement();

$displayBlanksAs = method_exists($style, 'getDisplayBlanksAs') ? $style->getDisplayBlanksAs() : 'gap';

$xmlWriter->startElement('c:dispBlanksAs');
$xmlWriter->writeAttribute('val', $displayBlanksAs);
$xmlWriter->endElement();
}

/**
Expand Down Expand Up @@ -314,13 +324,17 @@ private function writeSeriesItem(XMLWriter $xmlWriter, $type, $values): void
foreach ($values as $value) {
$xmlWriter->startElement('c:pt');
$xmlWriter->writeAttribute('idx', $index);
if (\PhpOffice\PhpWord\Settings::isOutputEscapingEnabled()) {
$xmlWriter->writeElement('c:v', $value);
} else {
$xmlWriter->startElement('c:v');
$xmlWriter->writeRaw($value);
$xmlWriter->endElement(); // c:v

if ($value !== null) {
if (\PhpOffice\PhpWord\Settings::isOutputEscapingEnabled()) {
$xmlWriter->writeElement('c:v', $value);
} else {
$xmlWriter->startElement('c:v');
$xmlWriter->writeRaw($value);
$xmlWriter->endElement(); // c:v
}
}

$xmlWriter->endElement(); // c:pt
++$index;
}
Expand Down
77 changes: 77 additions & 0 deletions tests/PhpWordTests/Writer/Word2007/Part/ChartNullHandlingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace PhpOffice\PhpWord\Tests\Writer\Word2007\Part;

use PhpOffice\PhpWord\Element\Chart;
use PhpOffice\PhpWord\Shared\XMLWriter;
use PhpOffice\PhpWord\Writer\Word2007\Part\Chart as ChartWriter;
use PHPUnit\Framework\TestCase;
use ReflectionClass;

class ChartNullHandlingTest extends TestCase
{
/**
* Test that the Style class correctly sets/gets the property.
*/
public function testSetGetDisplayBlanksAs(): void
{
// Note: Pass empty arrays for categories/values to avoid constructor errors
$chart = new Chart('line', [], []);
$style = $chart->getStyle();

// 1. Default should be 'gap'
self::assertEquals('gap', $style->getDisplayBlanksAs());

// 2. Test setting 'span'
$style->setDisplayBlanksAs('span');
self::assertEquals('span', $style->getDisplayBlanksAs());

// 3. Test invalid value (should remain 'span')
$style->setDisplayBlanksAs('invalid_option');
self::assertEquals('span', $style->getDisplayBlanksAs());
}

public function testWriteChartHandlesNullsAndGaps(): void
{
// 1. Setup Data
$categories = ['Jan', 'Feb', 'Mar'];
$values = [10, null, 20];
$seriesNames = ['My Series']; // <--- ADD THIS

// 2. Create Chart with Series Name
$chart = new Chart('line', $categories, $values, $seriesNames);
$chart->getStyle()->setDisplayBlanksAs('gap');

// 3. Setup Writer
$xmlWriter = new XMLWriter();
$chartWriter = new ChartWriter();

// Mock the parent writer
$chartWriter->setParentWriter($this->createMock(\PhpOffice\PhpWord\Writer\Word2007::class));

// 4. Inject Chart into Writer
$reflectionWriter = new ReflectionClass(ChartWriter::class);
$elementProperty = $reflectionWriter->getProperty('element');
$elementProperty->setAccessible(true);
$elementProperty->setValue($chartWriter, $chart);

// 5. Run
$method = $reflectionWriter->getMethod('writeChart');
$method->setAccessible(true);
$method->invokeArgs($chartWriter, [$xmlWriter]);

$xml = $xmlWriter->getData();

// --- ASSERTIONS ---
self::assertStringContainsString('<c:dispBlanksAs val="gap"/>', $xml);

// Check for the empty point (null value)
self::assertMatchesRegularExpression('/<c:pt idx="1"\s*\/?>/', $xml);

Check failure on line 69 in tests/PhpWordTests/Writer/Word2007/Part/ChartNullHandlingTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (7.2)

Call to an undefined static method PhpOffice\PhpWord\Tests\Writer\Word2007\Part\ChartNullHandlingTest::assertMatchesRegularExpression().

// Ensure no zero value was written for index 1
self::assertDoesNotMatchRegularExpression(

Check failure on line 72 in tests/PhpWordTests/Writer/Word2007/Part/ChartNullHandlingTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (7.2)

Call to an undefined static method PhpOffice\PhpWord\Tests\Writer\Word2007\Part\ChartNullHandlingTest::assertDoesNotMatchRegularExpression().
'/<c:pt idx="1"[^>]*>.*?<c:v>0<\/c:v>.*?<\/c:pt>/s',
$xml
);
}
}
Empty file.
Binary file added tests/PhpWordTests/_files/temp.epub
Binary file not shown.
Empty file added unknown.file
Empty file.
Loading