Skip to content
kerfjsGitHub

ScatterChart

Plots items by two measures, to show a relationship between them.

SourcePackage @kerf-js/veneer

Preview

tsx
import { ScatterChart } from '@kerf-js/veneer'export function Projects() {  return (  <ScatterChart    title="Busy projects stay fast"    description="Each dot is one project"    data={PROJECT_POINTS}    xName="Deploys"    yName="Latency (ms)"  />  )}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 @kerf-js/veneer

Usage

tsx
import { ScatterChart } from '@kerf-js/veneer'<ScatterChart  title="Busy projects stay fast"  description="Each dot is one project"  data={PROJECT_POINTS}  xName="Deploys"  yName="Latency (ms)"/>

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.
yNamestring—The vertical measure.
sizeNamestring—What a point's size means, for tooltips and the table.
formatFmt—Turns a value into the text shown.

RelatedBubble chart