Live Data and View State
Live Data and View State: anatomy, keyboard behavior, state, and theming in Askr.
Example
import { state } from '@askrjs/askr';
import { createPlot, type PlotView } from '@askrjs/charts';
const Plot = createPlot<MetricRow>();
function LiveLatency() {
const [view, setView] = state<PlotView>({});
return <Plot.Root
data={rows()}
rowKey="id"
label="Live latency"
view={view()}
onViewChange={setView}
followLatest={{ durationMs: 300_000, field: 'timestamp' }}
><Plot.Line x="timestamp" y="latencyMs" /></Plot.Root>;
}Append and upsert
`appendPlotRows(rows, additions)` adds one or many rows to the end of an array without mutating the original. `upsertPlotRows(rows, updates, rowKey)` replaces any row whose key matches an update and appends the rest, and rejects duplicate keys within the update batch itself — both return a frozen result, or the original array when nothing actually changed.
Trim rows
`trimPlotRows(rows, options)` keeps a live array from growing without bound. Pass a plain number (or `{ rows: N }`) to retain the latest N rows by position, or `{ durationMs, field, now? }` to retain only rows whose `Date` field falls within a trailing time window — the natural pairing for a plot that's also using `followLatest`.
Follow latest
`Root`'s `followLatest` prop accepts a bare number as row-count shorthand, `{ rows: N }`, or `{ durationMs, field }` for a time-based window, and keeps the visible view pinned to the newest data as it arrives. Any user pan or zoom pauses following immediately, and it stays paused — even as more rows come in — until the app calls `PlotApi.resumeLive()`, so an operator inspecting an anomaly is never yanked back to "now" mid-investigation.
Controlled view
`PlotView` holds optional `x` and `y` domain tuples plus a `scales` map for named coordinate scales; `x`/`y` are shorthand aliases for the primary scales, and an entry in `scales` takes precedence for that specific scale. Use `defaultView` when the view can live entirely inside the plot, or `view` together with `onViewChange` when a URL, route, or sibling control needs to own and synchronize the visible domain.