# Box Plot

> How the values of several groups are spread: the median, the middle half, the range and the outliers of each, side by side.

Source: https://ngwr.dev/charts/boxplot-chart  
Added in v15.1

## Installation

Import the class, and `@use` the entry point in your global styles: without it the component renders unstyled.

```typescript
import { Component } from '@angular/core';
import { WrBoxplotChart } from 'ngwr/charts/boxplot-chart';

@Component({ imports: [WrBoxplotChart] })
export class MyComponent {}
```

```scss
@use 'ngwr/charts/boxplot-chart';
```

## Basic

Pass each group's raw `values`. The chart works out the quartiles, the whiskers and the outliers. The value axis fits the data and is not forced to zero.

```angular-html
<wr-boxplot-chart
  ariaLabel="Response time by region"
  xLabel="Region"
  yLabel="Response time, ms"
  [groups]="[
    { label: 'Europe', values: [96, 102, 108, 111, 115, 290] },
    { label: 'Asia', values: [120, 131, 140, 148, 155, 161] }
  ]"
/>
```

## Reading a box

Quartiles use linear interpolation: type 7, the default in R and NumPy, and Excel's QUARTILE.INC. Whiskers follow Tukey's rule.

```angular-html
<wr-boxplot-chart
  ariaLabel="Eleven values, one outlier"
  [groups]="[{ label: 'Sample', values: [12, 14, 15, 17, 18, 19, 21, 22, 24, 27, 48] }]"
/>
```

| Mark | Means | Here |
| --- | --- | --- |
| Box | The first quartile to the third: the middle half of the values. | 16 to 23 |
| Line in the box | The median. | 19 |
| Whiskers | The farthest values within 1.5 × the box's height (the IQR) of the box. | 12 and 27 |
| Dots | Outliers: values past the whiskers' reach. | 48, past 23 + 1.5 × 7 |

## Precomputed stats

Already have the summary? Pass `stats` instead of `values`. It is drawn as given. A group's `color` overrides the chart's.

```angular-html
<wr-boxplot-chart ariaLabel="Build time by release" yLabel="Build time, s" [groups]="releases" />
```

```angular-ts
releases: WrBoxplotGroup[] = [
  { label: 'v14', stats: { min: 80, q1: 101, median: 118, q3: 134, max: 170, outliers: [240, 262] } },
  { label: 'v15', stats: { min: 70, q1: 92, median: 104, q3: 121, max: 150, outliers: [31] } },
  { label: 'v15.1', stats: { min: 61, q1: 80, median: 90, q3: 101, max: 128 }, color: 'var(--wr-color-success)' },
];
```

## Number format

Numbers follow `LOCALE_ID`. `valueFormat` replaces it for the ticks, the tooltip and the data table.

```angular-html
<wr-boxplot-chart ariaLabel="Build time by release" yLabel="Build time" [groups]="releases" [valueFormat]="seconds" />
```

```angular-ts
const unit = new Intl.NumberFormat('en-US', { style: 'unit', unit: 'second' });

seconds = (value: number): string => unit.format(value);
```

## Data table

`dataTable` adds a table only screen readers reach: a row per group, its five numbers and its outliers. Nothing changes on screen.

```angular-html
<wr-boxplot-chart ariaLabel="Response time by region" dataTable [groups]="regions" />
```

## Accessibility

| Part | Behaviour |
| --- | --- |
| Plot | One `role="img"`, named by `ariaLabel`. No tab stop. |
| Values | Only in the tooltip, unless `dataTable` is on. |
| Groups | Named under their boxes. Colour carries nothing the name does not. |
| Tooltip | Pointer only. `Escape` closes it. |
| Forced colours | Every mark is drawn as an outline in the system text colour. |

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `groups` | One entry per box, in reading order: each with its raw `values` or a `stats` summary worked out elsewhere. A group with neither, or with nothing finite to summarise, keeps its slot and its name and draws no box. | `readonly WrBoxplotGroup[]` | `[]` |
| `ariaLabel` | Accessible name of the chart. The numbers are nowhere in text unless `dataTable` puts them there, so say what the chart shows. Falls back to `boxplotChart.label` ("Box plot"). | `string \| null` | `null` |
| `xLabel` | What the groups are — a region, a release. Drawn under the group names only when given; either way it heads the group column of the data table, which falls back to `boxplotChart.group` ("Group"). | `string \| null` | `null` |
| `yLabel` | What the values measure, with their unit. Drawn above the value axis only when given. | `string \| null` | `null` |
| `valueFormat` | Writes every number the chart shows: the axis ticks, the tooltip and the data table. `null` uses `Intl.NumberFormat` in `LOCALE_ID`, with compact ticks (`1.2K`, `3.4M`) unless the full numbers are shorter. | `((value: number) => string) \| null` | `null` |
| `color` | The colour of every group with no `color` of its own. Any CSS colour. | `string` | `'var(--wr-color-primary)'` |
| `height` | The plot's height in px, at least 80. Under 160 the value axis aims for fewer ticks, so their labels keep clear of one another. | `number` | `240` |
| `showGrid` | Show the gridlines and the value axis' tick labels. | `boolean` | `true` |
| `tooltip` | Show a tooltip with the hovered group's five numbers — the whiskers' ends, the quartiles and the median — and its outliers' values, the lowest three, then how many more there are. Pointer only. | `boolean` | `true` |
| `dataTable` | Render every group's numbers as a table only assistive technology reaches, beside the drawing: a row per group, a column for each of the five numbers from the lower whisker up and, when a group has any, one listing its outliers. The drawing is one named image, so without it the numbers are nowhere a screen reader can walk. | `boolean` | `false` |

## Types

```angular-ts
interface WrBoxplotGroup {
  label: string;
  values?: readonly number[];
  stats?: WrBoxplotStats;
  color?: string;
}

interface WrBoxplotStats {
  min: number;
  q1: number;
  median: number;
  q3: number;
  max: number;
  outliers?: readonly number[];
}
```

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `WrBoxplotGroup` | One box. | `interface` | — |
| `label`required | The group name: under its box, in the tooltip and the data table. | `string` | — |
| `values` | Raw values to summarise. A non-finite value is left out. Ignored when `stats` is given. | `readonly number[]` | `undefined` |
| `stats` | A summary worked out elsewhere, drawn as given. | `WrBoxplotStats` | `undefined` |
| `color` | Any CSS colour. | `string` | ``the chart's `color``` |
| `WrBoxplotStats` | The five numbers and the outliers. | `interface` | — |
| `min`required | The lower whisker’s end: the smallest value that is not an outlier. | `number` | — |
| `q1`required | The first quartile: the box’s lower edge. | `number` | — |
| `median`required | The line across the box. | `number` | — |
| `q3`required | The third quartile: the box’s upper edge. | `number` | — |
| `max`required | The upper whisker’s end: the largest value that is not an outlier. | `number` | — |
| `outliers` | Values drawn as dots past the whiskers. | `readonly number[]` | `undefined` |

## CSS variables

Set these on the component's selector or a wrapper, not on `:root`: the defaults are declared on `ngwr/charts/boxplot-chart`'s own element.

| Variable | Default | Declared on |
| --- | --- | --- |
| `--wr-boxplot-chart-active-bg` | `color-mix(in srgb, var(--wr-color-on-surface) 6%, transparent)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-box-radius` | `var(--wr-border-radius-sm)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-box-tint` | `20%` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-box-tint-active` | `40%` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-box-width` | `min(3rem, 60%)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-cap-width` | `calc(var(--wr-boxplot-chart-box-width) / 2)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-color` | `var(--wr-color-on-surface)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-font-family` | `var(--wr-font-family-base)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-grid-color` | `color-mix(in srgb, var(--wr-border-base) 70%, transparent)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-label-color` | `var(--wr-color-on-surface)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-label-font-size` | `var(--wr-text-xs)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-label-gap` | `var(--wr-space-xs)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-label-line-height` | `var(--wr-text-xs-leading)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-line-width` | `2px` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-median-color` | `var(--wr-color-on-surface)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-median-width` | `3px` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-outlier-fill` | `var(--wr-color-surface)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-outlier-size` | `0.5rem` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-plot-inset-x` | `var(--wr-space-sm)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-plot-inset-y` | `var(--wr-space-sm)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-tick-color` | `var(--wr-color-on-surface-muted)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-tick-font-size` | `var(--wr-text-xs)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-tick-gap` | `var(--wr-space-xs)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-tick-line-height` | `var(--wr-text-xs-leading)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-title-color` | `var(--wr-color-on-surface-muted)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-title-font-size` | `var(--wr-text-xs)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-title-font-weight` | `var(--wr-font-weight-medium)` | `.wr-boxplot-chart` |
| `--wr-boxplot-chart-title-gap` | `var(--wr-space-xs)` | `.wr-boxplot-chart` |

## Dependencies

| Built on | [Popover](https://ngwr.dev/reference/components/popover) |
| --- | --- |

## See also

- [Scatter Chart](https://ngwr.dev/charts/scatter-chart) — Points on two numeric axes.
- [Candlestick Chart](https://ngwr.dev/charts/candlestick-chart) — Prices over time (OHLC): a candle per period, its wick from the low to the high and its body from the open to the close.
- [Bar Chart](https://ngwr.dev/charts/bar-chart) — Bars for one or several series, grouped or stacked, standing up or lying along a row, with lines over them.
- [Colors](https://ngwr.dev/guides/tokens/colors) — The --wr-color-* tokens, and which one to use for fills, text and borders.
- [Popover](https://ngwr.dev/reference/components/popover) — Show a template, or a text tooltip, next to its trigger.
