Box Plot
Box plots summarise a distribution in five statistics per box: [low, q1, median, q3, high]. They're core Highcharts — no module needed — and pair naturally with scatter outliers.
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.
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";
const chart = chartAtom({
chart: {
type: "boxplot"
},
title: {
text: "API latency by endpoint"
},
credits: {
enabled: false
},
colors: [
"#00968c",
"#06b6d4",
"#d97706",
"#7c3aed",
"#dc2626",
"#16a34a",
"#0172ad",
"#9333ea"
],
legend: {
enabled: false
},
xAxis: {
categories: [
"/users",
"/orders",
"/search",
"/export"
]
},
yAxis: {
title: {
text: "ms"
}
},
plotOptions: {
boxplot: {
fillColor: "rgba(0, 150, 140, 0.15)",
medianColor: "#00968c",
stemColor: "#94a3b8",
whiskerColor: "#94a3b8"
}
},
series: [
{
type: "boxplot",
name: "Latency",
data: [
[
42,
88,
120,
180,
320
],
[
38,
70,
95,
140,
260
],
[
65,
150,
240,
410,
900
],
[
110,
260,
380,
620,
1400
]
]
}
]
});
// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
html`<div style="height: 22rem">${Chart(chart)}</div>`;
Live examples
One box per category. The tooltip can name all five statistics via headerFormat/userFormat.
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";
const chart = chartAtom({
chart: {
type: "boxplot"
},
title: {
text: "API latency by endpoint"
},
credits: {
enabled: false
},
colors: [
"#00968c",
"#06b6d4",
"#d97706",
"#7c3aed",
"#dc2626",
"#16a34a",
"#0172ad",
"#9333ea"
],
legend: {
enabled: false
},
xAxis: {
categories: [
"/users",
"/orders",
"/search",
"/export"
]
},
yAxis: {
title: {
text: "ms"
}
},
plotOptions: {
boxplot: {
fillColor: "rgba(0, 150, 140, 0.15)",
medianColor: "#00968c",
stemColor: "#94a3b8",
whiskerColor: "#94a3b8"
}
},
series: [
{
type: "boxplot",
name: "Latency",
data: [
[
42,
88,
120,
180,
320
],
[
38,
70,
95,
140,
260
],
[
65,
150,
240,
410,
900
],
[
110,
260,
380,
620,
1400
]
]
}
]
});
// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
html`<div style="height: 22rem">${Chart(chart)}</div>`;
Add a scatter series sharing the x categories to display the raw samples beyond the whiskers.
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";
const chart = chartAtom({
chart: {
type: "boxplot"
},
title: {
text: "Build times"
},
credits: {
enabled: false
},
colors: [
"#00968c",
"#06b6d4",
"#d97706",
"#7c3aed",
"#dc2626",
"#16a34a",
"#0172ad",
"#9333ea"
],
legend: {
enabled: true
},
xAxis: {
categories: [
"main",
"feature/x",
"hotfix"
]
},
yAxis: {
title: {
text: "seconds"
}
},
series: [
{
type: "boxplot",
name: "Distribution",
data: [
[
60,
90,
105,
130,
190
],
[
80,
110,
125,
160,
240
],
[
55,
75,
88,
100,
150
]
]
},
{
type: "scatter",
name: "Outliers",
data: [
[
0,
250
],
[
1,
310
],
[
2,
40
]
],
marker: {
symbol: "circle",
radius: 4
}
}
]
});
// render inside any mates template — give the wrapper a height:
export const MyChart = () =>
html`<div style="height: 22rem">${Chart(chart)}</div>`;
Two boxplot series per category compare distributions side by side — same grouping engine as columns.
import { html } from "mates";
import { Chart, chartAtom } from "mates-charts";
const chart = chartAtom({
chart: {
type: "boxplot"
},
title: {
text: "Response time: before vs after cache"
},
credits: {
enabled: false
},
colors: [
"#00968c",
"#06b6d4",
"#d97706",
"#7c3aed",
"#dc2626",
"#16a34a",
"#0172ad",
"#9333ea"
],
legend: {
enabled: true
},
xAxis: {
categories: [
"GET /list",
"GET /detail",
"POST /query"
]
},
yAxis: {
title: {
text: "ms"
}
},
plotOptions: {
boxplot: {
fillColor: "rgba(6, 182, 212, 0.15)",
medianColor: "#06b6d4"
}
},
series: [
{
type: "boxplot",
name: "Before",
data: [
[
80,
140,
180,
240,
400
],
[
120,
200,
260,
340,
520
],
[
60,
110,
150,
210,
330
]
]
},
{
type: "boxplot",
name: "After",
data: [
[
22,
38,
45,
58,
90
],
[
30,
52,
64,
82,
130
],
[
18,
30,
40,
54,
85
]
]
}
]
});
// 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 box plot charts. See the full Highcharts API for everything else.
| Option | Type | Default | Description |
|---|---|---|---|
chart.type |
"boxplot" | — | Selects the box plot series type (core build). |
series[].data |
[low, q1, median, q3, high][] | — | Five statistics per box, in that exact order. |
plotOptions.boxplot.fillColor |
string | "#ffffff" | Box interior colour. |
plotOptions.boxplot.medianColor / medianWidth |
string / number | — | Median line colour and thickness. |
plotOptions.boxplot.stemColor / stemWidth |
string / number | — | The vertical line through the box. |
plotOptions.boxplot.whiskerColor / whiskerLength |
string / number|string | — | Cap styling at low/high ends. |
plotOptions.boxplot.groupPadding |
number | 0.2 | Space between box groups. |
tooltip.headerFormat |
string | — | Custom header naming the box statistics. |