MatesCharts v0.6.0
All charts

Dynamic Charts

The chart atom IS the chart state. Call set(…) with a new options object or update(…) with a mutator and the mounted chart patches itself via Highcharts' own chart.update — no imperative chart code, no re-render of the template.

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: "line"
    },
    title: {
        text: "Requests / second"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "-4s",
            "-3s",
            "-2s",
            "-1s",
            "now"
        ]
    },
    yAxis: {
        title: {
            text: "req/s"
        },
        min: 0
    },
    plotOptions: {
        series: {
            marker: {
                enabled: false
            },
            lineWidth: 2
        }
    },
    series: [
        {
            type: "line",
            name: "req/s",
            data: [
                42,
                51,
                38,
                63,
                57
            ]
        }
    ]
});

// 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.0req/sRequests / second-4s-3s-2s-1snow010203040506070
Live data (polling)

Replace the series data on an interval with chart.set(…). Highcharts animates the transition; the rest of the page never re-renders.

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

const chart = chartAtom({
    chart: {
        type: "line"
    },
    title: {
        text: "Requests / second"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "-4s",
            "-3s",
            "-2s",
            "-1s",
            "now"
        ]
    },
    yAxis: {
        title: {
            text: "req/s"
        },
        min: 0
    },
    plotOptions: {
        series: {
            marker: {
                enabled: false
            },
            lineWidth: 2
        }
    },
    series: [
        {
            type: "line",
            name: "req/s",
            data: [
                42,
                51,
                38,
                63,
                57
            ]
        }
    ]
});

// 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.0ValueClick anywhere to add a point01234567010203040506070
Click to add points Highcharts demo ↗

chart.events.click receives the chart instance as `this` — addPoint appends to the series and the axis scrolls via shift. The handler is part of the config, so the copy-paste snippet includes it.

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

const chart = chartAtom({
    chart: {
        type: "spline",
        events: {}
    },
    title: {
        text: "Click anywhere to add a point"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "0",
            "1",
            "2",
            "3",
            "4",
            "5",
            "6",
            "7"
        ]
    },
    yAxis: {
        title: {
            text: "Value"
        },
        min: 0
    },
    plotOptions: {
        series: {
            marker: {
                enabled: true,
                radius: 3
            }
        }
    },
    series: [
        {
            type: "spline",
            name: "Random walk",
            data: [
                31,
                42,
                38,
                51,
                44,
                62,
                57,
                49
            ]
        }
    ]
});

// 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$kSales by year — driven by an atom20232024202520260100200300400500600700
Reactive source (atom wiring)

Charts read plain atoms — wire them to any other state with effect(). When the source atom changes, the chart updates in place.

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

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Sales by year — driven by an atom"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "2023",
            "2024",
            "2025",
            "2026"
        ]
    },
    yAxis: {
        title: {
            text: "$k"
        }
    },
    series: [
        {
            type: "column",
            name: "Sales",
            data: [
                410,
                480,
                520,
                610
            ]
        }
    ]
});

// 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$kQuarterly revenueRevenueTargetQ1Q2Q3Q4050100150200
In-place updates with update()

chart.update(fn) mutates the current config — change a title, restyle a series or swap the chart type without rebuilding options from scratch.

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

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Quarterly 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"
        }
    },
    series: [
        {
            type: "column",
            name: "Revenue",
            data: [
                120,
                140,
                135,
                170
            ]
        },
        {
            type: "line",
            name: "Target",
            data: [
                130,
                130,
                130,
                130
            ],
            dashStyle: "Dash"
        }
    ]
});

// 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$kToggle datasetsOnlineRetailJanFebMarAprMayJun2025303540455055
Add & remove series

set() with a different series array swaps the whole chart content — toggle datasets, change granularity, or swap chart.type in one call.

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

const chart = chartAtom({
    chart: {
        type: "line"
    },
    title: {
        text: "Toggle datasets"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: true
    },
    xAxis: {
        categories: [
            "Jan",
            "Feb",
            "Mar",
            "Apr",
            "May",
            "Jun"
        ]
    },
    yAxis: {
        title: {
            text: "$k"
        }
    },
    series: [
        {
            type: "line",
            name: "Online",
            data: [
                22,
                31,
                28,
                41,
                38,
                49
            ]
        },
        {
            type: "line",
            name: "Retail",
            data: [
                40,
                36,
                44,
                39,
                47,
                43
            ]
        }
    ]
});

// 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.0msLatency p50–p99eu-1eu-2us-1us-2ap-10100200300400
Axis extremes

Update yAxis.min/max reactively to zoom into a range — pairs well with controls built from ordinary mates atoms.

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

const chart = chartAtom({
    chart: {
        type: "column"
    },
    title: {
        text: "Latency p50–p99"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "eu-1",
            "eu-2",
            "us-1",
            "us-2",
            "ap-1"
        ]
    },
    yAxis: {
        title: {
            text: "ms"
        },
        min: 0,
        max: 400
    },
    series: [
        {
            type: "column",
            name: "p99",
            data: [
                84,
                96,
                172,
                210,
                330
            ]
        }
    ]
});

// 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.0MBMemory usage (last 10 samples)050100150200250300
Sliding window (shift)

Keep the last N points: append the new value and drop the first — the classic rolling telemetry chart.

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

const chart = chartAtom({
    chart: {
        type: "areaspline"
    },
    title: {
        text: "Memory usage (last 10 samples)"
    },
    credits: {
        enabled: false
    },
    colors: [
        "#00968c",
        "#06b6d4",
        "#d97706",
        "#7c3aed",
        "#dc2626",
        "#16a34a",
        "#0172ad",
        "#9333ea"
    ],
    legend: {
        enabled: false
    },
    xAxis: {
        categories: [
            "-9s",
            "-8s",
            "-7s",
            "-6s",
            "-5s",
            "-4s",
            "-3s",
            "-2s",
            "-1s",
            "0s"
        ],
        labels: {
            enabled: false
        }
    },
    yAxis: {
        title: {
            text: "MB"
        },
        min: 0
    },
    plotOptions: {
        areaspline: {
            fillOpacity: 0.3,
            marker: {
                enabled: false
            },
            lineWidth: 1.5
        }
    },
    series: [
        {
            type: "areaspline",
            name: "Heap",
            data: [
                210,
                224,
                219,
                241,
                236,
                252,
                248,
                263,
                259,
                271
            ]
        }
    ]
});

// 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 dynamic charts charts. See the full Highcharts API for everything else.

Option Type Default Description
chart.events.click Function — `this` is the chart — e.g. this.series[0].addPoint(…) on click.
chart.events.load Function — Runs once on mount — start polling here if you prefer events to atoms.
series[].addPoint(value, redraw, shift) Function — Append a point; shift drops the oldest for sliding windows.
chart.update(options, redraw, oneToOne) Function — The imperative equivalent of atom.set — mates-charts calls it for you.
chart.setType(type) Function — Swap the series type at runtime.
yAxis.setExtremes(min, max) Function — Zoom the axis programmatically.
series[].pointInterval / pointStart number — Generate datetime x positions without listing them.
plotOptions.series.animation boolean | AnimationOptions true Transition between atom updates.