MatesCharts v0.6.0
All charts

Column & Bar

Columns compare values across categories; the bar variant renders them horizontally (chart.type = "bar"). Grouping, stacking and percent stacking are one option away — no extra series math. Both variants are the same series type with flipped axes.

Usage

Create a chart atom with standard Highcharts options, then render Chart(chart) anywhere in a mates template. Every later chart.set(…) or chart.update(…) re-renders the chart — no imperative Highcharts code.

Quick start
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Sales by region"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: true
    },
    xAxis: {
        categories: [
            "North",
            "South",
            "East",
            "West"
        ]
    },
    yAxis: {
        title: {
            text: "Units"
        }
    },
    plotOptions: {
        column: {
            borderRadius: 4,
            pointPadding: 0.2
        }
    },
    series: [
        {
            type: "column",
            name: "2025",
            data: [
                140,
                220,
                180,
                270
            ]
        },
        {
            type: "column",
            name: "2026",
            data: [
                180,
                260,
                210,
                310
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;

Live examples

Created with Highcharts 12.5.0UnitsSales by region20252026NorthSouthEastWest0100200300400
Grouped columns (vertical) Highcharts demo ↗

Multiple series are grouped side-by-side per category automatically. chart.type = "column" is the vertical default.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Sales by region"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: true
    },
    xAxis: {
        categories: [
            "North",
            "South",
            "East",
            "West"
        ]
    },
    yAxis: {
        title: {
            text: "Units"
        }
    },
    plotOptions: {
        column: {
            borderRadius: 4,
            pointPadding: 0.2
        }
    },
    series: [
        {
            type: "column",
            name: "2025",
            data: [
                140,
                220,
                180,
                270
            ]
        },
        {
            type: "column",
            name: "2026",
            data: [
                180,
                260,
                210,
                310
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0VotesTop features requested050100150200250300350Dark modeExportsAPI keysSSOAudit log
Horizontal bars

chart.type = "bar" flips orientation — great for long category labels that would overlap under vertical columns.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "bar"
    },
    title: {
        text: "Top features requested"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "Dark mode",
            "Exports",
            "API keys",
            "SSO",
            "Audit log"
        ]
    },
    yAxis: {
        title: {
            text: "Votes"
        }
    },
    plotOptions: {
        bar: {
            borderRadius: 4
        }
    },
    series: [
        {
            type: "bar",
            name: "Votes",
            data: [
                312,
                254,
                198,
                142,
                96
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0$kStacked revenue60​6070​7065​6590​9040​4055​5560​6080​8020​2025​2535​3545​45HardwareSoftwareServicesQ1Q2Q3Q4050100150200250
Stacked columns with totals Highcharts demo ↗

stacking = "normal" piles the series; a shared tooltip reads the total and every part at once.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Stacked revenue"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: true
    },
    xAxis: {
        categories: [
            "Q1",
            "Q2",
            "Q3",
            "Q4"
        ]
    },
    yAxis: {
        title: {
            text: "$k"
        }
    },
    tooltip: {
        shared: true
    },
    plotOptions: {
        column: {
            stacking: "normal",
            borderRadius: 3
        },
        series: {
            dataLabels: {
                enabled: true,
                format: "{y}"
            }
        }
    },
    series: [
        {
            type: "column",
            name: "Hardware",
            data: [
                60,
                70,
                65,
                90
            ]
        },
        {
            type: "column",
            name: "Software",
            data: [
                40,
                55,
                60,
                80
            ]
        },
        {
            type: "column",
            name: "Services",
            data: [
                20,
                25,
                35,
                45
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0Traffic mix by quarterOrganicPaidReferralQ1Q2Q3Q40%25%50%75%100%
Percentage-stacked columns Highcharts demo ↗

stacking = "percent" normalises each category to 100% — compare mix rather than magnitude.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Traffic mix by quarter"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: true
    },
    xAxis: {
        categories: [
            "Q1",
            "Q2",
            "Q3",
            "Q4"
        ]
    },
    yAxis: {
        labels: {
            format: "{value}%"
        },
        max: 100,
        title: {
            text: ""
        }
    },
    tooltip: {
        shared: true,
        valueSuffix: "%"
    },
    plotOptions: {
        column: {
            stacking: "percent",
            borderRadius: 3
        }
    },
    series: [
        {
            type: "column",
            name: "Organic",
            data: [
                55,
                52,
                48,
                45
            ]
        },
        {
            type: "column",
            name: "Paid",
            data: [
                25,
                28,
                32,
                35
            ]
        },
        {
            type: "column",
            name: "Referral",
            data: [
                20,
                20,
                20,
                20
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0EngineersLanguage usage by teamTypeScriptKotlinGoPython024681012141618202224WebMobileBackendData
Stacked horizontal bars

Orientation and stacking compose freely — horizontal + normal stacking for survey results with many categories.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "bar"
    },
    title: {
        text: "Language usage by team"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: true
    },
    xAxis: {
        categories: [
            "Web",
            "Mobile",
            "Backend",
            "Data"
        ]
    },
    yAxis: {
        title: {
            text: "Engineers"
        }
    },
    tooltip: {
        shared: true
    },
    plotOptions: {
        bar: {
            stacking: "normal",
            borderRadius: 3
        }
    },
    series: [
        {
            type: "bar",
            name: "TypeScript",
            data: [
                12,
                4,
                6,
                3
            ]
        },
        {
            type: "bar",
            name: "Kotlin",
            data: [
                0,
                9,
                1,
                0
            ]
        },
        {
            type: "bar",
            name: "Go",
            data: [
                1,
                0,
                11,
                4
            ]
        },
        {
            type: "bar",
            name: "Python",
            data: [
                2,
                1,
                3,
                10
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0$kMonthly net cash flowJanFebMarAprMayJun-10-50510152025
Diverging (positive & negative) bars Highcharts demo ↗

Negative values draw below/-left of the zero line automatically — perfect for profit/loss or sentiment. negativeColor highlights the losses.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Monthly net cash flow"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "Jan",
            "Feb",
            "Mar",
            "Apr",
            "May",
            "Jun"
        ]
    },
    yAxis: {
        title: {
            text: "$k"
        },
        plotLines: [
            {
                value: 0,
                width: 1,
                color: "#94a3b8"
            }
        ]
    },
    plotOptions: {
        column: {
            borderRadius: 3,
            negativeColor: "#dc2626"
        }
    },
    series: [
        {
            type: "column",
            name: "Net",
            data: [
                12,
                -8,
                15,
                -4,
                9,
                21
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0DeploysDeploy frequency14​149​922​2217​1711​11MonTueWedThuFri051015202530
Data labels & rounded tops

dataLabels + borderRadius are the quickest route to the modern 'dashboard column' look.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Deploy frequency"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "Mon",
            "Tue",
            "Wed",
            "Thu",
            "Fri"
        ]
    },
    yAxis: {
        title: {
            text: "Deploys"
        },
        maxPadding: 0.2
    },
    plotOptions: {
        column: {
            borderRadius: 6,
            pointWidth: 28
        },
        series: {
            dataLabels: {
                enabled: true,
                format: "{y}",
                style: {
                    fontWeight: "600"
                }
            }
        }
    },
    series: [
        {
            type: "column",
            name: "Deploys",
            data: [
                14,
                9,
                22,
                17,
                11
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0Requests / day (log)Endpoints by traffic//api/docs/blog/archive1001k10k100k1M10M
Logarithmic column axis

When category values span orders of magnitude, a log y-axis keeps small bars visible next to giants.

TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Endpoints by traffic"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "/",
            "/api",
            "/docs",
            "/blog",
            "/archive"
        ]
    },
    yAxis: {
        type: "logarithmic",
        title: {
            text: "Requests / day (log)"
        },
        minorTickInterval: 0.1
    },
    series: [
        {
            type: "column",
            name: "Requests",
            data: [
                980000,
                410000,
                42000,
                3800,
                210
            ]
        }
    ]
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;
Created with Highcharts 12.5.0Total percent market shareBrowser usage — click a column62.0%​62.0%24.0%​24.0%8.0%​8.0%6.0%​6.0%ChromeSafariFirefoxEdge010203040506070
Columns with drilldown Highcharts demo ↗

Column categories descend into detail on click — the browser/OS drilldown pattern from the classic demo.

Module setup. This example needs one extra Highcharts module:
import "highcharts/modules/drilldown";
TypeScript
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Browser usage — click a column"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        type: "category"
    },
    yAxis: {
        title: {
            text: "Total percent market share"
        }
    },
    plotOptions: {
        series: {
            borderWidth: 0,
            dataLabels: {
                enabled: true,
                format: "{point.y:.1f}%"
            }
        }
    },
    series: [
        {
            type: "column",
            name: "Browsers",
            colorByPoint: true,
            data: [
                {
                    name: "Chrome",
                    y: 62,
                    drilldown: "chrome"
                },
                {
                    name: "Safari",
                    y: 24,
                    drilldown: "safari"
                },
                {
                    name: "Firefox",
                    y: 8,
                    drilldown: "firefox"
                },
                {
                    name: "Edge",
                    y: 6
                }
            ]
        }
    ],
    drilldown: {
        series: [
            {
                type: "column",
                id: "chrome",
                name: "Chrome",
                data: [
                    [
                        "v126",
                        38
                    ],
                    [
                        "v125",
                        14
                    ],
                    [
                        "v124",
                        7
                    ],
                    [
                        "Older",
                        3
                    ]
                ]
            },
            {
                type: "column",
                id: "safari",
                name: "Safari",
                data: [
                    [
                        "v17",
                        15
                    ],
                    [
                        "v16",
                        7
                    ],
                    [
                        "Older",
                        2
                    ]
                ]
            },
            {
                type: "column",
                id: "firefox",
                name: "Firefox",
                data: [
                    [
                        "v127",
                        5
                    ],
                    [
                        "Older",
                        3
                    ]
                ]
            }
        ]
    }
});

// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
    html`<div style="height: 22rem">${Chart(chart)}</div>`;

Options reference

mates-charts passes options straight through to Highcharts — these are the keys that matter for column & bar charts. See the full Highcharts API for everything else.

Option Type Default Description
chart.type "column" | "bar" — Vertical columns or horizontal bars.
plotOptions.column.stacking undefined | "normal" | "percent" undefined Stack series on top of each other or as a 100% share.
plotOptions.column.grouping boolean true Group multiple series side-by-side per category.
plotOptions.column.pointPadding number 0.1 Padding between columns (in category-width fractions).
plotOptions.column.borderRadius number 0 Rounds the column tops.
plotOptions.series.pointWidth number undefined Fixed bar width in pixels (overrides padding).
plotOptions.series.dataLabels.enabled boolean false Print each value on its column.
plotOptions.series.dataLabels.format string "{y}" Label format, e.g. "{y} kg" or "{point.name}: {y}".
plotOptions.series.minPointLength number 0 Minimum pixel length so zero-values stay visible.
plotOptions.series.negativeColor string undefined Colour for values below the threshold.
yAxis.max number auto Pin the axis maximum — useful with stacking.
yAxis.type "linear" | "logarithmic" "linear" Log scale for values spanning orders of magnitude.