BubbleChart
A scatter chart with a third measure as the size of each point.
SourcePackage @weft-js/warp
Preview
tsx
import { BubbleChart } from '@weft-js/warp'export function Projects() { return ( <BubbleChart title="Deploys, latency and cost" description="Bigger bubbles cost more" data={PROJECT_POINTS} xName="Deploys" yName="Latency (ms)" sizeName="Cost ($100s)" /> )}type Status = 'Live' | 'Building' | 'Failed' | 'Paused'const PROJECTS: { id: string; name: string; owner: string; region: string; status: Status; deploys: number; uptime: number; latency: number; cost: number; updated: string }[] = [ { id: 'storefront', name: 'storefront', owner: 'Priya Raman', region: 'eu-west', status: 'Live', deploys: 412, uptime: 99.98, latency: 84, cost: 1240, updated: '2026-10-31' }, { id: 'checkout', name: 'checkout', owner: 'Tomás Oliveira', region: 'eu-west', status: 'Live', deploys: 288, uptime: 99.95, latency: 112, cost: 980, updated: '2026-10-31' }, { id: 'search-api', name: 'search-api', owner: 'Lena Fischer', region: 'us-east', status: 'Building', deploys: 196, uptime: 99.91, latency: 146, cost: 1610, updated: '2026-10-30' }, { id: 'billing', name: 'billing', owner: 'Mara Lindqvist', region: 'us-east', status: 'Live', deploys: 154, uptime: 99.99, latency: 73, cost: 720, updated: '2026-10-29' }, { id: 'mobile-bff', name: 'mobile-bff', owner: 'Sam Okafor', region: 'ap-south', status: 'Failed', deploys: 233, uptime: 99.42, latency: 208, cost: 860, updated: '2026-10-29' }, { id: 'notifier', name: 'notifier', owner: 'Jun Tanaka', region: 'eu-north', status: 'Live', deploys: 97, uptime: 99.97, latency: 58, cost: 310, updated: '2026-10-27' }, { id: 'reports', name: 'reports', owner: 'Noor Haddad', region: 'us-west', status: 'Paused', deploys: 41, uptime: 99.8, latency: 321, cost: 190, updated: '2026-10-22' }, { id: 'edge-cache', name: 'edge-cache', owner: 'Jun Tanaka', region: 'global', status: 'Live', deploys: 318, uptime: 100, latency: 21, cost: 1430, updated: '2026-10-31' }, { id: 'auth', name: 'auth', owner: 'Mara Lindqvist', region: 'eu-west', status: 'Live', deploys: 176, uptime: 99.99, latency: 66, cost: 540, updated: '2026-10-28' }, { id: 'ingest', name: 'ingest', owner: 'Lena Fischer', region: 'us-east', status: 'Live', deploys: 264, uptime: 99.93, latency: 131, cost: 2120, updated: '2026-10-30' },]const REGION_GROUP: Record<string, string> = { 'eu-west': 'Europe', 'eu-north': 'Europe', 'us-east': 'Americas', 'us-west': 'Americas' }const pointsIn = (group: string) => PROJECTS.filter(p => (REGION_GROUP[p.region] ?? 'Elsewhere') === group).map(p => ({ name: p.name, x: p.deploys, y: p.latency, size: Math.round(p.cost / 100) }))const PROJECT_POINTS = ['Europe', 'Americas', 'Elsewhere'].map(name => ({ name, points: pointsIn(name) }))const ms = (v: number) => `${Math.round(v)} ms`Installation
npm install @weft-js/warpUsage
tsx
import { BubbleChart } from '@weft-js/warp'<BubbleChart title="Deploys, latency and cost" description="Bigger bubbles cost more" data={PROJECT_POINTS} xName="Deploys" yName="Latency (ms)" sizeName="Cost ($100s)" />Accessibility
- Every chart has a text alternative and a table view of its numbers, so nothing depends on seeing the marks. See Chart for its keyboard support.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | — | The heading. |
level | 2 | 3 | 4 | 6 | 5 | — | The title's heading level: one below the heading the chart sits under. Default 3, a chart in a page section. |
description | unknown | — | One supporting line under the title. |
toolbar | unknown | — | Beside the view toggle: a layout switch, a range picker. |
state | "error" | "loading" | "empty" | — | Replaces the plot, in the same frame. With no data the frame shows empty on its own. |
loading | string | — | Shows that work is under way. |
empty | { title: string; detail?: unknown; } | — | The title and detail shown in place of the plot when there is no data. |
error | { title: string; detail?: unknown; } | — | A message that marks the field invalid and says why. |
action | unknown | — | The next step under an empty or error state: a Retry button. |
data | { name: string; points: Point[]; }[] | — | The series to draw. |
summary | string | ((c: { data: { name: string; points: Point[]; }[]; title: strin… | — | One sentence for screen readers and the page; generated from the data when absent. |
xName | string | — | The horizontal measure, for the axis, tooltips and the table. |
yName | string | — | The vertical measure, for the axis, tooltips and the table. |
sizeName | string | — | What the size means, for tooltips and the table. |
format | Fmt | — | Turns a value into the text shown. |
RelatedScatter chart