Components
Explore the relationship between two measurements. Group observations by color or use bubble area to show a third value.
npx mario-charts@latest add scatter-plotCompare points, bubbles, viewports, and trends.
The same chart through every state.
Illustrative spend and revenue · USD thousands
Waiting for chart space
Hover or tap to inspect. Left/Right follows X order; Up/Down switches channel. Enter selects.
import { ScatterPlot } from "@/components/charts/scatter-plot";
const data = [
{ campaign: "Launch", channel: "Search", spend: 2, revenue: 8, leads: 100 },
{ campaign: "Spring", channel: "Search", spend: 8, revenue: 25, leads: 400 },
{ campaign: "Discovery", channel: "Social", spend: 3, revenue: 7, leads: 75 },
{ campaign: "Retargeting", channel: "Social", spend: 10, revenue: 22, leads: 300 },
];
export function Campaigns() {
return <ScatterPlot data={data} x="spend" y="revenue" label="campaign"
series="channel" size="leads" sizeScale="area" sizeRange={[4, 24]}
xLabel="Spend ($k)" yLabel="Revenue ($k)" sizeLabel="Leads"
showLegend showGrid height={400} ariaLabel="Campaign performance" />;
}Coordinates represent observations and stay fixed during entrance and inspection. Bubbles grow at their own coordinates. Area scaling makes four times the value produce twice the radius, except where the minimum positive radius improves visibility. A zero size has no painted area and remains available through keyboard inspection.
Explicit domains define the visible window. Outside observations retain their original row indices and still contribute to per-series trend lines. The chart reports how many points are outside the window; clipped points never become invisible keyboard stops.
Trend lines describe a linear relationship and do not imply causation. Fits stop at the observed X extent. A single point or a series with identical X coordinates has no fitted line. Normalize missing values before rendering instead of silently discarding observations.
| Prop | Type | Default | Description |
|---|---|---|---|
dataRequired | readonly T[] | — | Observations with finite coordinates. Missing and malformed numbers produce an actionable row/key error. |
x / yRequired | keyof T | — | Numeric coordinate keys, inferred from the observation shape. |
label | keyof T | — | Point name for tooltips, focus, and the accessible table. Defaults to Point N. |
series | keyof T | — | Group/color key. Original group order stays stable when the viewport excludes some observations. |
size | keyof T | number | 6 | A fixed radius in pixels or a bubble-value key. Keyed values must be finite and nonnegative; zero retains inspection without painted area. |
sizeScale | 'area' | 'radius' | 'area' | Area uses the square root of value/max, with a minimum positive radius for visibility. Radius preserves the previous linear mapping between observed minimum and maximum. |
sizeRange | readonly [number, number] | [4, 40] | Minimum positive and maximum bubble radii in pixels. Only applies when size is a data key. |
xDomain / yDomain | readonly [number, number] | — | Finite increasing viewport bounds. Outside points are clipped, removed from keyboard navigation, and counted visibly; the source data is retained. |
showTrendLine | boolean | false | Per-series linear fit using all observations, clipped to the viewport and limited to observed X. Omitted for insufficient X variation or unrepresentable coefficients. |
trendLineColor | string | — | Override trend stroke color; otherwise use the series color. |
showGrid | boolean | false | Show reference lines only at ticks within the displayed domains. |
gridStyle | 'solid' | 'dashed' | 'dotted' | 'dashed' | Reference-grid line style. |
showLegend | boolean | false | Wrapping legend within the total chart height. |
height | number | 300 | Total frame height in every state, including legend and any viewport notice. |
loading | boolean | false | Retain observations for a skeleton with identical positions and radii. Without data, show a neutral placeholder. |
error | string | null | null | Error inside the persistent chart frame. |
animation | boolean | true | Grow radii at fixed coordinates. Grid and trends stay still; keyboard focus completes entrance. Respects reduced motion. |
xLabel / yLabel / sizeLabel | string | 'X' / 'Y' / 'Size' | Axis and inspection labels, including units when relevant. |
xFormatter / yFormatter / sizeFormatter | (value: number) => string | formatValue | Format ticks, inspection, accessible names, and source observations. |
onPointClick | (data: T, index: number, series?: string) => void | — | Original row/index and series key, from pointer or Enter/Space. Without it, points advertise inspection rather than a button action. |
tooltipRenderer | TooltipRenderer<ScatterPlotTooltipData<T>> | — | Custom tooltip with original data, index, label, numeric/formatted coordinates, bubble value, series key, and color. |
ariaLabel / description | string | — | Accessible chart name and context for interpreting the observations. |
colors | readonly string[] | DEFAULT_COLORS | Series colors in first-appearance order. |
className | string | — | Classes for the persistent outer frame. |