Scatterplots are drawn with TanStack Charts, through the kit's Chart components. They paint the chart with the theme's colors, grid and type, and add three palette props. The chart itself is a TanStack definition, written the way TanStack documents it.
Install
npx antuikit@latest init
npx antuikit@latest add tanstack-chart
The first command installs AntuikitProvider and the theme tokens. The second adds the chart components and TanStack Charts itself.
Your first scatterplot
Describe the chart with defineChart, outside the component, and pass it to Chart. A point is a dot mark: x and y name the two numeric fields, and both axes take a linear scale.
import { defineChart, dot } from "@tanstack/charts"
import { scaleLinear } from "@tanstack/charts/scales/linear"
import { tooltip } from "@tanstack/charts/tooltip"
import { Chart, chartColors } from "@/components/ui/tanstack-chart"
The chart fills its container's width, so give it a height. ariaLabel is required.
Which component
All three take the same definition and the same palette props.
Chart components
Many points
Chart draws one SVG element per point, which slows down past a few thousand points. Swap it for CanvasChart: it takes the same definition and draws on a canvas.
import { CanvasChart } from "@/components/ui/tanstack-chart"
<CanvasChart
definition={definition}
ariaLabel="Car weight against acceleration, colored by cylinder count"
height={280}
/>
Give every point a key that is unique, such as an id or a few fields joined. Without one, points that share a position share an identity.
Lower fillOpacity and r so dense areas show as darker, instead of one solid shape.
Canvas removes the cost of the SVG elements, not of the data. Past tens of thousands of points, count them into cells with a hexbin or a binned grid. The Heatmaps page shows both.
Groups
Set color to a category field to color the points by group. List the groups in color.domain on the definition, so each group keeps its color when one is filtered out.
r takes a fixed radius in pixels, or a field. With a field, pass rScale a square-root scale, so the area of each bubble, not its radius, follows the value. The scale's range is the smallest and the largest radius in pixels.
import { scaleSqrt } from "d3-scale"
// Draw the largest first, so the small bubbles stay on top.
const rows = [...penguins].sort((a, b) => b.body_mass - a.body_mass)
TanStack ships compact linear, band, point and ordinal scales. For square-root, log and time scales, add d3-scale to your project: npm install d3-scale and npm install -D @types/d3-scale.
Trend line
Add linearRegressionY on the same rows and fields to draw a least-squares line through the points. It draws a 95% confidence band around the line by default. ci: 0 hides it.
import { dot, linearRegressionY } from "@tanstack/charts"
Set z to a group field to fit one line per group. Both marks show in the tooltip, so check in your content whether the focused point is a car or the line.
Log scale
When values span several orders of magnitude, pass a log scale from d3-scale. Give it a fixed domain, since a log scale cannot include zero. Filter out rows at zero or below first.
Wrap the marks in facet to draw one scatterplot per group. Fix the domains of both scales, so every panel shares the same axes and the panels can be compared.
import { defineChart, dot, facet } from "@tanstack/charts"
The chart takes the theme's chart colors without any setup. Change the palette on the chart itself, or paint one mark with fill and chartColors. The Color guideline covers which palette fits which data.
Taken by Chart, RendererChart and CanvasChart. Rows marked antuikit in the Version column are added by the kit.
Animation
Use RendererChart with TanStack's motion() renderer to animate marks in and between data updates. It skips the animation when the reader has asked for reduced motion.
import { motion } from "@tanstack/charts/motion"
import { RendererChart } from "@/components/ui/tanstack-chart"