PhpSpreadsheet icon indicating copy to clipboard operation
PhpSpreadsheet copied to clipboard

Pie chart (2D) created as 3D

Open trane77 opened this issue 8 months ago • 5 comments

Hello,

I'm trying to create a 2D Pie chart, by following this example: 33_Chart_create_pie.php

Basically the generated chart is a 3D Pie:

Pie rendered as 3D

I've done a bit of reverse engineering and found the <c:view3d> tag in the generated XML, which leaded me to this line:

phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Chart.php:83

        if ($series->getPlotType() === DataSeries::TYPE_SURFACECHART) {
                    $surface2D = true;

                    break;
                }
        

So I did a quick test by changing the if condition to the following:

        if ($series->getPlotType() === DataSeries::TYPE_SURFACECHART || $series->getPlotType() === DataSeries::TYPE_PIECHART) {
                    $surface2D = true;

                    break;
                }
        

And the result now looks right: Pie wordking 2D

Unfortunately I can't send a PR as I don't know the codebase enough to know if this will break something else.

Cheers

trane77 avatar Mar 26 '25 15:03 trane77

The result from 33_Chart_Create_Pie looks correct to me without any code change:

Image

So something else must be at work here. Can you upload your code so that I can try to figure out what is causing the difference?

oleibman avatar Mar 26 '25 17:03 oleibman

Hello @oleibman,

Sure, I can share the code! Let me specify that I'm using Laravel-Excel, which in case you don't know, it's a wrapper around your library that makes things easier when working in Laravel projects.

  1. Data is added to the worksheet:
    public function array(): array
    {
        $this->rows = [
            [ '', 2010, 2011, 2012 ],
            [ 'Q1', 12, 15, 21 ],
            [ 'Q2', 56, 73, 86 ],
            [ 'Q3', 52, 61, 69 ],
            [ 'Q4', 30, 32, 0 ],
        ];

        return $this->rows;
    }
  1. Then I create the Pie Chart:
    /**
     * Add one or more Charts
     * @return Chart|Chart[]
     */
    public function charts()
    {
        return [ $this->makePieChart('D1', 'N25') ];
    }

    /**
     * @return \PhpOffice\PhpSpreadsheet\Chart\Chart
     */
    private function makePieChart(string $startCell, string $endCell, bool $withNameLabels = false)
    {
        $dataRowCount = count($this->rows)-1;

        // Set the Labels for each data series we want to plot
        $dataSeriesLabels = [
            new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010
        ];

        // Set the X-Axis Labels
        $xAxisTickValues = [
            new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, $dataRowCount), // Users names
        ];

        // Set the Data values for each data series we want to plot
        $dataSeriesValues = [
            new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, $dataRowCount), // Downloads No.
        ];

        // Build the dataseries
        $series1 = new DataSeries(
            DataSeries::TYPE_PIECHART, // plotType
            null, // plotGrouping (Pie charts don't have any grouping)
            range(0, count($dataSeriesValues) - 1),
            $dataSeriesLabels,
            $xAxisTickValues,
            $dataSeriesValues
        );

        // Set up a layout object for the Pie chart
        $layout1 = new Layout();
        $layout1->setShowVal(true);
        //$layout1->setShowPercent(true);
        if($withNameLabels) {
            $layout1->setShowCatName(true);
        }


        // Set the series in the plot area
        $plotArea1 = new PlotArea($layout1, [ $series1 ]);

        // Set the chart legend
        $legend1 = new Legend(Legend::POSITION_RIGHT, null, false);

        $title1 = new Title('Test Pie Chart');

        // Create the chart
        $chart = new Chart(
            'pie-chart-1', // name
            $title1, // title
            $legend1, // legend
            $plotArea1, // plotArea
            true, // plotVisibleOnly
            DataSeries::EMPTY_AS_GAP, // displayBlanksAs
            null, // xAxisLabel
            null   // yAxisLabel - Pie charts don't have a Y-Axis
        );

        // Set position in the worksheet
        $chart->setTopLeftPosition($startCell);
        $chart->setBottomRightPosition($endCell);

        return $chart;
    }

You know, I use ONLYOFFICE to replace MS Excel, I just tried to import the exported file in Google Sheets, and it rendered correctly.

What makes me think, is the fact that adding the condition mentioned in the issue description, fixes it. Also, if I download the XLS file from Google Sheets, then re-open it in ONLYOFFICE, it's showing up correctly.

If you want to do a comparison:

Let me know what do you think about it.

EDIT: switching the chart type to TYPE_DONUTCHART renders the chart in 2D as expected, it's an issue only with TYPE_PIECHART

trane77 avatar Mar 27 '25 09:03 trane77

So, the chart is displayed correctly in Excel and Google Docs, and I have just confirmed that it is displayed correctly in LibreOffice and Gnumeric as well. It sounds like you need to file a bug report with OnlyOffice.

oleibman avatar Mar 27 '25 16:03 oleibman

Nice, thanks for having checked @oleibman! I'll link this post in their issue ;-)

trane77 avatar Mar 28 '25 09:03 trane77