Web

The web renderer

@hzblj/zyplot/web draws in the DOM. A plain @hzblj/zyplot import already resolves here on every target except React Native, so naming the subpath only matters in a project that has both. It is also the only entry point that carries Chart.Frame, Chart.Legend and a .Skeleton on every form — all three are DOM composition with no native counterpart. Chart.Provider exists on every entry point, but only here does it take colorMode and a className.

What draws what

Component names are the form, not the engine. Chart.Line and Chart.TimeSeries both draw a line — you pick between them on point count, never on renderer.

PropTypeDefaultDescription
EChartscanvasEighteen of the twenty-one forms, Line through Treemap. Series types are registered per chart file, so a page with one line chart does not ship the sankey, sunburst and boxplot code.
uPlotcanvasChart.TimeSeries and Chart.Sparkline. Tens of thousands of points, or forty sparklines in a table, where one scene graph per row would drop frames.
Plain DOMno engineChart.Meter is a filled track — two elements and no engine, so it is also the only form that needs no client boundary.

Text stays in the DOM

Only marks and axis ticks are painted into the canvas. The legend is React: every chart with two or more series renders one on its own, a single series never does, and the labels stay selectable, translatable and reachable by a screen reader.

Server components

Chart props stay serializable — no formatter callbacks, no render props — so a server component can render a chart without a client boundary of its own. Anything that would have been a callback is expressed as data instead, which is what ChartNumberFormat is for.

Colors are read off the document. A canvas takes color as a string, so each chart reads the resolved --zyplot-* values from the DOM after mounting and repaints when they change. Until that first read there is nothing honest to paint, so a chart shows its skeleton for a frame even with isLoading false.