@c2n/chart
v0.0.17
Published
Line, area, bar, sparkline, pie, gauge, scatter and candlestick charts as custom elements, from one package.
Downloads
1,148
Maintainers
Readme
@c2n/chart
Line, area, bar, sparkline, pie, gauge, scatter and candlestick charts as custom elements, from one package.
npm install @c2n/chart uplot # line, area, bar, sparkline
npm install @c2n/chart echarts # pie, gauge, scatter, candlestick<c2-line-chart
x-field="year"
data='[{"year":2022,"nuclear":294.73,"wind":38.2,"solar":19.34},{"year":2023,"nuclear":338.2,"wind":50.48,"solar":22.59},{"year":2024,"nuclear":380.45,"wind":45.43,"solar":24.87}]'
>
<c2-chart-series field="nuclear" label="Nuclear"></c2-chart-series>
<c2-chart-series field="wind" label="Wind"></c2-chart-series>
<c2-chart-series field="solar" label="Solar"></c2-chart-series>
</c2-line-chart>import '@c2n/chart/line-chart.js' // one tag
import '@c2n/chart' // all of themElements
| Tag | Engine | For |
| ---------------------- | ------- | ----------------------------------------------- |
| c2-line-chart | uPlot | Time or numeric trends |
| c2-area-chart | uPlot | The same, with the region under the line filled |
| c2-bar-chart | uPlot | Categorical or time-bucketed values |
| c2-sparkline | uPlot | A chromeless trend for a table cell or KPI row |
| c2-pie-chart | ECharts | Parts of a whole, with a donut mode |
| c2-gauge-chart | ECharts | A bounded current value or target |
| c2-scatter-chart | ECharts | Relationships, clusters and outliers |
| c2-candlestick-chart | ECharts | Open-high-low-close financial sessions |
| c2-chart-series | — | A series definition; renders nothing |
| c2-chart-legend | — | A linked legend placed anywhere in the layout |
| c2-chart-tooltip | — | A linked floating or inline tooltip |
Independent legend and tooltip
The chart renders built-in chrome by default. To own its layout, link companion elements to the chart by id; each companion automatically replaces its corresponding built-in display:
<c2-line-chart id="sales" data="..."></c2-line-chart>
<c2-chart-legend for="sales"></c2-chart-legend>
<c2-chart-tooltip for="sales"></c2-chart-tooltip>The legend occupies its normal HTML position. The tooltip floats beside the hovered point by default and
flips at viewport edges; position="inline" makes it occupy its authored position. Assign renderLegend,
renderLegendItem or renderTooltip for data-driven custom Lit templates.
The chart's built-in tooltip also renders in the browser's top layer. It remains in the chart's shadow tree
for slots, parts and CSS-variable inheritance, but it is not clipped by the plot or an overflow: hidden
ancestor.
Engines
Both libraries are optional peer dependencies loaded through a dynamic import() on first paint, so
nothing is bundled into the package and a page that only shows a sparkline never downloads ECharts. Install
whichever engines your charts need.
Data
data accepts row objects, a bare number[], columnar [xs, ys…], or an already-normalised frame.
Internally everything becomes one columnar frame of Float64Arrays, which is the shape uPlot draws
natively and what makes appending O(1).
The documentation examples share a France 2015–2024 extract from the public Our World in Data Energy dataset, measured in terawatt-hours. Line, area, bar, scatter and sparkline charts read the annual rows directly; radial charts derive a focused metric or one slice per energy source from a selected year. Candlesticks use public OHLC observations.
chart.data = rows // full replace
chart.revision++ // after mutating the array in place
chart.appendPoint(x, [a, b]) // one realtime tickdata is compared by identity, never deep-diffed. A change to data or revision alone is pushed
straight into the engine — Lit does not render, and the canvas container is not touched — so a streaming
tick costs one engine redraw and nothing else. Anything else counts as presentation and rebuilds the engine
options. Use max-points to keep a bounded window.
For a lazy or streaming source, set dataSource instead: getWindow() is the pull half, and an optional
subscribe() feeds ticks straight into the append path.
Sizing
A canvas has no intrinsic size, so a chart is sized by its host: --c2-chart--height (320px, or 32px on a
sparkline) plus whatever width the layout gives it. A ResizeObserver keeps the canvas in step, and the
plot box is contain: strict so a resize cannot feed back into itself.
Theming
Every element shares the --c2-chart__* namespace, so theming once themes them all. The palette is
--c2-chart__series-1--color … --c2-chart__series-8--color, wired by @c2n/theme to the
--c2-theme--chart-series-* tokens, which carry light and dark values.
Because the plot is a canvas, these variables are resolved with getComputedStyle and handed to the
engine. They behave like any other CSS variable — including under a dark theme, which the element watches
for — but the marks cannot be reached with ::part(). The chrome around the plot (legend, tooltip, state
messages) is ordinary DOM and does expose parts.
Events
chart-ready, chart-error, point-click, point-hover, range-change, series-toggle, legend-change
and tooltip-change. The
semantic ones do not bubble: several components fire similarly named events, so a listener belongs on the
element itself. The host also carries data-chart-ready once the first frame is drawn, which is the
signal to wait on in a test.
