Chartist

Search

Find a guide, an API entry or an example.

Try

Composed charts

Build charts from axes and layers with chart(), for bars and a line on two Y axes, axes on any side and anything the presets don't cover.

lineChart(), barChart() and pieChart() are presets: ready-made recipes over one function, chart(). When a recipe doesn’t fit, you cook with the same parts yourself: a list of axes, and a list of layers that draw on them.

Preset or compose?

Use a preset when your chart is a line, bar or pie chart. Presets take the familiar options, handle responsive options and give you the classic markup in one call.

Compose when you need something a preset can’t do:

  • bars and a line in one chart,
  • two value scales, like millimeters on the left and degrees on the right,
  • several axes on one side, or an X axis at the top,
  • your own layer next to the built-in ones.

Bars and a line on two axes

A climate chart: rain as bars on the left axis, temperature as a line on the right axis, each on its own scale.

src/main.ts
import 'chartist/styles.css';
import {
  autoScaleAxis,
  axisGrid,
  axisLabels,
  bar,
  cartesianAxes,
  chart,
  line,
  stepAxis
} from 'chartist';

const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];

chart('#chart', {
  data: {
    labels: months,
    series: [
      { name: 'rain', data: [64, 58, 70, 82, 104, 120] },
      // A palette color that stands apart from the bars.
      {
        name: 'temperature',
        className: 'ct-series-g',
        data: [1, 3, 8, 12, 16, 20]
      }
    ]
  },
  axes: cartesianAxes([
    { id: 'month', side: 'bottom', type: stepAxis() },
    { id: 'mm', side: 'left', type: autoScaleAxis(), low: 0 },
    { id: 'celsius', side: 'right', type: autoScaleAxis(), low: 0 }
  ]),
  layers: [
    axisGrid({ axes: ['month', 'mm'] }),
    bar({ series: ['rain'], x: 'month', y: 'mm' }),
    line({
      series: ['temperature'],
      x: 'month',
      y: 'celsius',
      align: 'center'
    }),
    axisLabels()
  ]
});
Live

Three things make this work:

  • Axes have ids. cartesianAxes() takes a list of axes, each with an id, a side and a type.
  • Layers pick their series and axes. bar({ series: ['rain'], x: 'month', y: 'mm' }) draws the series named rain against the month and mm axes.
  • Each axis scales to its own series. The mm axis only looks at the rain, the celsius axis only at the temperature.

Axes

Every axis in cartesianAxes([...]) has:

Field What it is
id The name layers use to draw on it. Ids must be unique
side 'bottom' or 'top' for an X axis, 'left' or 'right' for a Y axis
type stepAxis(), autoScaleAxis() or fixedScaleAxis()

On top of that, an axis takes the same options as axisX and axisY in the presets: offset, low, high, onlyInteger, ticks, showGrid, showLabel, labelInterpolationFnc and the rest. Axes and scales explains the types and their options.

One thing goes beyond the presets: several axes can share a side. They stack outward in the order you list them, each with its own offset.

cartesianAxes([
  { id: 'month', side: 'bottom', type: stepAxis() },
  // Both on the left: 'eur' next to the chart, 'usd' outside it.
  { id: 'eur', side: 'left', type: autoScaleAxis() },
  { id: 'usd', side: 'left', type: autoScaleAxis(), offset: 50 }
]);

Layers

Layers draw in the order you list them, each on top of the ones before. Put the grid first and the labels last.

Layer Draws Options
line() Lines, points and areas series, x, y, align, lineSmooth, showLine, showPoint, showArea, areaBase
bar() Bars series, x, y, horizontalBars, stackBars, stackMode, seriesBarDistance, distributeSeries
axisGrid() Grid lines (g.ct-grids) axes (default: all), background
axisLabels() Axis labels (g.ct-labels) axes (default: all), labels ('html' or 'svg')

series picks series by name or by index; leave it out and the layer draws all of them. x and y are axis ids; leave them out and the layer uses the first X and the first Y axis. An unknown name or id throws an error that names the layer. Grid and label layers draw for every axis unless you name some: the example draws the grid of month and mm only, so the right axis doesn’t add a second set of lines.

Series keep their place in the data: the temperature is the second series, so it would be ct-series-b even though it’s the only series its layer draws. Your series colors stay put when you move a series to another layer. (The example picks ct-series-g with className, a blue that stands apart from the red bars.)

Lining up with bars

Bars sit in the middle of each step, while line points sit at the start of it by default. align: 'center' moves the points to the bar centers, as in the example.

Bars grow from zero on their value axis, so make sure zero is on it: low: 0, or referenceValue: 0 to include zero and still scale to the data.

The rest of the config

Next to data, axes and layers, chart() takes:

Option What it does
padding Space around the chart in px: a number, or { top, right, bottom, left } (default 15, 15, 5, 10)
className Classes for the <svg>. By default the chart type’s class, from the layers
width, height A fixed size; by default the chart fills its container
labels 'html' or 'svg' axis labels for every label layer

The class matters for CSS: the default stylesheet aligns labels by chart type. Without a className, a chart with a bar() layer gets ct-chart-bar, which centers the X labels under the bars, a pie gets ct-chart-pie (or ct-chart-donut), and anything else gets ct-chart-line. A className of your own replaces it, so add the chart type’s class to it if you want that alignment.

In the API reference: chart(), layers and scales and axes.

Next: learn what each axis type does, or keep the chart up to date with new data.