function withOptions<TOptions>(plugin: ChartPlugin<TOptions>, options: TOptions): PluginWithOptions<TOptions>Pairs a plugin with its options for a chart's plugins, and checks the options against the plugin's options type. install receives them as its second argument.
Parameters
pluginChartPlugin<TOptions>optionsTOptions
Example
import { lineChart, withOptions, type ChartPlugin } from 'chartist';
const lastPoint: ChartPlugin<{ className: string }> = {
name: 'last-point',
install(chart, options) {
chart.on('compose', current => {
if (current.role !== 'series') {
return;
}
const last = current.children.at(-1);
return last && options
? current.replace(last, last.addClass(options.className))
: undefined;
});
}
};
lineChart(
'#chart',
{ series: [[1, 3, 2, 5]] },
{ plugins: [withOptions(lastPoint, { className: 'ct-last' })] }
);interface ChartEventsThe custom events a chart can emit, by name, with their payloads. The core emits only responsive. A plugin that emits events of its own declares them here (TypeScript merges your declaration into Chartist's), so on(), off() and emit() check the names and payloads:
ts
declare module 'chartist' {
interface ChartEvents {
'legend:click': { readonly seriesIndex: number };
}
}
chartist/compat declares the 1.x events (draw, created, …).
Properties
responsive{ readonly previousConfig: ChartConfig; readonly currentConfig: ChartConfig } | { readonly previousOptions: unknown; readonly currentOptions: unknown }Responsive entries changed which overrides apply: the config before and after (
chart()), or the options before and after (presets).dataDataEvent1.x: the chart's data, before the first render (
type: 'initial') and after an update with new data (type: 'update'). Listeners can change it in place. Needs thecompatplugin.optionsChangedOptionsChangedEvent1.x: the responsive options changed, with the options before and after. Needs the
compatplugin.drawPointDrawEvent | LineDrawEvent | AreaDrawEvent | AxesDrawEvent | BarDrawEvent | SliceDrawEvent | SliceLabelDrawEvent1.x: an element was drawn: a grid line, label, point, line, area, bar or slice, with its live
element. Checktypeto narrow it. Needs thecompatplugin.createdLineChartCreatedEvent | BarChartCreatedEvent | PieChartCreatedEvent1.x: the chart is drawn and in the DOM, after its
drawevents, with thesvg, the chart area and the axes. Needs thecompatplugin.animationBeginAnimationEvent1.x: an SMIL animation began, started with
animate()on an element of the chart, such as theelementof adrawevent. Needs thecompatplugin.animationEndAnimationEvent1.x: an SMIL animation ended, started with
animate()on an element of the chart. Needs thecompatplugin.
type CustomEventName = keyof ChartEvents & stringThe name of a custom event: a key of ChartEvents. Plugins list the names they emit in provides.
interface ChartPlugin<TOptions = unknown>A plugin: a name and an install function that registers listeners on the chart. Plugins go into plugins, in the config of chart or the options of the presets. They install in order, so with two listeners on the same event, the earlier plugin's runs first.
For options, write a function that takes them and returns the plugin, or read them from the second argument of install and pass the plugin with withOptions.
Properties
readonly namestringNames the plugin. Prefix your custom events with it to keep them apart.
readonly provides?readonly CustomEventName[]The custom events this plugin emits with
chart.emit(), each declared inChartEvents. They're known before any plugin installs, so another plugin may listen to them.install(chart: ChartHandle, options?: TOptions) => unknownSets the plugin up: runs once, before the first render, with the chart's handle. Listeners registered here stay for every later render, after updates and resizes too, and
off(name)without a listener leaves them alone: remove one with its reference.Return a function to undo what
installset up outside the chart, such as a listener on the document:destroy()calls it once, after the chart's output is removed.detach()doesn't.keyframes?(previous: SceneNode, next: SceneNode, progress: readonly number[]) => Keyframes | undefinedGives the keyframes of a node's update animation, for nodes that don't move well number by number, such as a path the plugin draws. A renderer that animates updates (
smilAnimations()fromchartist/live) asks it once per update, never per frame, with the progress points of the chart's easing: 0 is the previous node, 1 the new one, and points beyond them come from an easing that overshoots. Plugins are asked in their order, before the layer that drew the node; the first one that returns keyframes wins.
Example
import { barChart, type ChartPlugin } from 'chartist';
// Bars at or above the limit get the class ct-over.
const threshold = (limit: number): ChartPlugin => ({
name: 'threshold',
install(chart) {
chart.on('compose', current => {
if (current.role !== 'bar') {
return;
}
const { value } = current.ctx;
const y =
typeof value === 'number'
? value
: value && 'y' in value
? value.y
: undefined;
return y !== undefined && y >= limit
? current.addClass('ct-over')
: undefined;
});
}
});
barChart('#chart', { series: [[5, 4, 3, 7]] }, { plugins: [threshold(5)] });type PluginWithOptions<TOptions = unknown> = readonly [ChartPlugin<TOptions>, TOptions]A plugin paired with its options, as withOptions creates it. install receives the options as its second argument.
type PluginEntry = ChartPlugin<any> | PluginWithOptions<any>An entry of a chart's plugins: a plugin, or a plugin with its options. Prefer withOptions (it checks the options) or a function that returns a plugin over a bare [plugin, options] pair. A 1.x plugin (a plain function) throws; convert it with fromLegacyPlugin() from chartist/compat.
interface ChartDataChart data as passed to chart() or toScene().
Properties
readonly labels?readonly (string | number | Date)[]The labels of the values, e.g. for the X axis or the slices.
readonly seriesreadonly unknown[]The series: arrays of values, series objects with
data, or, for a pie, one value per slice.
interface PreparedSeriesOne series after the prepare phase.
Properties
readonly name?stringThe series'
name, from a series object.readonly className?stringThe series'
className, from a series object.readonly meta?unknownThe series'
meta, from a series object.readonly valuesreadonly unknown[]The series' values, as given.
interface PreparedDataThe data after the prepare phase: every series as a PreparedSeries, whether it was given as an array or an object.
Properties
readonly labelsreadonly (string | number | Date)[]The labels as given, or an empty array.
readonly seriesreadonly PreparedSeries[]The series, each with its
values.readonly flat?booleanThe input was a flat series (e.g. pie or distributed bar data).
interface AreaThe drawing area inside the padding (and the axes), in px in the SVG. y1 is the bottom edge, as in 1.x.
Properties
readonly x1numberThe left edge.
readonly y1numberThe bottom edge.
readonly x2numberThe right edge.
readonly y2numberThe top edge.
readonly widthnumberThe area's width in px.
readonly heightnumberThe area's height in px.
interface LayoutThe payload of the layout phase: the chart's size and the drawing area inside its padding and axes. A layout listener can return a changed layout, e.g. to make room for a legend.
Properties
readonly widthnumberThe chart's width in px (at least the left and right padding).
readonly heightnumberThe chart's height in px (at least the top and bottom padding).
readonly paddingChartPaddingThe padding around the drawing area, in px.
readonly areaAreaWhere the layers draw, inside the padding and the axes.
readonly inset?ChartPaddingThe room layers reserved outside the drawing area with
Layer.inset, in px per side;paddingincludes it. Absent when no layer reserved room.
interface NormalizedChartDataData normalized for axes: multi values ({ x, y }), padded labels.
Properties
readonly labelsreadonly Label[]The labels, padded with empty strings to the longest series.
readonly seriesreadonly NormalizedSeries[]The series' values as numbers,
{ x, y }values or holes, each series padded with holes to the longest one.
interface InsetContextWhat a layer's inset gets: the chart's size and padding, its axes, the layer's series and ways to measure text and styles, so it can size the room it needs.
Properties
readonly widthnumberThe chart's width in px.
readonly heightnumberThe chart's height in px.
readonly paddingChartPaddingThe chart's padding option, in px, without any reserved room.
readonly dataPreparedDataThe prepared data; only the layer's series when it selects some.
readonly axesreadonly AxisDefinition[]The chart's axis definitions, with their ids, sides and offsets; empty without axes.
readonly coordinatesCoordinatesThe chart's coordinate system.
readonly layerIndexnumberThe layer's index in the chart's
layers.readonly labelsLabelModeHow label layers draw labels: chart option, else the renderer's.
readonly measureTextMeasureTextMeasures text with the renderer's metrics (in the browser, with the page's fonts and the chart's classes).
readonly measureStyle?MeasureStyleReads computed styles with the renderer. Absent without a DOM.
interface ResolvedConfigOptions after the resolve phase: defaults applied, listeners removed.
Properties
readonly dataChartDataThe chart's data, as given.
readonly layersreadonly Layer[]The layers, drawn in this order.
readonly coordinatesCoordinatesThe coordinate system;
cartesianunless the config says otherwise.readonly paddingChartPaddingThe padding in px on every side, the 1.x defaults filled in.
readonly axes?CartesianAxesThe chart's axes, from
cartesianAxes(), if it has any.readonly width?string | numberThe root svg's
widthfrom the config, e.g.100%or600.readonly height?string | numberThe root svg's
heightfrom the config, e.g.300px.readonly viewBox?{ readonly width: number; readonly height: number }Fixed drawing coordinates for the root svg's
viewBox, in px.readonly className?stringClass names of the root svg, e.g.
ct-chart-line.readonly labels?LabelModeLabel mode for all label layers; else the renderer decides.
readonly preset?LinePresetState | BarPresetState | PiePresetStateThe preset that created the chart, if any: its kind, options and data. Check
kindto narrow it, e.g.config.preset?.kind === 'line'.
interface PhaseEventsThe payloads of the phase events, by phase, in the order the phases run. Listen with on in the config of chart(), chart.on() or a plugin. A listener can return a new payload to change the phase (see PhaseResult); later phases build on the change.
When the container resizes, the chart runs again from layout, so resolve and prepare listeners aren't called.
Properties
resolve{ readonly config: ResolvedConfig }The config with defaults applied: padding, coordinates, layers, axes.
prepare{ readonly data: PreparedData }The data, each series as
{ values, name, className, meta }.composeSceneNodeEach node with a role that a layer draws, children before their parents: series, lines, areas, points, bars, slices, grid lines and labels. Return a changed node, a new one, or
nullto drop it.renderRenderEventThe renderer has applied the scene: created, replaced or changed the output in place.
outputis what it returned.mountRenderEvent & { readonly elementOf: (node: SceneNode) => Element | undefined; readonly animation?: UpdateAnimation }The output is in the page; touch elements only here. Return a function to undo what the listener did: it runs before the next render changes the output, and on
destroy().
Example
import { barChart, type ChartPlugin } from 'chartist';
// Bars at or above the limit get the class ct-over.
const threshold = (limit: number): ChartPlugin => ({
name: 'threshold',
install(chart) {
chart.on('compose', current => {
if (current.role !== 'bar') {
return;
}
// A number, { x, y } (with an X scale axis) or a hole.
const { value } = current.ctx;
const y =
typeof value === 'number'
? value
: value && 'y' in value
? value.y
: undefined;
return y !== undefined && y >= limit
? current.addClass('ct-over')
: undefined;
});
}
});
barChart(
'#chart',
{ labels: ['Q1', 'Q2', 'Q3', 'Q4'], series: [[5, 4, 3, 7]] },
{ plugins: [threshold(5)] }
);interface RenderEventWhat the render and mount events carry about a render: the scene, the renderer's output, why the chart rendered and what changed.
Properties
readonly sceneSceneNodeThe scene the renderer applied.
readonly outputRenderOutputWhat the renderer returned.
readonly causeRenderCauseWhy the chart rendered, e.g.
updateorresize.readonly previous?SceneNodeThe previous render's scene; absent on the first render and on
hydrate.readonly changesreadonly SceneChange[]What the render did to the output, in document order. When the renderer changed its output in place (
liveDomRenderer()fromchartist/live), these are its changes; otherwise every node of the previous scene is removed and every node of the new one added. Ahydraterender has anaddentry for every node, as a first render.readonly hydration?{ readonly repaired: number }On a
hydraterender: how many attributes, classes and texts of the server's markup differed from the scene the browser built, and were set. 0 when the server and the browser drew the same data and options; more means they didn't. Styles, which the markup leaves out, don't count.
type PhaseName = keyof PhaseEventsThe name of a pipeline phase, such as compose: a key of PhaseEvents.
type PhaseResult<K extends PhaseName> = K extends 'render' ? void : K extends 'mount' ? unknown : PhaseEvents[K] | K extends 'compose' ? null : never | undefined | voidWhat a phase listener returns: a new payload to transform the phase, or nothing to keep it. compose listeners may return null to drop the node. render listeners return nothing (they observe). A function a mount listener returns is its cleanup; other values are ignored, so () => chart.detach() stays a valid listener.
type PhaseListener<K extends PhaseName> = (payload: PhaseEvents[K]) => PhaseResult<K>A listener of one phase: gets the phase's payload and may return a new one (see PhaseResult). Listeners of a phase run in the order they were added, each with the previous one's result.
type AllPhasesListener = (name: PhaseName, payload: unknown) => voidA listener of every phase ('*'): gets the phase name and its final payload, after the phase's own listeners. It only observes.
type PhaseListeners = { [K in PhaseName]?: PhaseListener<K> } & { … }Phase listeners by phase name, as the on option of chart() takes them. They're registered before the first render.
Properties
readonly *?AllPhasesListenerListens to every phase, with the phase name as first argument.