Skip to content

Commit

Permalink
Additional Properties for Trendlines
Browse files Browse the repository at this point in the history
Fix PHPOffice#3011. Some properties for Trendlines were omitted in the original request for this feature. Also, the trendlines sample spreadsheet included two charts. The rendering script 35_Chart_render handles this, but overlays the first output file with the second. It is changed to produce files with different names.
  • Loading branch information
oleibman committed Aug 25, 2022
1 parent bb072d1 commit 39a21e0
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 6 deletions.
3 changes: 2 additions & 1 deletion samples/Chart/33_Chart_create_scatter5_trendlines.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
// 3- moving Avg (period=2) single-arrow trendline, w=1.5, same color as marker fill; no dispRSqr, no dispEq
$trendLines = [
new TrendLine(TrendLine::TRENDLINE_LINEAR, null, null, false, false),
new TrendLine(TrendLine::TRENDLINE_POLYNOMIAL, 3, null, true, true),
new TrendLine(TrendLine::TRENDLINE_POLYNOMIAL, 3, null, true, true, 20.0, 28.0, 44104.5, 'metric3 polynomial fit'),
new TrendLine(TrendLine::TRENDLINE_MOVING_AVG, null, 2, true),
];
$dataSeriesValues[0]->setTrendLines($trendLines);
Expand Down Expand Up @@ -263,6 +263,7 @@

// Add the chart to the worksheet $chartSheet
$chartSheet->addChart($chart);
$spreadsheet->setActiveSheetIndex(1);

// Save Excel 2007 file
$filename = $helper->getFilename(__FILE__);
Expand Down
3 changes: 3 additions & 0 deletions samples/Chart/35_Chart_render.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@
$helper->log(' ' . $chartName . ' - ' . $caption);

$jpegFile = $helper->getFilename('35-' . $inputFileNameShort, 'png');
if ($i !== 0) {
$jpegFile = substr($jpegFile, 0, -3) . "$i.png";
}
if (file_exists($jpegFile)) {
unlink($jpegFile);
}
Expand Down
Binary file modified samples/templates/32readwriteScatterChartTrendlines1.xlsx
Binary file not shown.
108 changes: 104 additions & 4 deletions src/PhpSpreadsheet/Chart/TrendLine.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,44 @@ class TrendLine extends Properties
/** @var bool */
private $dispEq = false;

/** @var string */
private $name = '';

/** @var float */
private $backward = 0.0;

/** @var float */
private $forward = 0.0;

/** @var float */
private $intercept = 0.0;

/**
* Create a new TrendLine object.
*/
public function __construct(string $trendLineType = '', ?int $order = null, ?int $period = null, bool $dispRSqr = false, bool $dispEq = false)
{
public function __construct(
string $trendLineType = '',
?int $order = null,
?int $period = null,
bool $dispRSqr = false,
bool $dispEq = false,
?float $backward = null,
?float $forward = null,
?float $intercept = null,
?string $name = null
) {
parent::__construct();
$this->setTrendLineProperties($trendLineType, $order, $period, $dispRSqr, $dispEq);
$this->setTrendLineProperties(
$trendLineType,
$order,
$period,
$dispRSqr,
$dispEq,
$backward,
$forward,
$intercept,
$name
);
}

public function getTrendLineType(): string
Expand Down Expand Up @@ -103,8 +134,65 @@ public function setDispEq(bool $dispEq): self
return $this;
}

public function setTrendLineProperties(?string $trendLineType = null, ?int $order = 0, ?int $period = 0, ?bool $dispRSqr = false, ?bool $dispEq = false): self
public function getName(): string
{
return $this->name;
}

public function setName(string $name): self
{
$this->name = $name;

return $this;
}

public function getBackward(): float
{
return $this->backward;
}

public function setBackward(float $backward): self
{
$this->backward = $backward;

return $this;
}

public function getForward(): float
{
return $this->forward;
}

public function setForward(float $forward): self
{
$this->forward = $forward;

return $this;
}

public function getIntercept(): float
{
return $this->intercept;
}

public function setIntercept(float $intercept): self
{
$this->intercept = $intercept;

return $this;
}

public function setTrendLineProperties(
?string $trendLineType = null,
?int $order = 0,
?int $period = 0,
?bool $dispRSqr = false,
?bool $dispEq = false,
?float $backward = null,
?float $forward = null,
?float $intercept = null,
?string $name = null
): self {
if (!empty($trendLineType)) {
$this->setTrendLineType($trendLineType);
}
Expand All @@ -120,6 +208,18 @@ public function setTrendLineProperties(?string $trendLineType = null, ?int $orde
if ($dispEq !== null) {
$this->setDispEq($dispEq);
}
if ($backward !== null) {
$this->setBackward($backward);
}
if ($forward !== null) {
$this->setForward($forward);
}
if ($intercept !== null) {
$this->setIntercept($intercept);
}
if ($name !== null) {
$this->setName($name);
}

return $this;
}
Expand Down
20 changes: 19 additions & 1 deletion src/PhpSpreadsheet/Reader/Xlsx/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,25 @@ private function chartDataSeries(SimpleXMLElement $chartDetail, string $plotType
$order = self::getAttribute($seriesDetail->order, 'val', 'integer');
/** @var ?int */
$period = self::getAttribute($seriesDetail->period, 'val', 'integer');
$trendLine->setTrendLineProperties($trendLineType, $order, $period, $dispRSqr, $dispEq);
/** @var ?float */
$forward = self::getAttribute($seriesDetail->forward, 'val', 'float');
/** @var ?float */
$backward = self::getAttribute($seriesDetail->backward, 'val', 'float');
/** @var ?float */
$intercept = self::getAttribute($seriesDetail->intercept, 'val', 'float');
/** @var ?string */
$name = (string) $seriesDetail->name;
$trendLine->setTrendLineProperties(
$trendLineType,
$order,
$period,
$dispRSqr,
$dispEq,
$backward,
$forward,
$intercept,
$name
);
$trendLines[] = $trendLine;

break;
Expand Down
24 changes: 24 additions & 0 deletions src/PhpSpreadsheet/Writer/Xlsx/Chart.php
Original file line number Diff line number Diff line change
Expand Up @@ -1132,10 +1132,19 @@ private function writePlotGroup(?DataSeries $plotGroup, string $groupType, XMLWr
$period = $trendLine->getPeriod();
$dispRSqr = $trendLine->getDispRSqr();
$dispEq = $trendLine->getDispEq();
$forward = $trendLine->getForward();
$backward = $trendLine->getBackward();
$intercept = $trendLine->getIntercept();
$name = $trendLine->getName();
$trendLineColor = $trendLine->getLineColor(); // ChartColor
$trendLineWidth = $trendLine->getLineStyleProperty('width');

$objWriter->startElement('c:trendline'); // N.B. lowercase 'ell'
if ($name !== '') {
$objWriter->startElement('c:name');
$objWriter->writeRawData($name);
$objWriter->endElement(); // c:name
}
$objWriter->startElement('c:spPr');

if (!$trendLineColor->isUsable()) {
Expand All @@ -1155,6 +1164,21 @@ private function writePlotGroup(?DataSeries $plotGroup, string $groupType, XMLWr
$objWriter->startElement('c:trendlineType'); // N.B lowercase 'ell'
$objWriter->writeAttribute('val', $trendLineType);
$objWriter->endElement(); // trendlineType
if ($backward !== 0.0) {
$objWriter->startElement('c:backward');
$objWriter->writeAttribute('val', "$backward");
$objWriter->endElement(); // c:backward
}
if ($forward !== 0.0) {
$objWriter->startElement('c:forward');
$objWriter->writeAttribute('val', "$forward");
$objWriter->endElement(); // c:forward
}
if ($intercept !== 0.0) {
$objWriter->startElement('c:intercept');
$objWriter->writeAttribute('val', "$intercept");
$objWriter->endElement(); // c:intercept
}
if ($trendLineType == TrendLine::TRENDLINE_POLYNOMIAL) {
$objWriter->startElement('c:order');
$objWriter->writeAttribute('val', $order);
Expand Down
12 changes: 12 additions & 0 deletions tests/PhpSpreadsheetTests/Chart/TrendLineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public function testTrendLine(): void
self::assertSame('accent4', $lineColor->getValue());
self::assertSame('stealth', $trendLine->getLineStyleProperty(['arrow', 'head', 'type']));
self::assertEquals(0.5, $trendLine->getLineStyleProperty('width'));
self::assertSame('', $trendLine->getName());
self::assertSame(0.0, $trendLine->getBackward());
self::assertSame(0.0, $trendLine->getForward());
self::assertSame(0.0, $trendLine->getIntercept());

$trendLine = $trendLines[1];
self::assertSame('poly', $trendLine->getTrendLineType());
Expand All @@ -82,6 +86,10 @@ public function testTrendLine(): void
self::assertSame('accent3', $lineColor->getValue());
self::assertNull($trendLine->getLineStyleProperty(['arrow', 'head', 'type']));
self::assertEquals(1.25, $trendLine->getLineStyleProperty('width'));
self::assertSame('metric3 polynomial', $trendLine->getName());
self::assertSame(20.0, $trendLine->getBackward());
self::assertSame(28.0, $trendLine->getForward());
self::assertSame(14400.5, $trendLine->getIntercept());

$trendLine = $trendLines[2];
self::assertSame('movingAvg', $trendLine->getTrendLineType());
Expand All @@ -91,6 +99,10 @@ public function testTrendLine(): void
self::assertSame('accent2', $lineColor->getValue());
self::assertNull($trendLine->getLineStyleProperty(['arrow', 'head', 'type']));
self::assertEquals(1.5, $trendLine->getLineStyleProperty('width'));
self::assertSame('', $trendLine->getName());
self::assertSame(0.0, $trendLine->getBackward());
self::assertSame(0.0, $trendLine->getForward());
self::assertSame(0.0, $trendLine->getIntercept());

$reloadedSpreadsheet->disconnectWorksheets();
}
Expand Down

0 comments on commit 39a21e0

Please sign in to comment.