{"record":{"id":"0a7a30431be9c3f1","repo":"PHPOffice/PhpSpreadsheet","slug":"chart-is-not-yet-implemented","errorCode":null,"errorMessage":"Chart is not yet implemented","messagePattern":"Chart is not yet implemented","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Writer\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Writer/Xlsx/Chart.php","lineNumber":1115,"sourceCode":"    private static function getChartType(PlotArea $plotArea): array\n    {\n        $groupCount = $plotArea->getPlotGroupCount();\n\n        if ($groupCount == 1) {\n            $plotType = $plotArea->getPlotGroupByIndex(0)->getPlotType();\n            $chartType = ($plotType === null) ? [] : [$plotType];\n        } else {\n            $chartTypes = [];\n            for ($i = 0; $i < $groupCount; ++$i) {\n                $plotType = $plotArea->getPlotGroupByIndex($i)->getPlotType();\n                if ($plotType !== null) {\n                    $chartTypes[] = $plotType;\n                }\n            }\n            $chartType = array_unique($chartTypes);\n        }\n        if (count($chartType) == 0) {\n            throw new WriterException('Chart is not yet implemented');\n        }\n\n        return $chartType;\n    }\n\n    /**\n     * Method writing plot series values.\n     */\n    private function writePlotSeriesValuesElement(XMLWriter $objWriter, int $val, ?ChartColor $fillColor): void\n    {\n        if ($fillColor === null || !$fillColor->isUsable()) {\n            return;\n        }\n        $objWriter->startElement('c:dPt');\n\n        $objWriter->startElement('c:idx');\n        $objWriter->writeAttribute('val', \"$val\");\n        $objWriter->endElement(); // c:idx","sourceCodeStart":1097,"sourceCodeEnd":1133,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Writer/Xlsx/Chart.php#L1097-L1133","documentation":"When writing charts to Xlsx, the chart writer derives the chart-type list from the plot area: either the single plot group's type, or the unique types of all plot groups. If that list ends up empty - no DataSeries attached to the PlotArea, or every series having a null plot type - it throws this generic 'not yet implemented' message. It fires at save() time, after the chart was already added to a worksheet (and only when the writer includes charts).","triggerScenarios":"$chart = new Chart('chart'); $chart->setPlotArea(new PlotArea(null, [])); $sheet->addChart($chart); then ->save('out.xlsx') - zero plot groups yields an empty type list; also attaching only DataSeries objects whose plot type is null.","commonSituations":"Programmatically built charts where attaching the DataSeries was forgotten; charts whose series values come from a query that returned no data; editing a loaded chart and dropping its plot groups.","solutions":["Attach at least one DataSeries with an explicit plot type (e.g. DataSeries::TYPE_PIECHART) to the PlotArea before addChart()","Skip creating/adding the chart entirely when it would have no series","Guard data-driven charts: only addChart() when the series values are non-empty"],"exampleFix":"// before\n$chart = new Chart('chart1');\n$chart->setPlotArea(new PlotArea(null, []));\n$sheet->addChart($chart);\n\n// after\n$values = new DataSeriesValues('Number', 'Data!$B$2:$B$5', null, 4);\n$series = new DataSeries(DataSeries::TYPE_PIECHART, null, [0], [null], [null], [$values]);\n$chart = new Chart('chart1', new Title('Chart'), null, new PlotArea(null, [$series]));\n$sheet->addChart($chart);","handlingStrategy":"validation","validationCode":"/** Ensure every chart has at least one typed plot group before saving Xlsx. */\nfunction chartsAreWritable(Spreadsheet $spreadsheet): bool\n{\n    foreach ($spreadsheet->getAllSheets() as $sheet) {\n        foreach ($sheet->getChartCollection() as $chart) {\n            $groups = $chart->getPlotArea()?->getPlotGroup() ?? [];\n            $typed = array_filter($groups, fn ($g) => $g->getPlotType() !== null);\n            if (count($typed) === 0) {\n                return false;\n            }\n        }\n    }\n\n    return true;\n}\n\nif (!chartsAreWritable($spreadsheet)) {\n    // drop empty charts instead of failing the whole export\n    foreach ($spreadsheet->getAllSheets() as $sheet) {\n        // remove chart-less series charts per your model\n    }\n}\n$writer->setIncludeCharts(true);\n$writer->save('out.xlsx');","typeGuard":null,"tryCatchPattern":"try {\n    $writer->setIncludeCharts(true);\n    $writer->save('out.xlsx');\n} catch (\\PhpOffice\\PhpSpreadsheet\\Writer\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Chart is not yet implemented')) {\n        $writer->setIncludeCharts(false);\n        $writer->save('out-nocharts.xlsx'); // deliver data now, fix charts later\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Never addChart() without verifying the PlotArea holds a DataSeries with a non-null plot type","Build charts in one factory method that always constructs label/category/values DataSeriesValues together","Cover chart construction with a test that round-trips every generated chart through the Xlsx writer"],"tags":["phpspreadsheet","xlsx","chart","writer","empty-data"],"backgroundTag":"empty-chart-data","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}