Scatter Documentation has not yet been reviewed by a human.
Draw a mark at each data point. Use size, mark, and stroke to control
its appearance. Set tooltip: true for a tooltip showing the point’s values.
Size and color from data
Use a size accessor to vary mark diameter and a color accessor to highlight larger values. An outline keeps overlapping bubbles distinct.
import { scatter, type APlotElement } from '@antadesign/plot/browser'import '@antadesign/plot/elements/a-plot'import '@antadesign/plot/plot.css'
const plot = document.createElement('a-plot') as APlotElement
const data = Array.from({ length: 24 }, (_, i) => ({ x: 12 + (i * 17 % 83), y: 15 + (i * 31 % 72), volume: 20 + (i * 43 % 180),}))
plot.plotArgs = { series: [scatter({ data, size: row => (5 + Math.sqrt(Number(row.volume)) * 1.8) * 1.3, color: row => Number(row.volume) > 120 ? { light: '#e76f51', dark: '#fda489' } : { light: '#0891b2', dark: '#67e8f9' }, stroke: { color: { light: '#ffffff', dark: '#151b28' }, width: 2 }, tooltip: ({ row }) => document.createTextNode('Volume: ' + row.volume), })], height: 260, margin: { top: 12, right: 12, bottom: 28, left: 36 }, axis: { x: { min: 0, max: 110, label: '' }, y: { min: 0, max: 100, label: '' } }, background: { light: '#ffffff', dark: '#151b28' }, chrome_color: { light: '#e2e8f0', dark: '#334155' }, border: false, zoom_pan: false,}
document.body.append(plot)Mark shapes and outlines
Use different marks to distinguish groups without relying on color alone. Each series sets its own shape, size, and stroke.
import { scatter, type APlotElement } from '@antadesign/plot/browser'import '@antadesign/plot/elements/a-plot'import '@antadesign/plot/plot.css'
const plot = document.createElement('a-plot') as APlotElement
const data = Array.from({ length: 18 }, (_, i) => ({ x: 10 + i * 4.5, y: 18 + i * 2.5 + Math.sin(i * 2.1) * 12,}))
plot.plotArgs = { series: [ scatter({ data, mark: 'square', size: 11, color: { light: '#c4b5fd', dark: '#8b5cf6' }, stroke: { color: { light: '#6d28d9', dark: '#ddd6fe' }, width: 2 }, tooltip: ({ x, y }) => document.createTextNode('Squares: ' + x + ', ' + Math.round(Number(y))), }), scatter({ data: data.map(point => ({ x: point.x + 5, y: 95 - point.y })), mark: 'diamond', size: 13, color: { light: '#99f6e4', dark: '#0d9488' }, stroke: { color: { light: '#0f766e', dark: '#5eead4' }, width: 2 }, tooltip: ({ x, y }) => document.createTextNode('Diamonds: ' + x + ', ' + Math.round(Number(y))), }), ], height: 260, margin: { top: 12, right: 12, bottom: 28, left: 36 }, axis: { x: { min: 0, max: 100, label: '' }, y: { min: 0, max: 100, label: '' } }, background: { light: '#ffffff', dark: '#151b28' }, chrome_color: { light: '#e2e8f0', dark: '#334155' }, border: false, zoom_pan: false,}
document.body.append(plot)Scatter arguments
| Field | Type | Default | Description |
|---|---|---|---|
data |
Record<string, unknown>[] |
Required | Rows used to build the series. |
x? |
FieldArg |
'x' |
Horizontal field name or accessor. |
y? |
FieldArg |
'y' |
Vertical field name or accessor. |
color? |
ColorArg |
Black | Series color; theme pairs provide separate light and dark colors. |
size? |
number | ((row, index, viewport) => number) |
5 |
Mark diameter in pixels, or a per-row accessor. A row’s size takes precedence. |
mark? |
MarkShape |
'circle' |
Mark shape: circle, square, diamond, or triangle. |
stroke? |
StrokeArg |
None | Outline color and optional width. |
tooltip? |
TooltipArg |
None | Use true for the default tooltip, or a callback for custom content. |
on_select? |
SelectFn |
None | Callback receiving the selected point and its source row. |
hoverable? |
boolean |
true |
Allow the series to participate in hit testing. |
highlight? |
boolean |
true |
Draw hover feedback for a hit point. |
highlight_color? |
ColorArg |
Automatic | Exact hover color, including opacity. For custom series, affects only the fallback renderer. Stacked bars also accept a ThemeColor[] palette. |
import { scatter } from '@antadesign/plot'
const series = [scatter({ data: [{ time: 1, value: 3 }, { time: 2, value: 5 }, { time: 3, value: 4 }], x: 'time', y: 'value', color: (row) => Number(row.value) >= 5 ? 'coral' : 'steelblue', size: (row) => Number(row.value) * 2, mark: 'diamond', stroke: { color: 'navy', width: 1 }, tooltip: ({ x, y }) => `(${x}, ${y})`, on_select: ({ row }) => console.log('Selected row:', row), hoverable: true, highlight: true,})]Size
Scatter size accepts a fixed pixel diameter or a pure accessor returning a number.
The accessor receives (row, index, viewport), so you can combine data and viewport
without storing zoom in application state.
Scroll near 50. The first series stays at 4px. The other series alternate between 2px and 4px based on their data, then grow with horizontal zoom, at different rates, up to 16px. Drag to pan; Reset Zoom in the context menu restores the starting sizes.
import { scatter, type PlotArgs } from '@antadesign/plot'import '@antadesign/plot/elements/a-plot'import '@antadesign/plot/plot.css'import type { APlotElement } from '@antadesign/plot/browser'
export function viewportSizes(): PlotArgs<Node> { const labels = ['Fixed 4px', 'Data + gradual zoom', 'Data + faster zoom'] const positions = [0, 10, 25, 40, 45, 48, 49, 49.5, 49.75, 50, 50.25, 50.5, 51, 52, 55, 60, 75, 90, 100] const rows = (label: string) => positions.map((x, i) => ({ x, y: label, weight: i % 2 ? 4 : 2 })) return { height: 260, margin: { top: 24, right: 20, bottom: 48, left: 160 }, axis: { x: { min: 0, max: 100, label: 'Zoom near 50' }, y: { categories: labels, label: '' } }, background: { light: '#ffffff', dark: '#202124' }, chrome_color: { light: '#64748b', dark: '#cbd5e1' }, grid: false, zoom_pan: { x: true, y: false }, series: [ scatter({ data: rows(labels[0]), size: 4, color: { light: '#64748b', dark: '#cbd5e1' }, tooltip: true }), scatter({ data: rows(labels[1]), size: (row, index, viewport) => Math.min(16, Number(row.weight) * viewport.zoom_factor.x ** 0.25), color: { light: '#7c3aed', dark: '#c4b5fd' }, tooltip: true }), scatter({ data: rows(labels[2]), size: (row, index, viewport) => Math.min(16, Number(row.weight) * viewport.zoom_factor.x ** 0.5), color: { light: '#c2410c', dark: '#fdba74' }, tooltip: true }), ], }}
const plot = document.createElement('a-plot') as APlotElementplot.plotArgs = viewportSizes()document.body.append(plot)viewport has the same shape as Viewport changes: x and y
contain visible and full domains (null for a categorical axis), and zoom_factor.x and
zoom_factor.y contain gesture magnification. Each starts at 1. Panning, resizing, and
data-domain changes preserve magnification. Reset and new keyed viewport requests
establish factor 1 on their affected axes. Zooming out beyond a requested initial
window can yield factors below 1. Use Math.max(viewport.zoom_factor.x, viewport.zoom_factor.y)
to follow the more magnified axis.
Size accessors run during composition, including zoom and pan, rather than when
the series is constructed. Keep them pure and inexpensive. Existing accessors
that only read the row or index remain valid. Returned sizes must be finite and
non-negative; invalid results report a composition error and retain the previous
plot. Numeric row size fields take precedence, and the index stays tied to the
original input row after category filtering. Drawing, hit testing, and highlights
reuse the composed sizes. Other series’ size options and font sizes remain numeric.
Shared configuration
See Install and configure to set up Plot. The argument tables describe omitted fields; examples may override these defaults. See Data fields, Series colors, Strokes, and Mark shapes for shared options. For callbacks, see Tooltips and Selection callbacks.