The spread of raw values per category with quartiles, whiskers and outliers
Tags: chart box-plot distribution spread outliers reporting
The BoxPlotChart summarises raw observations per category as a box from the first to the third quartile, a median line, whiskers to the furthest values within 1.5 IQR, and dots for outliers. Use it to compare consistency as well as typical values, for example cycle times per builder or days to close per community.
Svelte only (
@classic-homes/charts-svelte); React support is pending.
Import
<script>
import { BoxPlotChart } from '@classic-homes/charts-svelte';
</script>Basic Usage
<script>
import { BoxPlotChart } from '@classic-homes/charts-svelte';
const data = [
{ name: 'Hilltop Builders', values: [92, 98, 101, 104, 108, 110, 115, 121, 168] },
{ name: 'Riverbend Homes', values: [105, 112, 116, 118, 122, 126, 131, 138] },
{ name: 'Oak & Main', values: [99, 118, 124, 129, 133, 141, 150, 162] },
];
</script>
<BoxPlotChart title="Cycle Time by Builder" {data} valueFormat="days" />Props
Chart-Specific Props
| Prop | Type | Default | Description |
|---|---|---|---|
data |
BoxPlotGroup[] |
required | One box per group, computed from its raw values |
orientation |
'vertical' | 'horizontal' |
'vertical' |
Box orientation; horizontal lists the first group at the top |
showOutliers |
boolean |
true |
Draw values beyond the whiskers as dots |
color |
string |
- | Box colour (defaults to the first series colour) |
xAxisConfig |
AxisConfig |
- | Horizontal axis customisation |
yAxisConfig |
AxisConfig |
- | Vertical axis customisation |
referenceLines |
ReferenceLine[] |
- | Lines at fixed values (statistics such as 'average' are ignored on box plots) |
referenceBands |
ReferenceBand[] |
- | Shaded value ranges, e.g. a target band |
onClick |
(params: DataPointEventParams) => void |
- | Callback when a box is clicked; value is [low, q1, median, q3, high] |
Inherited Base Props
| Prop | Type | Default | Description |
|---|---|---|---|
title |
string |
required | Chart title for accessibility (aria-label) |
description |
string |
- | Description for screen readers (generated from the data when omitted) |
height |
number | string |
400 |
Chart height in pixels or CSS value |
minHeight |
number |
- | Minimum height in pixels; also bounds an 'auto' height |
maxHeight |
number |
- | Maximum height in pixels; also bounds an 'auto' height |
loading |
boolean |
false |
Show loading skeleton (an overlay when data is already shown) |
error |
string | null |
- | Error message to display |
onRetry |
() => void |
- | Show a Retry button on the error state, calling this |
emptyMessage |
string |
- | Message shown when data is empty |
theme |
'light' | 'dark' | 'auto' |
'auto' |
Theme preference |
animation |
boolean |
true |
Enable/disable animations (respects prefers-reduced-motion) |
showTooltip |
boolean |
true |
Show tooltip on hover |
showGrid |
boolean |
true |
Show grid lines |
valueFormat |
ValueFormat |
- | Preset ('number', 'integer', 'compact', 'currency', 'currencyCents', 'percent', 'percentValue', 'days'), Intl.NumberFormatOptions or a function; drives the value axis, tooltip, labels and data table |
locale |
string |
'en-US' |
Locale for valueFormat |
tooltipFormatter |
string | ((items: TooltipFormatterParams[]) => string) |
- | Custom tooltip template or HTML function |
tooltipValueFormatter |
(value: number) => string |
- | Format values in the default tooltip (overrides valueFormat there) |
option |
EChartsOption |
- | Raw ECharts option deep-merged over the generated one |
onReady |
(chart: EChartsType) => void |
- | Called with the ECharts instance when it is created |
events |
ChartEventHandlers |
- | Raw ECharts event handlers keyed by event name ('datazoom', 'legendselectchanged', ...) |
showDataTable |
boolean | 'sr-only' |
'sr-only' |
Data table for screen readers only, a visible "Show data" toggle (true) or none (false) |
exportable |
boolean | ChartExportConfig |
- | Show PNG and CSV download buttons, or { image, csv, filename } |
patterns |
boolean |
false |
Fill series with decal patterns as well as colour |
class |
string |
- | Custom CSS class |
showLegend |
boolean |
- | Show chart legend |
Data Structure
interface BoxPlotGroup {
name: string; // Category label
values: number[]; // Raw observations; non-finite values are ignored
}
// Computed per group (also available via boxplotStats(values))
interface BoxPlotStats {
low: number; // Smallest value within 1.5 IQR of Q1
q1: number;
median: number;
q3: number;
high: number; // Largest value within 1.5 IQR of Q3
outliers: number[];
count: number;
mean: number;
}Examples
Horizontal with a Target Band
<BoxPlotChart
title="Days to Close by Community"
{data}
orientation="horizontal"
valueFormat="days"
referenceBands={[{ from: 30, to: 45, label: 'Target' }]}
/>Without Outliers
<BoxPlotChart title="Sale Price by Plan" {data} showOutliers={false} valueFormat="compact" />Summary Statistics Only
boxplotStats gives the same five-number summary for use elsewhere, such as a table.
import { boxplotStats } from '@classic-homes/charts-svelte';
const stats = boxplotStats([92, 98, 101, 104, 108, 110, 115, 121, 168]);
// { low: 92, q1: 101, median: 108, q3: 115, high: 121, outliers: [168], count: 9, mean: ... }Accessibility
- The
titleprop is used asaria-label; a description with each group's median and middle half is generated whendescriptionis omitted - The five-number summary per group is rendered as a screen-reader table (
showDataTable) - Tooltips list high, Q3, median, Q1, low and the group size
- Animations respect
prefers-reduced-motion
Related Charts
- HistogramChart - Distribution of one set of values
- DotPlotChart - One value per category
- ScatterChart - Relationships between values