Export
Export: anatomy, keyboard behavior, state, and theming in Askr.
Example
import { state } from '@askrjs/askr';
import { createPlot, type PlotApi } from '@askrjs/charts';
const Plot = createPlot<ProjectRow>();
function ExportableRevenue() {
const [api, setApi] = state<PlotApi<ProjectRow> | null>(null);
return <>
<Plot.Root data={rows} rowKey="id" label="Revenue" onApiChange={setApi}>
<Plot.Line x="createdAt" y="revenue" />
</Plot.Root>
<button type="button" onClick={() => download(api()?.exportSvg() ?? '', 'revenue.svg')}>Export SVG</button>
</>;
}Data export
`PlotApi.exportData(options?)` returns a string shaped by `view` (`current`/`full`), `rows` (`source`/`transformed`), `scope` (`all`/`visible`/`selected`), and `format` (`csv`/`json`). CSV output neutralizes cells that spreadsheet applications would otherwise interpret as formulas; JSON output serializes dates as ISO strings and represents non-finite numbers as `null` rather than silently dropping them.
SVG export
`PlotApi.exportSvg(options?)` renders the resolved scene as an SVG string — it's purely an export format, not a mounted renderer and not a graphical SSR fallback. It requires a mounted plot with resolved dimensions, references fonts by name instead of embedding them, and by default excludes transient overlays like hover, crosshair, and brush state via `includeOverlays`.
PNG export
`PlotApi.exportPng(options?)` returns a `Promise<Blob>` rasterized from the same resolved scene, with a `pixelRatio` option for high-density output and the same `includeOverlays` toggle as SVG export. Like SVG export, it needs an already-mounted plot — there's nothing to rasterize before the canvas has resolved dimensions.
View selection
PNG, SVG, and data export all share the same `view: "current" | "full"` option: `current` captures exactly what's visible after any pan or zoom, while `full` captures the entire domain regardless of what the viewer has scrolled to. Picking the right one matters — a support screenshot usually wants `current`, while a downstream data pipeline usually wants `full`.