v5 modernizes the package for Chart.js 3 and 4, fixes several long-standing behavioral bugs, and adds support for real JavaScript callbacks in chart configs. Most code keeps working unchanged — read the upgrade guide before updating.
Breaking changes
- Chart.js 3.0+ is now required (4.x recommended).
beginAtZero()emits the modernoptions.scales.y.beginAtZerosyntax and merges into existing scales instead of replacing them. If you are still on Chart.js 2, stay on v4. toHtml()was rewritten. The signature is nowtoHtml(string $element, bool $uniqueId = true)— the second parameter disables the random id suffix; the old undocumented?Chartparameter is gone. Element names must match[A-Za-z][A-Za-z0-9_-]*or anInvalidArgumentExceptionis thrown. Cleanup listens topagehide(back/forward-cache aware) instead of the deprecatedunload, and re-rendering into the same id destroys the previous chart first.- Serialization shape. A chart whose
typewas never set omits"type"entirely (previously"type": null), andtoJson()encodes emptydata/optionsas{}the way Chart.js expects.toArray()/get()remain PHP-facing and still return arrays — always usetoJson()(orjson_encode($chart)) when feeding Chart.js. - Stricter magic setters. Calling an option setter with anything other than exactly one argument throws an
ArgumentCountError. Previously$options->responsive()silently assignedfalse. - Interfaces extend
\JsonSerializable. Third-party implementers ofChartInterface/ConfigInterfacemust add ajsonSerialize()method.
New
JsExpression(#47): wrap tooltip formatters, tick callbacks, and other scriptable options sotoJson()/toHtml()embed them as real JavaScript instead of dead strings. Only ever wrap code you wrote yourself — never user input.- Chart instances are registered in
window.bbsnlyChartJSInstancesfor access from your own JavaScript.
Fixed
toArray()no longer mutates the object graph — nestedDatasetobjects stay objects, even when references are held into the config.isset(),empty(), andunset()now work on magic config properties.- Reading a never-set property no longer leaks
"key": nullinto the output. - Cloning a chart or config no longer shares state with the original.
- The
composer testcommand documented in the README now exists (pluscomposer analyse).
Under the hood
- PHPStan at
level: maxoversrcandtests; 100% line coverage. - Generated JavaScript is now tested behaviorally: executed in Node against a DOM stub, including the callback and bfcache lifecycle paths.
- CI matrix covers PHP 8.1–8.5.