{"record":{"id":"8eb4ec6ec2690418","repo":"PHPOffice/PhpSpreadsheet","slug":"chart-renderer-must-implement-phpoffice-phpspreads","errorCode":null,"errorMessage":"Chart renderer must implement PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\IRenderer","messagePattern":"Chart renderer must implement PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\IRenderer","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Settings.php","lineNumber":56,"sourceCode":"    {\n        return Calculation::getInstance()->setLocale($locale);\n    }\n\n    public static function getLocale(): string\n    {\n        return Calculation::getInstance()->getLocale();\n    }\n\n    /**\n     * Identify to PhpSpreadsheet the external library to use for rendering charts.\n     *\n     * @param class-string<IRenderer> $rendererClassName Class name of the chart renderer\n     *    eg: PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\JpGraph\n     */\n    public static function setChartRenderer(string $rendererClassName): void\n    {\n        if (!is_a($rendererClassName, IRenderer::class, true)) {\n            throw new Exception('Chart renderer must implement ' . IRenderer::class);\n        }\n\n        self::$chartRenderer = $rendererClassName;\n    }\n\n    public static function unsetChartRenderer(): void\n    {\n        self::$chartRenderer = null;\n    }\n\n    /**\n     * Return the Chart Rendering Library that PhpSpreadsheet is currently configured to use.\n     *\n     * @return null|class-string<IRenderer> Class name of the chart renderer\n     *    eg: PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\JpGraph\n     */\n    public static function getChartRenderer(): ?string\n    {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Settings.php#L38-L74","documentation":"Settings::setChartRenderer() registers the class used to render charts; the guard is is_a($rendererClassName, IRenderer::class, true), so the string must name an existing class implementing Chart\\Renderer\\IRenderer. Note the bundled implementation Chart\\Renderer\\JpGraph additionally requires the jpgraph library to be installed, otherwise rendering later fails with a different error ('JpGraph Library not included').","triggerScenarios":"Settings::setChartRenderer('JpGraph') — wrong/missing namespace; a class name with a typo or not autoloadable (is_a returns false for nonexistent classes); a custom renderer that does not implement the IRenderer interface; passing an instance instead of a class-string is fine only if it implements IRenderer.","commonSituations":"First-time chart export setup without composer-requiring jpgraph; copying PHPExcel-era examples; renaming of renderer classes across major versions; test bootstrap left over from another project.","solutions":["Use the constant, not a literal: Settings::setChartRenderer(\\PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\JpGraph::class)","Install the dependency: composer require jpgraph/jpgraph, or call Settings::unsetChartRenderer() if charts are not needed","For custom renderers, implement every method of Chart\\Renderer\\IRenderer (render(), etc.) and reference the class via ClassName::class","Clear the renderer in test teardown to avoid leaking state between tests"],"exampleFix":"// before\n\\PhpOffice\\PhpSpreadsheet\\Settings::setChartRenderer('JpGraph'); // throws\n\n// after\n\\PhpOffice\\PhpSpreadsheet\\Settings::setChartRenderer(\n    \\PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\JpGraph::class\n); // + composer require jpgraph/jpgraph","handlingStrategy":"validation","validationCode":"use PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\IRenderer;\nuse PhpOffice\\PhpSpreadsheet\\Settings;\n\n$renderer = \\PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\JpGraph::class;\nif (is_a($renderer, IRenderer::class, true)) {\n    Settings::setChartRenderer($renderer);\n}","typeGuard":"function isValidRendererClass(string $class): bool\n{\n    return is_a($class, \\PhpOffice\\PhpSpreadsheet\\Chart\\Renderer\\IRenderer::class, true);\n}","tryCatchPattern":"try {\n    Settings::setChartRenderer($rendererClass);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    // fall back to exporting without rendered charts\n    Settings::unsetChartRenderer();\n}","preventionTips":["Reference renderers via ClassName::class, never string literals","composer require jpgraph/jpgraph when enabling the bundled renderer","Implement all IRenderer methods in custom renderers","unsetChartRenderer() in test teardown to avoid cross-test leakage"],"tags":["charts","renderer","configuration","dependency-missing"],"backgroundTag":"invalid-interface-implementation","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}