Mantle Chart SVG Renderer Migration Guide
BarChart, LineChart, and AreaChart paint into an <svg> by default. The <canvas> with data-slot="bar-chart-canvas" (line-chart-canvas, area-chart-canvas) is gone from the default chart, and an <svg> with data-slot="bar-chart-svg" (line-chart-svg, area-chart-svg) takes its place. The marks, the axes, the hover layers, the tooltip, the description, and the data table are the same. ScatterPlot did not change, and still paints a <canvas>.
TL;DR: Find every selector and every test that reads a chart's <canvas> (canvas, [data-slot="bar-chart-canvas"], getContext("2d"), getImageData). Point a selector at [data-slot="bar-chart-svg"] instead. A test that reads canvas pixels reads the SVG's paths instead. Change nothing else.
Codemod
Codemod: manual: the change breaks CSS selectors and test queries, not JSX, and a rule cannot tell which chart a test reads pixels from.
You are an agent migrating a codebase. Do this:
- Find each CSS selector,
querySelector, and testing-library query that names a chart canvas:[data-slot="bar-chart-canvas"],[data-slot="line-chart-canvas"],[data-slot="area-chart-canvas"],[data-slot$="-chart-canvas"], or a barecanvasinside aBarChart.Root,LineChart.Root, orAreaChart.Root. Replace-chart-canvaswith-chart-svg, and a barecanvaswithsvg[data-slot$="-chart-svg"]. Leave ascatter-plot-canvasselector alone. - Find each test that waits for a chart to paint through its canvas, such as
canvas.width > 0. Wait for a path in the SVG instead:container.querySelector('[data-slot="bar-chart-svg"] path[d]'). - Find each test that reads a chart's pixels through
getContext("2d")orgetImageData. Read the SVG instead: each series paints one<path>, itsdattribute holds the geometry, and itsstyle.fillorstyle.strokeis the series color, such asvar(--color-chart-1). A browser test that must compare pixels takes a screenshot of the plot. - After editing, run the project's formatter, linter, type checker, and tests.
Why SVG? On a list of 100 cards with one small chart each, the SVG charts used less main-thread time than the canvas charts on mount, hover, resize, theme switch, and a data change, and they hold no bitmap memory. An SVG paints mantle's color tokens as CSS, so a theme switch repaints no chart. The SVG draws the same geometry as the canvas did: a browser test paints each scene both ways and compares the pixels.
Before → after
A selector on the chart surface
A test that waits for the paint
A test that reads canvas pixels
Edge cases & gotchas
- happy-dom lays out nothing, so no chart paints its marks in a happy-dom test. Assert the slots, roles, and text a happy-dom test can see, and read paint in a browser test.
- A consumer stylesheet that set
coloror a--color-chart-Noverride on the Root still works: the SVG reads both from the Root's cascade.
How to verify
Run the project's tests. Search the code for -chart-canvas and for getContext("2d") near a chart. Each match left must belong to a ScatterPlot.