Skip to content
weftGitHub

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/warp

Usage

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

PropTypeDefaultDescription
titlestring—The heading.
level2 | 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.
descriptionunknown—One supporting line under the title.
toolbarunknown—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.
loadingstring—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.
actionunknown—The next step under an empty or error state: a Retry button.
data{ name: string; points: Point[]; }[]—The series to draw.
summarystring | ((c: { data: { name: string; points: Point[]; }[]; title: strin…—One sentence for screen readers and the page; generated from the data when absent.
xNamestring—The horizontal measure, for the axis, tooltips and the table.
yNamestring—The vertical measure, for the axis, tooltips and the table.
sizeNamestring—What the size means, for tooltips and the table.
formatFmt—Turns a value into the text shown.

RelatedScatter chart