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

Add Trendline for Xlsx Charts - Revised complete solution and samples included #2815

Closed
bridgeplayr opened this issue May 9, 2022 · 0 comments · Fixed by #2976
Closed

Add Trendline for Xlsx Charts - Revised complete solution and samples included #2815

bridgeplayr opened this issue May 9, 2022 · 0 comments · Fixed by #2976
Labels

Comments

@bridgeplayr
Copy link

bridgeplayr commented May 9, 2022

  1. Create new class PhpSpeadSheet/Chart/TrendLine.php

TrendLine.php.txt
(remove ".txt")

  1. Modify PhpSpeadSheet/Chart/DataSeriesValues.php
  • add
    use PhpOffice\PhpSpreadsheet\Chart\TrendLine;

  • add to the list of properties (note original suggestion of scalar $trendLine is replaced by array $trendLines[] because Excel supports up to 3 trend lines for each DataSeriesValues dataset

    /** @var array of Trendlines*/
    private $trendLines = [];
  • add getter/setter methods
    public function setTrendLines($trendLines): self
    {
        $this->trendLines = $trendLines;

        return $this;
    }

    public function getTrendLines($indx = null)
    {
        if (is_numeric($indx)) {
            return $this->trendLines[$indx]; // return one trendLine
        } else { 
            return $this->trendLines; // return the array if no indx provided
      }

        return $this;

    }

  1. Modify PhpSpeadSheet/Writer/Xlsx/Chart.php
  • add
    use PhpOffice\PhpSpreadsheet\Chart\TrendLine;

  • following existing code

//    Formatting for the points (markers)
    ...
            if (($groupType === DataSeries::TYPE_BARCHART) || ($groupType === DataSeries::TYPE_BARCHART_3D) || ($groupType === DataSeries::TYPE_BUBBLECHART)) {
                $objWriter->startElement('c:invertIfNegative');
                $objWriter->writeAttribute('val', 0);
                $objWriter->endElement();
            }

  • add
            // Trendlines
            $trendLines = $plotSeriesValues->getTrendLines(); // returns array
            if ($trendLines) {
                $trendLineCount = count($trendLines);
                for ($i=0; $i<$trendLineCount; $i++) {
                    $trendLine = $plotSeriesValues->getTrendLines($i);

                    $trendLineType  = $trendLine->getTrendLineType();
                    $order          = $trendLine->getOrder(); 
                    $period         = $trendLine->getPeriod(); 
                    $dispRSqr       = $trendLine->getDispRSqr(); 
                    $dispEq         = $trendLine->getDispEq(); 
                    $trendLineColor = $trendLine->getLineColor(); // ChartColor
                    $trendLineWidth = $trendLine->getLineStyleProperty('width');
            
                    $objWriter->startElement('c:trendline'); // N.B. lowercase 'ell'
                    $objWriter->startElement('c:spPr');

                    if ($trendLineColor == null)
                    {   // use dataSeriesValues line color as a backup if $trendLineColor is null
                        $dsvLineColor = $plotSeriesValues->getLineColor();
                        if ($dsvLineColor) { 
                            $trendLine->getLineColor()
                                      ->setColorProperties($dsvLineColor['value'],$dsvLineColor['alpha'],$dsvLineColor['type']);
                        }
                    } // otherwise, hope Excel does the right thing
            
                    $this->writeLineStyles($objWriter, $trendLine, false); // suppress noFill
            
                    $objWriter->endElement(); // spPr
            
                    $objWriter->startElement('c:trendlineType'); // N.B lowercase 'ell'
                    $objWriter->writeAttribute('val', $trendLineType);
                    $objWriter->endElement(); // trendlineType
                    if ($trendLineType == 'poly')
                    {   $objWriter->startElement('c:order');
                        $objWriter->writeAttribute('val', $order);
                        $objWriter->endElement(); // order
                    }
                    if ($trendLineType == 'movingAvg') 
                    {
                        $objWriter->startElement('c:period');
                        $objWriter->writeAttribute('val', $period);
                        $objWriter->endElement(); // period
                    }
                    $objWriter->startElement('c:dispRSqr');
                    $objWriter->writeAttribute('val', (int) $dispRSqr);
                    $objWriter->endElement();
                    $objWriter->startElement('c:dispEq');
                    $objWriter->writeAttribute('val', (int) $dispEq);
                    $objWriter->endElement();  
                    if ($groupType === DataSeries::TYPE_SCATTERCHART || $groupType === DataSeries::TYPE_LINECHART )
                    {
                        $objWriter->startElement('c:trendlineLbl');
                        $objWriter->startElement('c:numFmt');
                        $objWriter->writeAttribute('formatCode', (string) 'General');
                        $objWriter->writeAttribute('sourceLinked', (int) 0);
                        $objWriter->endElement();  // numFmt
                        $objWriter->endElement();  // trendlineLbl
                    }
            
                    $objWriter->endElement(); // trendline
                }
            }

  1. Add chart creator code samples\Chart\33_Chart_create_scatter_trendline.php
    33_scatter_w_trendlines.php.txt (remove .txt and edit file to match PHPSS file naming and saving conventions)
  • I added more datapoints to the data table.
  • I added a separate worksheet for the charts.
  • I created two charts; the first with 3 DSVs and no trend lines; the second with only 1 DSV, but with 3 different Trend Lines to demonstrate different 'fits'. R squared and equations are displayed.
  • I add Marker, Marker Color and Marker Size in each instantiation of the DataSeriesValues to reduce the method calls, if only slightly.
  1. Add template Xlsx chart produced by above sample:
    33_Chart_create_scatter_trendlines.xlsx
@oleibman oleibman added the charts label May 9, 2022
@bridgeplayr bridgeplayr changed the title Add Trendline for Xlsx Charts Add Trendline for Xlsx Charts - Revised complete solution and samples included Jul 8, 2022
oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Aug 1, 2022
oleibman added a commit that referenced this issue Aug 7, 2022
Fix #2968. Fix #2815. Solution largely based on suggestions by @bridgeplayr.
MarkBaker added a commit that referenced this issue Sep 25, 2022
### Added

- Implementation of the new `TEXTBEFORE()`, `TEXTAFTER()` and `TEXTSPLIT()` Excel Functions
- Implementation of the `ARRAYTOTEXT()` and `VALUETOTEXT()` Excel Functions
- Support for [mitoteam/jpgraph](https://packagist.org/packages/mitoteam/jpgraph) implementation of
  JpGraph library to render charts added.
- Charts: Add Gradients, Transparency, Hidden Axes, Rounded Corners, Trendlines, Date Axes.

### Changed

- Allow variant behaviour when merging cells [Issue #3065](#3065)
  - Merge methods now allow an additional `$behaviour` argument. Permitted values are:
    - Worksheet::MERGE_CELL_CONTENT_EMPTY - Empty the content of the hidden cells (the default behaviour)
    - Worksheet::MERGE_CELL_CONTENT_HIDE - Keep the content of the hidden cells
    - Worksheet::MERGE_CELL_CONTENT_MERGE - Move the content of the hidden cells into the first cell

### Deprecated

- Axis getLineProperty deprecated in favor of getLineColorProperty.
- Moved majorGridlines and minorGridlines from Chart to Axis. Setting either in Chart constructor or through Chart methods, or getting either using Chart methods is deprecated.
- Chart::EXCEL_COLOR_TYPE_* copied from Properties to ChartColor; use in Properties is deprecated.
- ChartColor::EXCEL_COLOR_TYPE_ARGB deprecated in favor of EXCEL_COLOR_TYPE_RGB ("A" component was never allowed).
- Misspelled Properties::LINE_STYLE_DASH_SQUERE_DOT deprecated in favor of LINE_STYLE_DASH_SQUARE_DOT.
- Clone not permitted for Spreadsheet. Spreadsheet->copy() can be used instead.

### Removed

- Nothing

### Fixed

- Fix update to defined names when inserting/deleting rows/columns [Issue #3076](#3076) [PR #3077](#3077)
- Fix DataValidation sqRef when inserting/deleting rows/columns [Issue #3056](#3056) [PR #3074](#3074)
- Named ranges not usable as anchors in OFFSET function [Issue #3013](#3013)
- Fully flatten an array [Issue #2955](#2955) [PR #2956](#2956)
- cellExists() and getCell() methods should support UTF-8 named cells [Issue #2987](#2987) [PR #2988](#2988)
- Spreadsheet copy fixed, clone disabled. [PR #2951](#2951)
- Fix PDF problems with text rotation and paper size. [Issue #1747](#1747) [Issue #1713](#1713) [PR #2960](#2960)
- Limited support for chart titles as formulas [Issue #2965](#2965) [Issue #749](#749) [PR #2971](#2971)
- Add Gradients, Transparency, and Hidden Axes to Chart [Issue #2257](#2257) [Issue #2229](#2929) [Issue #2935](#2935) [PR #2950](#2950)
- Chart Support for Rounded Corners and Trendlines [Issue #2968](#2968) [Issue #2815](#2815) [PR #2976](#2976)
- Add setName Method for Chart [Issue #2991](#2991) [PR #3001](#3001)
- Eliminate partial dependency on php-intl in StringHelper [Issue #2982](#2982) [PR #2994](#2994)
- Minor changes for Pdf [Issue #2999](#2999) [PR #3002](#3002) [PR #3006](#3006)
- Html/Pdf Do net set background color for cells using (default) nofill [PR #3016](#3016)
- Add support for Date Axis to Chart [Issue #2967](#2967) [PR #3018](#3018)
- Reconcile Differences Between Css and Excel for Cell Alignment [PR #3048](#3048)
- R1C1 Format Internationalization and Better Support for Relative Offsets [Issue #1704](#1704) [PR #3052](#3052)
- Minor Fix for Percentage Formatting [Issue #1929](#1929) [PR #3053](#3053)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

2 participants