Rect Documentation has not yet been reviewed by a human.
Draw rectangles with explicit bounds. Use x, x2, y, and y2 to select
the fields defining each rectangle’s corners. Rectangles can represent
intervals, regions, or cells in a grid.
Categorical cells
Combine two categorical axes to form a heatmap. Color each cell from its value and use inset to separate neighboring cells.
import { rect, 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 days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']const hours = ['09', '11', '13', '15', '17', '19']const data = days.flatMap((day, d) => hours.map((hour, h) => ({ day, hour, activity: Math.round(20 + 75 * Math.sin(h * 0.8 + d * 0.5) ** 2),})))
plot.plotArgs = { series: [ rect({ data, x: 'hour', y: 'day', inset: 2, color: row => ({ light: 'hsl(174, 65%, ' + (94 - Number(row.activity) * 0.6) + '%)', dark: 'hsl(174, 55%, ' + (16 + Number(row.activity) * 0.4) + '%)', }), tooltip: ({ row }) => document.createTextNode(row.day + ' ' + row.hour + ':00 · ' + row.activity + '%'), }), ], height: 260, margin: { top: 5, right: 8, bottom: 20, left: 38 }, axis: { x: { categories: hours, label: '' }, y: { categories: days, label: '' } }, background: { light: '#ffffff', dark: '#151b28' }, chrome_color: { light: '#e2e8f0', dark: '#334155' }, grid: false, border: false, zoom_pan: false,}
document.body.append(plot)Intervals with explicit bounds
Set x and x2 to show durations within categorical rows. Each rectangle retains its start and end values as the plot resizes.
import { rect, 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 = [ { task: 'Fetch', start: 0.5, end: 3.2 }, { task: 'Parse', start: 2.8, end: 5.1 }, { task: 'Build', start: 4.5, end: 9.4 }, { task: 'Test', start: 7.8, end: 11.2 }, { task: 'Ship', start: 10.8, end: 12.5 },]
plot.plotArgs = { series: [ rect({ data, x: 'start', x2: 'end', y: 'task', inset: 9, color: { light: '#c4b5fd', dark: '#6d28d9' }, stroke: { color: { light: '#7c3aed', dark: '#c4b5fd' }, width: 1 }, hover_span_y: true, tooltip: ({ row }) => document.createTextNode(row.task + ': ' + row.start + '–' + row.end + ' s'), }), ], height: 260, margin: { top: 5, right: 8, bottom: 20, left: 44 }, axis: { x: { min: 0, max: 14, label: '' }, y: { label: '' } }, background: { light: '#ffffff', dark: '#151b28' }, chrome_color: { light: '#e2e8f0', dark: '#334155' }, grid: false, border: false, zoom_pan: false,}
document.body.append(plot)Fixed pixel dimensions
Set size to draw rectangles with a consistent width and height at numeric coordinates. An outline keeps nearby marks distinct.
import { rect, 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: 32 }, (_, i) => ({ x: 8 + (i * 23 % 84), y: 18 + (i * 13 % 65), value: 20 + (i * 17 % 80),}))
plot.plotArgs = { series: [ rect({ data, size: { width: 16, height: 9 }, color: row => Number(row.value) > 65 ? { light: '#c2410c', dark: '#fdba74' } : { light: '#0891b2', dark: '#67e8f9' }, stroke: { color: { light: '#ffffff', dark: '#151b28' }, width: 1 }, tooltip: ({ row }) => document.createTextNode('Value: ' + row.value), }), ], height: 260, margin: { top: 5, right: 8, bottom: 20, left: 30 }, axis: { x: { min: 0, max: 100, label: '' }, y: { min: 0, max: 100, label: '' } }, background: { light: '#ffffff', dark: '#151b28' }, chrome_color: { light: '#e2e8f0', dark: '#334155' }, grid: false, border: false, zoom_pan: false,}
document.body.append(plot)Run history
Place fixed-size rectangles on a time axis in Passed and Failed lanes. Use band_align to anchor both sets of marks to the shared divider, with passing runs above and failures below.
import { rect, 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 start = Date.UTC(2026, 0, 1, 9)const data = Array.from({ length: 36 }, (_, i) => ({ run: i + 1, end_ms: start + (i * 3 + (i % 3)) * 60_000, lane: [5, 6, 14, 23, 24, 25, 32].includes(i) ? 'Failed' : 'Passed',}))
plot.plotArgs = { series: [ rect({ data: data.filter(row => row.lane === 'Passed'), x: 'end_ms', y: 'lane', size: { width: 10, height: 40 }, band_align: 'end', inset: 0, color: { light: '#189e3e', dark: '#4ade80' }, stroke: { color: { light: '#ffffff', dark: '#151b28' }, width: 0.5 }, tooltip: ({ row }) => document.createTextNode('Run ' + row.run + ': ' + row.lane), }), rect({ data: data.filter(row => row.lane === 'Failed'), x: 'end_ms', y: 'lane', size: { width: 10, height: 40 }, band_align: 'start', inset: 0, color: { light: '#c41e5e', dark: '#fb7185' }, stroke: { color: { light: '#ffffff', dark: '#151b28' }, width: 0.5 }, tooltip: ({ row }) => document.createTextNode('Run ' + row.run + ': ' + row.lane), }), ], height: 260, margin: { top: 5, right: 8, bottom: 24, left: 56 }, axis: { x: { scale: 'utc', min: start - 5 * 60_000, max: start + 115 * 60_000, label: '', line: false, tick_label: { format: value => new Date(Number(value)).toISOString().slice(11, 16) }, }, y: { categories: ['Failed', 'Passed'], grid_align: 'edge', label: '', line: false }, }, background: { light: '#ffffff', dark: '#151b28' }, chrome_color: { light: '#e2e8f0', dark: '#334155' }, grid: true, border: false, theme_invert: false, zoom_pan: false,}
document.body.append(plot)Rect arguments
| Field | Type | Default | Description |
|---|---|---|---|
data |
Record<string, unknown>[] |
Required | Rows used to build the series. |
x? |
FieldArg |
'x' |
Horizontal field name or accessor. |
x2? |
FieldArg |
'x2' when present in data |
Opposite horizontal corner. Numeric axes need a second corner or pixel size. |
y? |
FieldArg |
'y' |
Vertical field name or accessor. |
y2? |
FieldArg |
'y2' when present in data |
Opposite vertical corner. Numeric axes need a second corner or pixel size. |
span? |
'x' | 'y' |
None | Stretch the rectangle across the full plot on this axis. |
size? |
number | { width?: number; height?: number } |
Derived from bounds or band | Fixed pixel size, shared or per dimension. |
band_align? |
'center' | 'start' | 'end' |
'center' |
Alignment of a fixed-size rectangle within a categorical band. |
hover_span_x? |
boolean |
false |
Extend the horizontal hit region across the categorical band. |
hover_span_y? |
boolean |
false |
Extend the vertical hit region across the categorical band. |
inset? |
number |
One sixth of band width | Inset on each side of a categorical band, in pixels. |
min_size? |
number |
0 |
Minimum pixel length for a rectangle defined by data bounds. |
offset? |
{ x?: number; y?: number } |
{ x: 0, y: 0 } |
Pixel offsets applied to each rectangle. |
color? |
ColorArg |
Black | Series color; theme pairs provide separate light and dark colors. |
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 { rect } from '@antadesign/plot'
const series = [rect({ data: [ { start: 1, end: 3, low: 2, high: 5 }, { start: 4, end: 6, low: 1, high: 4 }, ], x: 'start', x2: 'end', y: 'low', y2: 'high', min_size: 2, offset: { x: 0, y: 0 }, color: 'lightsteelblue', stroke: { color: 'steelblue', width: 1 }, tooltip: ({ x, y }) => `(${x}, ${y})`, on_select: ({ row }) => console.log('Selected row:', row), hoverable: true, highlight: true,})]For fixed-size marks in categorical bands, use size and band_align.
inset controls the space around a band when its size is not fixed:
import { rect } from '@antadesign/plot'
const series = [rect({ data: [{ group: 'A', row: 'First' }, { group: 'B', row: 'Second' }], x: 'group', y: 'row', size: { width: 12 }, band_align: 'start', inset: 4, offset: { x: 2, y: 0 }, hover_span_x: true, hover_span_y: true, color: 'steelblue', tooltip: true,})]Use span to fill one axis, leaving its coordinates unspecified. Add this
series before the data series to draw a background region:
import { rect } from '@antadesign/plot'
const series = [rect({ data: [{ low: 2, high: 5 }], span: 'x', y: 'low', y2: 'high', color: 'aliceblue', hoverable: false, highlight: false,})]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.