Chartist

Search

Find a guide, an API entry or an example.

Try

Rendering

From scene to output: renderers, text measuring, and rendering on the server.

Chartist renders a scene as SVG in the page or as a string on the server. @chartist-js/terminal renders the same scene as text for terminals and as text art in HTML.

toScene

experimentalSource
function toScene(config: ChartConfig, size: SceneSize): SceneNode

Builds a chart's scene without rendering it: no DOM, timers or globals. Runs the phases resolve to scene with the config's plugins and listeners.

It takes the same config as chart(), and the SVG gets the same chart type class without className. Listeners of render and mount never run, responsive overrides and the renderer are ignored, and calling update(), detach() or destroy() on the handle a plugin gets throws. Turn the scene into markup with renderToString.

Parameters

config ChartConfig

The chart: data, axes, layers, plugins and listeners

size SceneSize

The size to lay out at, in px, and how to measure text

Returns

The scene, its root the svg

Example

import {
  autoScaleAxis,
  axisGrid,
  axisLabels,
  cartesianAxes,
  line,
  node,
  renderToString,
  stepAxis,
  toScene
} from 'chartist';

const labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const scene = toScene(
  {
    data: { labels, series: [[12, 9, 7, 8, 5]] },
    axes: cartesianAxes([
      { id: 'x', side: 'bottom', type: stepAxis(), ticks: labels },
      { id: 'y', side: 'left', type: autoScaleAxis() }
    ]),
    layers: [axisGrid(), line(), axisLabels()],
    viewBox: { width: 600, height: 300 },
    on: {
      // Styles inside the SVG, for tools that read it on its own.
      scene: ({ scene }) => ({
        scene: scene.append(
          node('style').text('.ct-line { fill: none; stroke: #d70206; }'),
          true
        )
      })
    }
  },
  { width: 600, height: 300 }
);

export const markup = renderToString(scene);

seriesColors

experimentalSource
const seriesColors: readonly string[]

The default series colors, a to o, as hex: the colors of chartist/styles.css ($ct-series-colors in the Sass settings). Renderers without CSS use them to color series the way the styles do. The styles color the first fifteen series only.

Example

import { seriesColors } from 'chartist';

// The color of series `c`, the third.
export const third = seriesColors[2];

domRenderer

experimentalSource
function domRenderer(): Renderer<DomRenderOutput>

Creates the renderer chart() uses by default: it renders scenes as inline SVG into the container, replacing an earlier Chartist SVG there (as 1.x does), and measures text and reads styles for layout in the container, so its CSS applies. Wrap it to change what every render puts on the page.

Example

import { chart, domRenderer, pie, type Renderer } from 'chartist';

const dom = domRenderer();
// The DOM renderer, with a name for screen readers on every render.
const renderer: Renderer = {
  ...dom,
  render(scene, container) {
    const output = dom.render(scene, container);
    output.svg.setAttribute('role', 'img');
    output.svg.setAttribute('aria-label', 'Monthly budget');
    return output;
  }
};

chart('#chart', {
  data: { series: [50, 30, 20] },
  coordinates: 'polar',
  layers: [pie()],
  renderer
});

textAscent

experimentalSource
const textAscent: 0.85

Where SVG text labels put a line's baseline: this share of the font size below the top of the line (a typical font's ascent). Lines are one font size apart, so a renderer finds a line's vertical center at y - (textAscent - 0.5) * fontSize from its y.

estimateText

experimentalSource
const estimateText: MeasureText

Estimates text size without a DOM: an average glyph is 0.6 em wide, and a line is 1.2 em high, at fontSize or else 12 px. toScene() measures with it unless you pass your own, which can build on it.

Example

import { estimateText, type MeasureText } from 'chartist';

// Bold labels: a tenth wider than the estimate.
export const measureText: MeasureText = (text, options) => {
  const size = estimateText(text, options);
  return { ...size, width: size.width * 1.1 };
};

renderToString

experimentalSource
function renderToString(scene: SceneNode): string

Serializes a scene to standalone SVG markup. Needs no DOM, so it works in Node.js and in server bundles.

The root gets the SVG and ct: namespaces, and attribute values and text are escaped. The markup has the chart's classes but no styles: load chartist/styles.css where it's shown, or add a style element to the scene.

Parameters

scene SceneNode

A scene, usually from toScene()

Returns

The SVG markup, e.g. <svg xmlns="…" …>…</svg>

Example

import {
  autoScaleAxis,
  axisGrid,
  axisLabels,
  cartesianAxes,
  line,
  renderToString,
  stepAxis,
  toScene
} from 'chartist';

export function weekChart(values: number[]): string {
  const labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
  const scene = toScene(
    {
      data: { labels, series: [values] },
      axes: cartesianAxes([
        { id: 'x', side: 'bottom', type: stepAxis(), ticks: labels },
        { id: 'y', side: 'left', type: autoScaleAxis() }
      ]),
      layers: [axisGrid(), line(), axisLabels()],
      className: 'ct-chart-line'
    },
    { width: 600, height: 300 }
  );
  return renderToString(scene);
}

SceneSize

Source
interface SceneSize

The size toScene lays a chart out at, since there's no container to measure, and how to measure text there.

Properties

readonly width number

The width to lay out at, in px. The root svg gets it as its width, unless the config sets one.

readonly height number

The height to lay out at, in px. The root svg gets it as its height, unless the config sets one.

readonly measureText? MeasureText

Text measurement for layout; an estimate by default.

readonly labels? LabelMode

Label mode when the config sets none: svg by default, since string output often goes to tools without HTML support.

DomRenderOutput

experimentalSource
interface DomRenderOutput extends RenderOutput

What domRenderer returns from render(): the inline SVG it added to the container.

Properties

readonly svg SVGSVGElement

The chart's svg element, in the container.

readonly elementOf (node: SceneNode) => Element | undefined

The rendered element of a scene node of this render.

readonly remove () => void

Takes the SVG out of the container again.

TextMetrics

Source
interface TextMetrics

The size of a measured text, as a MeasureText function returns it.

Properties

readonly width number

The text's width in px.

readonly height number

The text's height in px: one line.

readonly fontSize? number

The font size in px the text was measured with, when known.

LabelMode

experimentalSource
type LabelMode = 'html' | 'svg'

How labels are drawn: HTML in a foreignObject (1.x) or SVG text.

MeasureTextOptions

Source
interface MeasureTextOptions

What a MeasureText function gets with the text to measure.

Properties

readonly classes? readonly string[]

Class names of the text, for renderers that apply CSS.

readonly fontSize? number

Font size in px. Without it, the browser measures with the CSS font size and the estimate uses 12, the size of 1.x .ct-label.

readonly rootClass? string

Classes of the chart's root svg, so chart-type CSS applies.

readonly container? Element

Where to measure (the chart container), so its CSS applies.

MeasureText

Source
type MeasureText = (text: string, options?: MeasureTextOptions) => TextMetrics

Measures how much space a text takes, in px, so labels can be wrapped and aligned. In the browser, Chartist measures with the page's fonts; toScene() estimates (0.6 em per character, 1.2 em per line) unless you pass your own in its size.

Example

import type { MeasureText } from 'chartist';

// Wider glyphs than the estimate, for a wide font.
export const measureText: MeasureText = (text, options = {}) => {
  const fontSize = options.fontSize ?? 12;
  return { width: text.length * fontSize * 0.7, height: fontSize * 1.25 };
};

MeasureStyleOptions

Source
interface MeasureStyleOptions

What a MeasureStyle function gets with the property to read.

Properties

readonly classes? readonly string[]

Class names of the element whose style is read.

readonly rootClass? string

Classes of the chart's root svg, so chart-type CSS applies.

readonly container? Element

Where to measure (the chart container), so its CSS applies.

MeasureStyle

Source
type MeasureStyle = (property: string, options?: MeasureStyleOptions) => string | undefined

Reads a computed CSS property of an SVG path with the given classes, for values that the stylesheet decides and layout needs: the pie layer reads the stroke-width of a donut slice to fit the ring. Returns undefined when it can't tell. In the browser, Chartist reads it in the chart's container; toScene() has no stylesheet, so layout uses its defaults there.

Example

import { domRenderer, type Renderer } from 'chartist';

// The DOM renderer, but donuts are laid out for 30px rings, whatever
// the stylesheet says. Pass it as `renderer` to `chart()`.
export const renderer: Renderer = {
  ...domRenderer(),
  measureStyle: property => (property === 'stroke-width' ? '30px' : undefined)
};

RenderOutput

Source
interface RenderOutput

What a renderer returns from render(). The render and mount phase events pass it on as output.

Properties

readonly elementOf? (node: SceneNode) => Element | undefined

The rendered element of a scene node, if the output is DOM.

readonly remove? () => void

Removes the output again.

Renderer

experimentalSource
interface Renderer<TOutput extends RenderOutput = RenderOutput>

Turns a scene into output. chart() renders inline SVG into its container with the DOM renderer, unless its config sets a renderer. To get markup instead, without a DOM, use toScene() and renderToString.

Properties

render (scene: SceneNode, target: Element) => TOutput

Renders a scene into the chart's container, after the scene phase and on every update and resize.

readonly measureText? MeasureText

Measures text for layout, in the container so its CSS applies; without it, Chartist estimates text sizes.

readonly measureStyle? MeasureStyle

Reads computed styles for layout, in the container so its CSS applies; without it, layout uses its defaults (a donut's ring is laid out for 60 px).

readonly labels? LabelMode

The default label mode of this renderer; html if omitted.