diff --git a/docs/changes/1.x/1.5.0.md b/docs/changes/1.x/1.5.0.md index b96865bada..d2240e7ef1 100644 --- a/docs/changes/1.x/1.5.0.md +++ b/docs/changes/1.x/1.5.0.md @@ -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) @@ -16,4 +18,4 @@ ### BC Breaks -### Notes \ No newline at end of file +### Notes diff --git a/docs/usage/styles/chart.md b/docs/usage/styles/chart.md index f297718d24..99e4016136 100644 --- a/docs/usage/styles/chart.md +++ b/docs/usage/styles/chart.md @@ -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*. \ No newline at end of file +- ``gridY``. Show Gridlines for Y-Axis, *true* or *false*. +- ``setDisplayBlanksAs``. How to display null values, *zero*, *span*, *gap* (default). diff --git a/header-footer-images-test-result.docx b/header-footer-images-test-result.docx new file mode 100644 index 0000000000..a855345141 Binary files /dev/null and b/header-footer-images-test-result.docx differ diff --git a/src/PhpWord/Style/Chart.php b/src/PhpWord/Style/Chart.php index 3773565ce9..bb19d95999 100644 --- a/src/PhpWord/Style/Chart.php +++ b/src/PhpWord/Style/Chart.php @@ -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. * @@ -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; + } } diff --git a/src/PhpWord/Writer/Word2007/Part/Chart.php b/src/PhpWord/Writer/Word2007/Part/Chart.php index 65e686ebad..445c8272fc 100644 --- a/src/PhpWord/Writer/Word2007/Part/Chart.php +++ b/src/PhpWord/Writer/Word2007/Part/Chart.php @@ -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(); } /** @@ -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; } diff --git a/tests/PhpWordTests/Writer/Word2007/Part/ChartNullHandlingTest.php b/tests/PhpWordTests/Writer/Word2007/Part/ChartNullHandlingTest.php new file mode 100644 index 0000000000..cf8bbb7b77 --- /dev/null +++ b/tests/PhpWordTests/Writer/Word2007/Part/ChartNullHandlingTest.php @@ -0,0 +1,77 @@ +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('', $xml); + + // Check for the empty point (null value) + self::assertMatchesRegularExpression('//', $xml); + + // Ensure no zero value was written for index 1 + self::assertDoesNotMatchRegularExpression( + '/]*>.*?0<\/c:v>.*?<\/c:pt>/s', + $xml + ); + } +} diff --git a/tests/PhpWordTests/_files/tcpdf.pdf b/tests/PhpWordTests/_files/tcpdf.pdf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/PhpWordTests/_files/temp.epub b/tests/PhpWordTests/_files/temp.epub new file mode 100644 index 0000000000..f8d3b65aa6 Binary files /dev/null and b/tests/PhpWordTests/_files/temp.epub differ diff --git a/unknown.file b/unknown.file new file mode 100644 index 0000000000..e69de29bb2