Scatter Chart

A composable time-series scatter chart with offset rings, hover dimming, and animated enter

Installation

pnpm dlx shadcn@latest add @bklit/scatter-chart

Usage

Build scatter charts by composing ScatterChart with one or more Scatter series, plus shared cartesian pieces (Grid, XAxis, ChartTooltip).

Basic Example

import { ScatterChart, Scatter, Grid, XAxis, ChartTooltip } from "@bklitui/ui/charts";

const data = [
  { date: new Date("2025-01-01"), users: 1200 },
  { date: new Date("2025-02-01"), users: 1350 },
  { date: new Date("2025-03-01"), users: 1100 },
];

export default function SimpleScatter() {
  return (
    <ScatterChart data={data}>
      <Grid horizontal />
      <Scatter dataKey="users" />
      <XAxis />
      <ChartTooltip />
    </ScatterChart>
  );
}

Multiple Series

Series colors default to the chart palette (--chart-1--chart-5) in child order:

<ScatterChart data={data}>
  <Grid horizontal />
  <Scatter dataKey="sessions" />
  <Scatter dataKey="conversions" />
  <XAxis />
  <ChartTooltip />
</ScatterChart>

Offset Ring

Each dot is an inner fill plus an outer ring separated by a gap (ringGap):

<Scatter dataKey="users" radius={6} strokeWidth={2} ringGap={2} />

Hover Interaction

Non-active points can fade and blur while the crosshair is active:

<Scatter
  dataKey="users"
  fadeOnHover
  inactiveOpacity={0.5}
  inactiveBlur={2}
  showActiveHighlight
/>

Y Gradient

Color dots by vertical position with a chart-space gradient — lower values toward red, higher toward green. Set strokeWidth={0} for solid fills without rings:

<Scatter dataKey="users" strokeWidth={0} yGradient />

// Custom stops
<Scatter
  dataKey="users"
  strokeWidth={0}
  yGradient={{ from: "var(--color-red-500)", to: "var(--color-emerald-500)" }}
/>

Props

ScatterChart

PropTypeDefaultDescription
dataRecord<string, unknown>[]requiredRows with a date (or xDataKey) and numeric series fields
xDataKeystring"date"Field used for the time x-axis
marginPartial<Margin>40 all sidesChart margins
animationDurationnumber1100Enter animation duration (ms)
enterTransitionTransitionline-chart defaultMotion tween for enter
revealSignaturestringChange to replay enter animation
aspectRatiostring"2 / 1"Container aspect ratio

Scatter

PropTypeDefaultDescription
dataKeystringrequiredY value field
fillstringseries paletteInner dot fill
strokestringsame as fillOuter ring color
strokeWidthnumber2Outer ring width (0 disables)
ringGapnumber2Gap between fill and ring (px)
radiusnumber5Inner dot radius (px)
fadeOnHoverbooleantrueDim/blur non-active points on hover
inactiveOpacitynumber0.5Opacity for dimmed points
inactiveBlurnumber2Blur (px) for dimmed points
showActiveHighlightbooleantrueScale up the active point
yGradientboolean | { from?: string; to?: string }Color dots by y-position (default red → green)

Shared Components

Use the same cartesian building blocks as LineChart:

  • Grid — horizontal/vertical grid lines
  • XAxis — date labels with crosshair fade
  • ChartTooltip — crosshair, date pill, and series rows