chart-paint
Canvas painting helpers for the chart family — plot rect, grid, axis labels, line/area/bars, crosshair and drag selection, all theme-aware
Installation
- $npx litefy@latest add chart-paint
- $pnpm dlx litefy@latest add chart-paint
- $yarn dlx litefy@latest add chart-paint
- $bun --bun litefy@latest add chart-paint
Usage
chart-paint is the canvas layer under Chart: it turns a PlotFrame (the plot rectangle plus the visible data window) into pixels — grid, axis labels, line/area/bars, crosshair and the drag-selection box. Pair it with the chart-kit math layer, which computes the scales, ticks and downsampled points that these painters consume.
readThemeColor resolves a CSS custom property from document.documentElement with a fallback, so canvas strokes follow brand and dark-mode changes. A minimal draw pass:
import { computePlotRect, drawYAxisGrid, drawXAxisLabels, drawLineSeries, readThemeColor } from "@/utils/chart-paint";
function draw(ctx: CanvasRenderingContext2D, width: number, height: number, ticks: number[], points: Point[]) {
const frame = computePlotRect(ctx, ticks, width, height);
const textColor = readThemeColor("--color-muted-foreground", "#6b7280");
const gridColor = readThemeColor("--color-border", "#e5e7eb");
drawYAxisGrid(ctx, frame, ticks, textColor, gridColor);
drawXAxisLabels(ctx, frame, xLabels, textColor);
drawLineSeries(ctx, frame, points, { stroke: "var(--color-primary)", width: 1.5 });
}Chart is the reference implementation — its draw() shows the full pipeline (clip to the plot rect, bars first, then line/area series, crosshair and selection last).
API Reference
Helpers
| Member | Type | Description |
|---|---|---|
AXIS_FONT | string | Font used by axis label painters |
readThemeColor(name, fallback) | (name: string, fallback: string) => string | Resolve a CSS custom property with a fallback |
fillWith(ctx, color, alpha) | (ctx, color: string, alpha: number) => void | Set fillStyle with alpha |
strokeWith(ctx, color, alpha) | (ctx, color: string, alpha: number) => void | Set strokeStyle with alpha |
resetAlpha(ctx) | (ctx) => void | Reset globalAlpha to 1 |
computePlotRect(ctx, yTicks, width, height) | (ctx, yTicks: number[], width: number, height: number) => { left, top, width, height } | Measure the widest y-label and reserve it; returns the plot rectangle |
Painters
| Member | Description |
|---|---|
drawYAxisGrid(ctx, frame, yTicks, textColor, gridColor) | Horizontal grid lines with y-axis labels |
drawXAxisLabels(ctx, frame, xLabels, textColor) | X-axis labels; xLabels is { value, text }[] mapped through the frame scale |
drawBars(ctx, frame, xs, barSpecs, band) | Grouped bars; barSpecs is BarSeriesPaint[], band is the category width in px |
drawLineSeries(ctx, frame, points, options) | Line or area path; options is LineSeriesPaint (stroke, width, fill, fillAlpha) |
drawCrosshair(ctx, frame, crossX, dots, background, textColor) | Vertical hover line with per-series dots |
drawSelection(ctx, frame, startPx, endPx, color) | Drag-zoom selection overlay between two x pixels |
Types
| Type | Fields |
|---|---|
PlotFrame | left, top, plotWidth, plotHeight, xMin, xMax, yMin, yMax, i0, i1 (visible data window) |
BarSeriesPaint | values: number[], fill: string, alpha: number |
LineSeriesPaint | stroke: string, width: number, fill?: string, fillAlpha: number |