caliper uidocs

Bubble timeline

Pro

A scatter that moves through time: bubbles placed by two measures and sized by a third. Play, pause, scrub, or choose a name to trace its path. It never starts on its own.

Installs components/ui/bubble-timeline.tsxDepends on @radix-ui/react-slot, d3-shape, lucide-reactMotion shared motion tokens
pnpm dlx shadcn@latest add @caliper/bubble-timeline
Markets by customers and gross margin, 2024 to 2026
Q1 ’24

Q1 ’24

Markets by customers and gross margin, 2024 to 2026
FrameNameCustomers (hundreds)Gross marginARR
Q1 ’24Germany2048120
Q1 ’24France3152.4160
Q1 ’24United Kingdom3346.9200
Q1 ’24United States3841.1900
Q1 ’24Canada4456.6280
Q1 ’24Brazil4548.7320
Q1 ’24Japan5435.7360
Q1 ’24Australia6760.6400
Q2 ’24Germany2552.2130
Q2 ’24France3651.8173
Q2 ’24United Kingdom3845.5216
Q2 ’24United States4046.4972
Q2 ’24Canada4755.5302
Q2 ’24Brazil5148.1346
Q2 ’24Japan5839.3389
Q2 ’24Australia7261.6432
Q3 ’24Germany2956.1139
Q3 ’24France3950.7186
Q3 ’24United Kingdom4144.9232
Q3 ’24United States4251.71044
Q3 ’24Canada5153.5325
Q3 ’24Brazil5648.3371
Q3 ’24Japan6343.2418
Q3 ’24Australia7661.6464
Q4 ’24Germany3359.5149
Q4 ’24France4349198
Q4 ’24United Kingdom4545.2248
Q4 ’24United States4456.81116
Q4 ’24Canada5550.9347
Q4 ’24Brazil6249.2397
Q4 ’24Japan6747.1446
Q4 ’24Australia8060.8496
Q1 ’25Germany3762.1158
Q1 ’25France4647.2211
Q1 ’25United Kingdom4846.3264
Q1 ’25United States4761.31188
Q1 ’25Canada5947.9370
Q1 ’25Brazil6951422
Q1 ’25Japan7150.8475
Q1 ’25Australia8359.2528
Q2 ’25Germany4063.8168
Q2 ’25France4845.5224
Q2 ’25United Kingdom5248.2280
Q2 ’25United States5065.11260
Q2 ’25Canada6444.6392
Q2 ’25Brazil7553.6448
Q2 ’25Japan7554504
Q2 ’25Australia8657.3560
Q3 ’25Germany4264.6178
Q3 ’25France5144.1237
Q3 ’25United Kingdom5650.8296
Q3 ’25United States5468.11332
Q3 ’25Canada6941.4414
Q3 ’25Brazil8157.1474
Q3 ’25Japan7856.4533
Q3 ’25Australia8955.1592
Q4 ’25Germany4564.4187
Q4 ’25France5343.4250
Q4 ’25United Kingdom6153.7312
Q4 ’25United States5870.11404
Q4 ’25Canada7538.6437
Q4 ’25Brazil8661.1499
Q4 ’25Japan8058562
Q4 ’25Australia9152.9624
Q1 ’26Germany4663.4197
Q1 ’26France5643.4262
Q1 ’26United Kingdom6656.9328
Q1 ’26United States6271.21476
Q1 ’26Canada7936.4459
Q1 ’26Brazil9165.6525
Q1 ’26Japan8258.7590
Q1 ’26Australia9451.2656
Q2 ’26Germany4861.7206
Q2 ’26France5944.4275
Q2 ’26United Kingdom7259.9344
Q2 ’26United States6771.51548
Q2 ’26Canada8435482
Q2 ’26Brazil9670.2550
Q2 ’26Japan8458.5619
Q2 ’26Australia9750688
Q3 ’26Germany5059.5216
Q3 ’26France6346.4288
Q3 ’26United Kingdom7862.5360
Q3 ’26United States7171.11620
Q3 ’26Canada8834.6504
Q3 ’26Brazil10074.6576
Q3 ’26Japan8657.5648
Q3 ’26Australia10049.6720
Q4 ’26Germany5257.1226
Q4 ’26France6649.4301
Q4 ’26United Kingdom8464.5376
Q4 ’26United States7570.21692
Q4 ’26Canada9235.1526
Q4 ’26Brazil10478.6602
Q4 ’26Japan8855.9677
Q4 ’26Australia10450.2752

When to use #

Use it for

  • Accounts or markets changing over quarters.
  • Presentations where the movement is the point.

Skip it when

  • Reading exact values; use the table or a line chart.
  • More than about 20 bubbles.

Installation #

terminal
pnpm dlx shadcn@latest add @caliper/bubble-timeline

Adds its 7 files to components/ui/, each with its own stylesheet, and installs their packages. Pro installs with your access token, set up once per project. See Pro access. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

Import it from your copy of the source. The example behind the preview comes with the source.

example.tsx
import { BubbleTimeline } from "@/components/ui/bubble-timeline"

The worked example comes with Pro

The 37-line example behind the preview opens here with a Pro or Team licence.

Checking your licence…

API reference #

BubbleTimeline

component
PropTypeDefaultDescription
label *string—
entities *readonly BubbleEntity[]—
frames *readonly BubbleFrame[]—
groupsreadonly ChartSeries[]—
xLabel *string—
yLabel *string—
sizeLabel *string—
formatX((value: number) => string)numberText
formatY((value: number) => string)numberText
formatSize((value: number) => string)numberText
intervalnumber900Milliseconds per frame while playing.
heightnumber340
loadingboolean—
errorstring—
classNamestring—

Accessibility #

It exposes group and status semantics, with aria-label, aria-busy, aria-hidden, aria-valuetext and aria-pressed kept in step with state. Changes that matter are announced through a live region.

No custom key handling; Tab and the native activation keys do the work.

Motion #

Transitions use the shared duration and easing tokens. Under prefers-reduced-motion those tokens collapse to instant and travel distances go to zero, so state changes still happen without movement.