import { Component } from '@angular/core';
import { WrScatterChart } from 'ngwr/charts/scatter-chart';
@Component({ imports: [WrScatterChart] })
export class MyComponent {}Scatter Chart
Points on two numeric axes. An optional size per point makes it a bubble chart.
Installation
Import the class, and @use the entry point in your global styles: without it the component renders unstyled.
Basic
Neither axis is forced to include zero. Each fits its data and snaps to round numbers.
<wr-scatter-chart
xLabel="Price"
yLabel="Rating"
[series]="[{ label: 'Headphones', data: [{ x: 49, y: 3.6 }, { x: 129, y: 4.2 }] }]"
/>Several series
Each series takes the next palette colour and the next marker shape, so the shape tells them apart too.
<wr-scatter-chart xLabel="Weight, kg" yLabel="Battery, h" [series]="devices" />Bubbles
size is drawn as the marker's area: the largest at maxRadius, none under 4px. Bubbles are see-through, since they overlap. label names a point.
<wr-scatter-chart
xLabel="Visitors a day"
yLabel="Revenue, k$"
sizeLabel="Floor area, m²"
[series]="stores"
/>stores: WrScatterSeries[] = [
{
label: 'City centre',
data: [
{ x: 1450, y: 62, size: 320, label: 'Harbour' },
{ x: 1720, y: 71, size: 410, label: 'Old Town' },
],
},
];Number format
Numbers follow LOCALE_ID. valueFormat replaces it, and its second argument says which number it writes: 'x', 'y' or 'size'.
<wr-scatter-chart xLabel="Price" yLabel="Rating" [series]="products" [valueFormat]="format" />const usd = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
format = (value: number, axis: WrScatterAxis): string =>
axis === 'x' ? usd.format(value) : value.toFixed(1) + ' ★';Toggle series
toggleableLegend makes each legend row a button. A hidden series leaves the points, both axes, the tooltip and the data table.
<wr-scatter-chart [series]="devices" toggleableLegend [(hiddenSeries)]="hidden" />hidden = signal<readonly number[]>([]);Data table
dataTable renders every value as a table only screen readers reach: a group per series, a row per point. Nothing changes on screen.
<wr-scatter-chart ariaLabel="Weight against battery life" dataTable [series]="devices" />Accessibility
| Part | Behaviour |
|---|---|
| Plot | One role="img", named by ariaLabel. No tab stop. |
| Values | Only in the tooltip, unless dataTable is on. |
| Series | Told apart by marker shape as well as colour. |
| Tooltip | Pointer only. Escape closes it. |
| Forced colours | Points keep their colours. Their ring takes the page colour. |
Many points
Hover measures every point. Keep a chart to a few thousand points, or bin them first.
API
| Name | Description | Type | Default |
|---|---|---|---|
series | One entry per series. A series with no color takes the next entry from the chart's palette, and every series takes the next marker shape, so several series are told apart unconfigured. | readonly WrScatterSeries[] | [] |
ariaLabel | Accessible name of the chart. The legend carries the series NAMES only — the values are nowhere in text unless dataTable puts them there — so say what the chart shows. Falls back to scatterChart.label ("Scatter chart"). | string | null | null |
xLabel | The x axis' name. Drawn under the axis only when given; either way it names the x row of the tooltip and the x column of the data table, which fall back to scatterChart.x ("X"). | string | null | null |
yLabel | The y axis' name. Drawn above the axis only when given; either way it names the y row of the tooltip and the y column of the data table, which fall back to scatterChart.y ("Y"). | string | null | null |
sizeLabel | What a point's size measures. It names the size row of the tooltip and the size column of the data table, which appear only when a point has a size, and falls back to scatterChart.size ("Size"). | string | null | null |
valueFormat | Writes every number the chart shows — the axis ticks, the tooltip and the data table — and is told which number it is writing: 'x', 'y' or 'size', so the two axes can carry different units. A (value) => string written for another chart fits too. null uses Intl.NumberFormat in LOCALE_ID, with compact ticks (1.2K, 3.4M) unless the full numbers are shorter. | ((value: number, axis: WrScatterAxis) => string) | null | null |
height | The plot's height in px, at least 80. | number | 240 |
showGrid | Show the gridlines and the tick labels of both axes. | boolean | true |
showLegend | Show the legend above the chart. | boolean | true |
toggleableLegend | Make each legend row a toggle button that shows and hides its series, through hiddenSeries. A row is a <button aria-pressed>, pressed while its series is shown, so the legend becomes one tab stop per series. | boolean | false |
hiddenSeries | The positions in series of the series that are hidden. Positions rather than labels, since two series may share a label. A toggleable legend writes it, and a host may bind it with or without one: [(hiddenSeries)]. A hidden series is left out of everything that reads its values: it draws no points, the tooltip cannot land on them, the data table drops its rows, and both axes and the bubble scale are fitted to the series still shown, so hiding an outlier lets the rest fill the plot. Its legend row stays, struck through, so it can be shown again. With every series hidden the plot is the empty 0 to 1 frame. A position past the end of series is kept and ignored. | readonly number[] | [] |
tooltip | Show a tooltip with the series, x, y and size of the point under the pointer. Pointer only. | boolean | true |
dataTable | Render every point's values as a table only assistive technology reaches, beside the drawing: one group of rows per series shown, headed by the series' name, a row per point, and a column for x, for y and, when a point has one, for size. The drawing is one named image, so without it the values are nowhere a screen reader can walk. | boolean | false |
maxRadius | The radius, in px, the largest size shown is drawn at. Every other sized point is scaled by AREA against it — a point of half the size has half the area, not half the radius — and none is drawn under 4px. At least 4. | number | 20 |
Types
interface WrScatterSeries {
label: string;
data: readonly WrScatterPoint[];
color?: string;
}
interface WrScatterPoint {
x: number;
y: number;
size?: number;
label?: string;
}
type WrScatterAxis = 'x' | 'y' | 'size';| Name | Description | Type | Default |
|---|---|---|---|
WrScatterSeries | One series of points. | interface | — |
labelrequired | The series name: legend, tooltip, data table. | string | — |
datarequired | The points, in any order. | readonly WrScatterPoint[] | — |
color | Any CSS colour. | string | palette |
WrScatterPoint | One point. | interface | — |
xrequired | Position on the x axis. A non-finite point is not drawn. | number | — |
yrequired | Position on the y axis. | number | — |
size | Drawn as the marker's area. The largest is drawn at maxRadius. | number | undefined |
label | The point's name, in the tooltip and as its data table row. | string | undefined |
WrScatterAxis | Which number valueFormat writes. | 'x' | 'y' | 'size' | — |
CSS variables
Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/charts/scatter-chart's own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-scatter-chart-bubble-opacity | 0.7 | .wr-scatter-chart |
--wr-scatter-chart-color | var(--wr-color-on-surface) | .wr-scatter-chart |
--wr-scatter-chart-font-family | var(--wr-font-family-base) | .wr-scatter-chart |
--wr-scatter-chart-grid-color | color-mix(in srgb, var(--wr-border-base) 70%, transparent) | .wr-scatter-chart +1 variant override |
--wr-scatter-chart-halo-width | 2px | .wr-scatter-chart |
--wr-scatter-chart-legend-margin-bottom | var(--wr-space-md) | .wr-scatter-chart |
--wr-scatter-chart-plot-inset-x | var(--wr-space-md) | .wr-scatter-chart |
--wr-scatter-chart-plot-inset-y | var(--wr-space-sm) | .wr-scatter-chart |
--wr-scatter-chart-point-opacity | 1 | .wr-scatter-chart +1 variant override |
--wr-scatter-chart-point-ring | var(--wr-color-surface) | .wr-scatter-chart +1 variant override |
--wr-scatter-chart-point-ring-width | 1px | .wr-scatter-chart |
--wr-scatter-chart-tick-color | var(--wr-color-on-surface-muted) | .wr-scatter-chart |
--wr-scatter-chart-tick-font-size | var(--wr-text-xs) | .wr-scatter-chart |
--wr-scatter-chart-tick-gap | var(--wr-space-xs) | .wr-scatter-chart |
--wr-scatter-chart-tick-line-height | var(--wr-text-xs-leading) | .wr-scatter-chart |
--wr-scatter-chart-title-color | var(--wr-color-on-surface-muted) | .wr-scatter-chart |
--wr-scatter-chart-title-font-size | var(--wr-text-xs) | .wr-scatter-chart |
--wr-scatter-chart-title-font-weight | var(--wr-font-weight-medium) | .wr-scatter-chart |
--wr-scatter-chart-title-gap | var(--wr-space-xs) | .wr-scatter-chart |
Dependencies
| Built on | Chart Legend, Popover |
|---|
See also
Component Line ChartOne or more series of values as lines or as an area chart, overlaid or stacked.Component Bar ChartBars for one or several series, grouped or stacked, standing up or lying along a row, with lines over them.Component Box PlotHow the values of several groups are spread: the median, the middle half, the range and the outliers of each, side by side.Component Radar ChartSeveral series compared across the same axes, as polygons on a polar grid or as polar-area wedges.Guide ColorsThe --wr-color-* tokens, and which one to use for fills, text and borders.Component Chart LegendA chart's key: a swatch, a name and a value per series.Component PopoverShow a template, or a text tooltip, next to its trigger.