Skip to content

Bar Chart

The Bar Chart compares one or more values across a categorical axis, drawing a bar per series per category. It is the right chart whenever the categories are discrete and the comparison is between magnitudes rather than a trend. stacked switches between grouped bars, a single stacked bar per category, and 'percent' for a 100%-stacked view; orientation flips the bars horizontal for long category names; borderRadius and labels handle the finish. Tooltips, grid lines and axis labels are on by default, a legend appears once there is more than one series, and bars animate on entry, update and exit. It draws to Canvas, SVG or a terminal context without changing the options.

NOTE

For the full API, see the Charts API Reference.

Example

Usage

ts
import {
    createBarChart,
} from '@ripl/charts';

const chart = createBarChart('#container', {
    data: [/* ... */],
    key: 'quarter',
    stacked: false,          // set true to stack series
    orientation: 'vertical', // 'vertical' | 'horizontal'
    series: [
        { id: 'sales', value: 'sales', label: 'Sales' },
        { id: 'costs', value: 'costs', label: 'Costs' },
    ],
});

Data Format

Each item in the data array should contain a category key and one or more numeric fields for series values:

ts
const data = [
    {
        month: 'Jan',
        sales: 420,
        costs: 280,
    },
    {
        month: 'Feb',
        sales: 380,
        costs: 310,
    },
    {
        month: 'Mar',
        sales: 510,
        costs: 250,
    },
];

The key option identifies the category field ('month'), and each series maps to a numeric field via its value property.

Variants

Grouped (default)

Bars for each series sit side-by-side within each category:

ts
createBarChart('#container', {
    data,
    key: 'month',
    stacked: false,
    series: [
        {
            id: 'sales',
            value: 'sales',
            label: 'Sales',
        },
        {
            id: 'costs',
            value: 'costs',
            label: 'Costs',
        },
    ],
});

Stacked

Bars stack on top of each other, showing cumulative totals:

ts
createBarChart('#container', {
    data,
    key: 'month',
    stacked: true,
    series: [
        {
            id: 'sales',
            value: 'sales',
            label: 'Sales',
        },
        {
            id: 'costs',
            value: 'costs',
            label: 'Costs',
        },
    ],
});

100% stacked

Pass stacked: 'percent' to normalize each category to its share of the category total. The value axis is fixed to 0–100% and values default to percentage formatting:

ts
createBarChart('#container', {
    data,
    key: 'month',
    stacked: 'percent',
    series: [
        {
            id: 'sales',
            value: 'sales',
            label: 'Sales',
        },
        {
            id: 'costs',
            value: 'costs',
            label: 'Costs',
        },
    ],
});

Rotated x labels

Rotate crowded tick labels with axis.x.labelRotation (degrees; positive tilts labels up to the right):

ts
createBarChart('#container', {
    data,
    key: 'month',
    series: [
        {
            id: 'sales',
            value: 'sales',
            label: 'Sales',
        },
    ],
    axis: {
        x: { labelRotation: 45 },
    },
});

Multiple y-axes

Vertical grouped bars support any number of y-axes. Supply an array of axis.y entries and bind each series to one with its yAxis option, naming the axis's id; position: 'right' axes sit on the right and same-side axes stack outward in array order. Each axis scales independently to the series bound to it:

ts
createBarChart('#container', {
    data,
    key: 'month',
    series: [
        {
            id: 'revenue',
            value: 'revenue',
            label: 'Revenue',
            yAxis: 'revenue',
        },
        {
            id: 'orders',
            value: 'orders',
            label: 'Orders',
            yAxis: 'orders',
        },
    ],
    axis: {
        y: [
            {
                id: 'revenue',
                title: 'Revenue ($)',
            },
            {
                id: 'orders',
                position: 'right',
                title: 'Orders',
            },
        ],
    },
});

NOTE

Multiple y-axes apply to vertical grouped bars only. Stacked bars share one cumulative value scale, and horizontal bars read categories along the y-axis, so both use the primary axis.

Horizontal

Swap axes so bars extend horizontally:

ts
createBarChart('#container', {
    data,
    key: 'month',
    orientation: 'horizontal',
    series: [
        {
            id: 'sales',
            value: 'sales',
            label: 'Sales',
        },
    ],
});

Options

A full configuration for this chart. The options every chart shares — padding, title, animation, theme and the rest — behave the same everywhere and are documented on Shared Options.

ts
createBarChart('#container', {
    data,
    key: 'month',
    orientation: 'vertical',
    borderRadius: 4,
    labels: true,
    format: 'number',
    // `stacked` is not shown here: stacked and percent bars share one cumulative scale, so they
    // cannot combine with the second axis below. Both are in Variants above.
    series: [
        {
            id: 'revenue',
            value: 'revenue',
            label: 'Revenue',
            color: '#7cacf8',
            yAxis: 'revenue',
        },
        {
            id: 'orders',
            value: 'orders',
            label: 'Orders',
            color: '#6dd5b1',
            yAxis: 'orders',
        },
    ],
    axis: {
        y: [
            {
                id: 'revenue',
                title: 'Revenue ($)',
            },
            {
                id: 'orders',
                position: 'right',
                title: 'Orders',
            },
        ],
    },
});

Events

Subscribe with chart.on(...). A handler receives an Event object, not the payload directly — the payload is on event.data, and carries the interacted datum plus its { x, y } anchor in chart pixels. event.target and event.stopPropagation() are also available.

ts
// Emitted when a bar is clicked.
chart.on('barclick', event => console.log(event.data)); // event.data: BarChartBarEvent
// Emitted when the pointer enters a bar.
chart.on('barenter', event => console.log(event.data)); // event.data: BarChartBarEvent
// Emitted when the pointer leaves a bar.
chart.on('barleave', event => console.log(event.data)); // event.data: BarChartBarEvent