Charts
Charts: anatomy, keyboard behavior, state, and theming in Askr.
Example
import { createPlot } from '@askrjs/charts';
const Plot = createPlot<ProjectRow>();
<Plot.Root data={rows} rowKey="id" label="Revenue by day">
<Plot.Bar x="createdAt" y="revenue" />
<Plot.Line x="createdAt" y="target" />
</Plot.Root>Plot factory
Every chart starts with createPlot<Row>(), called once per row type at module scope. The call returns a stable, factory-bound namespace of primitives — Root, marks like Bar and Line, and interaction elements like Legend — all typed against Row. Primitives from one factory cannot be mixed into another factory's Root, and the row type drives which field names are valid on each channel.
Data and marks
A plot compiles its JSX children into one immutable scene, then paints that scene with a mounted Canvas 2D renderer. Root takes data (an array or a reactive getter), rowKey, and a required label; marks such as Bar, Line, Area, Point, Arc, Cell, Rect, Rule, and Text read channels off that data using plain field names, accessors, or expression helpers. Scales, axes, and tooltips are inferred from channel types unless you add explicit Scale, Axis, or Tooltip children.
View state and interaction
The visible x/y domains and the current row selection can be left uncontrolled with defaultView/defaultSelection, or fully controlled with view/onViewChange and selection/onSelectionChange. followLatest keeps a live plot scrolled to the newest rows until the viewer pans or zooms, at which point it pauses until PlotApi.resumeLive() is called. onActivate(row, key) is the drill-down hook for clicks and keyboard activation.
Production checklist
Import JavaScript from @askrjs/charts and the stylesheet separately from @askrjs/charts/styles — there's no components, core, or default entrypoint left to fall back on. Keep loading, error, and card chrome in the application; Root only owns plotting semantics, empty state, and summary text. Set meter on any bounded bar or arc used as a progress/gauge so the accessible value survives even when the canvas isn't rendered, and pass diagnostics during development to surface omitted-row warnings.