2

Scatter Chart

PreviousNext

Point scatter charts with multiple symbols and optional trend lines.

020406080100Cost Index020406080100Performance Score
"use client"

import { ScatterChart } from "@/components/ui/charts"

// Rich dataset with many scattered points and varied sizes
const data = [
  {
    name: "Category A",
    color: "#1e40af",
    symbol: "circle" as const,
    data: [
      { x: 12, y: 85, size: 45 },
      { x: 25, y: 42, size: 28 },
      { x: 38, y: 68, size: 62 },
      { x: 52, y: 25, size: 35 },
      { x: 65, y: 78, size: 48 },
      { x: 78, y: 55, size: 22 },
      { x: 18, y: 92, size: 55 },
      { x: 42, y: 35, size: 32 },
      { x: 58, y: 88, size: 42 },
      { x: 72, y: 48, size: 38 },
      { x: 85, y: 72, size: 52 },
      { x: 32, y: 58, size: 28 },
      { x: 48, y: 15, size: 35 },
      { x: 62, y: 95, size: 65 },
      { x: 8, y: 65, size: 25 },
      { x: 92, y: 38, size: 42 },
    ],
  },
  {
    name: "Category B",
    color: "#2563eb",
    symbol: "circle" as const,
    data: [
      { x: 15, y: 52, size: 38 },
      { x: 28, y: 78, size: 45 },
      { x: 42, y: 32, size: 28 },
      { x: 55, y: 65, size: 52 },
      { x: 68, y: 88, size: 35 },
      { x: 82, y: 42, size: 48 },
      { x: 22, y: 72, size: 32 },
      { x: 35, y: 18, size: 25 },
      { x: 48, y: 58, size: 42 },
      { x: 62, y: 82, size: 55 },
      { x: 75, y: 28, size: 38 },
      { x: 88, y: 62, size: 45 },
      { x: 5, y: 45, size: 22 },
      { x: 95, y: 75, size: 58 },
      { x: 38, y: 92, size: 48 },
      { x: 72, y: 12, size: 32 },
    ],
  },
  {
    name: "Category C",
    color: "#3b82f6",
    symbol: "circle" as const,
    data: [
      { x: 18, y: 38, size: 42 },
      { x: 32, y: 62, size: 35 },
      { x: 45, y: 85, size: 55 },
      { x: 58, y: 22, size: 28 },
      { x: 72, y: 68, size: 48 },
      { x: 85, y: 45, size: 32 },
      { x: 25, y: 55, size: 38 },
      { x: 38, y: 78, size: 52 },
      { x: 52, y: 42, size: 25 },
      { x: 65, y: 92, size: 62 },
      { x: 78, y: 28, size: 35 },
      { x: 92, y: 58, size: 45 },
      { x: 12, y: 75, size: 38 },
      { x: 28, y: 15, size: 22 },
      { x: 68, y: 52, size: 42 },
      { x: 82, y: 88, size: 58 },
    ],
  },
  {
    name: "Category D",
    color: "#60a5fa",
    symbol: "circle" as const,
    data: [
      { x: 22, y: 48, size: 35 },
      { x: 35, y: 72, size: 48 },
      { x: 48, y: 28, size: 32 },
      { x: 62, y: 55, size: 42 },
      { x: 75, y: 82, size: 55 },
      { x: 88, y: 35, size: 28 },
      { x: 15, y: 68, size: 45 },
      { x: 28, y: 95, size: 62 },
      { x: 42, y: 18, size: 25 },
      { x: 55, y: 75, size: 52 },
      { x: 68, y: 42, size: 38 },
      { x: 82, y: 65, size: 48 },
      { x: 8, y: 88, size: 55 },
      { x: 95, y: 22, size: 32 },
      { x: 38, y: 58, size: 42 },
      { x: 72, y: 8, size: 28 },
    ],
  },
  {
    name: "Category E",
    color: "#93c5fd",
    symbol: "circle" as const,
    data: [
      { x: 10, y: 32, size: 28 },
      { x: 25, y: 58, size: 42 },
      { x: 40, y: 82, size: 55 },
      { x: 55, y: 15, size: 22 },
      { x: 70, y: 45, size: 35 },
      { x: 85, y: 72, size: 48 },
      { x: 18, y: 88, size: 58 },
      { x: 32, y: 25, size: 32 },
      { x: 48, y: 65, size: 45 },
      { x: 62, y: 38, size: 38 },
      { x: 78, y: 92, size: 62 },
      { x: 92, y: 52, size: 42 },
      { x: 5, y: 78, size: 48 },
      { x: 38, y: 42, size: 35 },
      { x: 65, y: 18, size: 25 },
      { x: 80, y: 58, size: 38 },
    ],
  },
]

export function ScatterChartDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <ScatterChart
        data={data}
        width={560}
        height={400}
        sizeRange={[6, 24]}
        showLegend
        xAxisLabel="Cost Index"
        yAxisLabel="Performance Score"
        margin={{ top: 20, right: 30, bottom: 50, left: 70 }}
      />
    </div>
  )
}

About

The Scatter Chart component displays the relationship between two numerical variables. Built with D3, it supports:

  • Multiple data series with different colors
  • Various point symbols (circle, square, triangle, diamond, cross)
  • Bubble charts with size-mapped data points
  • Trend lines showing linear regression
  • Interactive tooltips with point details

Installation

pnpm dlx shadcn@latest add https://ui.simplifying.ai/r/scatter-chart.json

Usage

import { ScatterChart } from "@/components/ui/charts"
 
const data = [
  {
    name: "Dataset A",
    color: "#2563eb",
    data: [
      { x: 10, y: 20 },
      { x: 15, y: 35 },
      { x: 25, y: 45 },
    ],
  },
]
 
export function Example() {
  return <ScatterChart data={data} showLegend />
}

Examples

Default

The default scatter chart displays data points with circle symbols and an interactive legend for multiple series.

020406080100Cost Index020406080100Performance Score
"use client"

import { ScatterChart } from "@/components/ui/charts"

// Rich dataset with many scattered points and varied sizes
const data = [
  {
    name: "Category A",
    color: "#1e40af",
    symbol: "circle" as const,
    data: [
      { x: 12, y: 85, size: 45 },
      { x: 25, y: 42, size: 28 },
      { x: 38, y: 68, size: 62 },
      { x: 52, y: 25, size: 35 },
      { x: 65, y: 78, size: 48 },
      { x: 78, y: 55, size: 22 },
      { x: 18, y: 92, size: 55 },
      { x: 42, y: 35, size: 32 },
      { x: 58, y: 88, size: 42 },
      { x: 72, y: 48, size: 38 },
      { x: 85, y: 72, size: 52 },
      { x: 32, y: 58, size: 28 },
      { x: 48, y: 15, size: 35 },
      { x: 62, y: 95, size: 65 },
      { x: 8, y: 65, size: 25 },
      { x: 92, y: 38, size: 42 },
    ],
  },
  {
    name: "Category B",
    color: "#2563eb",
    symbol: "circle" as const,
    data: [
      { x: 15, y: 52, size: 38 },
      { x: 28, y: 78, size: 45 },
      { x: 42, y: 32, size: 28 },
      { x: 55, y: 65, size: 52 },
      { x: 68, y: 88, size: 35 },
      { x: 82, y: 42, size: 48 },
      { x: 22, y: 72, size: 32 },
      { x: 35, y: 18, size: 25 },
      { x: 48, y: 58, size: 42 },
      { x: 62, y: 82, size: 55 },
      { x: 75, y: 28, size: 38 },
      { x: 88, y: 62, size: 45 },
      { x: 5, y: 45, size: 22 },
      { x: 95, y: 75, size: 58 },
      { x: 38, y: 92, size: 48 },
      { x: 72, y: 12, size: 32 },
    ],
  },
  {
    name: "Category C",
    color: "#3b82f6",
    symbol: "circle" as const,
    data: [
      { x: 18, y: 38, size: 42 },
      { x: 32, y: 62, size: 35 },
      { x: 45, y: 85, size: 55 },
      { x: 58, y: 22, size: 28 },
      { x: 72, y: 68, size: 48 },
      { x: 85, y: 45, size: 32 },
      { x: 25, y: 55, size: 38 },
      { x: 38, y: 78, size: 52 },
      { x: 52, y: 42, size: 25 },
      { x: 65, y: 92, size: 62 },
      { x: 78, y: 28, size: 35 },
      { x: 92, y: 58, size: 45 },
      { x: 12, y: 75, size: 38 },
      { x: 28, y: 15, size: 22 },
      { x: 68, y: 52, size: 42 },
      { x: 82, y: 88, size: 58 },
    ],
  },
  {
    name: "Category D",
    color: "#60a5fa",
    symbol: "circle" as const,
    data: [
      { x: 22, y: 48, size: 35 },
      { x: 35, y: 72, size: 48 },
      { x: 48, y: 28, size: 32 },
      { x: 62, y: 55, size: 42 },
      { x: 75, y: 82, size: 55 },
      { x: 88, y: 35, size: 28 },
      { x: 15, y: 68, size: 45 },
      { x: 28, y: 95, size: 62 },
      { x: 42, y: 18, size: 25 },
      { x: 55, y: 75, size: 52 },
      { x: 68, y: 42, size: 38 },
      { x: 82, y: 65, size: 48 },
      { x: 8, y: 88, size: 55 },
      { x: 95, y: 22, size: 32 },
      { x: 38, y: 58, size: 42 },
      { x: 72, y: 8, size: 28 },
    ],
  },
  {
    name: "Category E",
    color: "#93c5fd",
    symbol: "circle" as const,
    data: [
      { x: 10, y: 32, size: 28 },
      { x: 25, y: 58, size: 42 },
      { x: 40, y: 82, size: 55 },
      { x: 55, y: 15, size: 22 },
      { x: 70, y: 45, size: 35 },
      { x: 85, y: 72, size: 48 },
      { x: 18, y: 88, size: 58 },
      { x: 32, y: 25, size: 32 },
      { x: 48, y: 65, size: 45 },
      { x: 62, y: 38, size: 38 },
      { x: 78, y: 92, size: 62 },
      { x: 92, y: 52, size: 42 },
      { x: 5, y: 78, size: 48 },
      { x: 38, y: 42, size: 35 },
      { x: 65, y: 18, size: 25 },
      { x: 80, y: 58, size: 38 },
    ],
  },
]

export function ScatterChartDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <ScatterChart
        data={data}
        width={560}
        height={400}
        sizeRange={[6, 24]}
        showLegend
        xAxisLabel="Cost Index"
        yAxisLabel="Performance Score"
        margin={{ top: 20, right: 30, bottom: 50, left: 70 }}
      />
    </div>
  )
}

Bubble Chart

Use the size property on data points to create bubble charts. The sizeRange prop controls the min/max bubble sizes.

020406080Growth Rate (%)405060708090Profit Margin (%)
"use client"

import { ScatterChart } from "@/components/ui/charts"

// Company market data with size representing market cap
const data = [
  {
    name: "Tech Companies",
    color: "#1e40af",
    data: [
      { x: 15, y: 85, size: 120, label: "TechCorp" },
      { x: 45, y: 72, size: 85, label: "DataSoft" },
      { x: 65, y: 90, size: 150, label: "CloudNet" },
      { x: 80, y: 65, size: 60, label: "AppWorks" },
      { x: 35, y: 55, size: 45, label: "CodeLab" },
    ],
  },
  {
    name: "Finance Companies",
    color: "#3b82f6",
    data: [
      { x: 25, y: 45, size: 100, label: "FinBank" },
      { x: 55, y: 78, size: 130, label: "InvestCo" },
      { x: 70, y: 52, size: 75, label: "TradeFirm" },
      { x: 40, y: 88, size: 95, label: "WealthMgmt" },
    ],
  },
]

export function ScatterChartBubbleDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <ScatterChart
        data={data}
        width={500}
        height={320}
        showLegend
        sizeRange={[8, 28]}
        xAxisLabel="Growth Rate (%)"
        yAxisLabel="Profit Margin (%)"
      />
    </div>
  )
}
const data = [
  {
    name: "Dataset A",
    data: [
      { x: 10, y: 20, size: 30 },
      { x: 15, y: 35, size: 50 },
      { x: 25, y: 45, size: 20 },
    ],
  },
]
 
<ScatterChart data={data} sizeRange={[6, 20]} />

With Trend Line

Enable showTrendLine to display a linear regression line through the data points.

246810Study Hours5060708090100Test Score
"use client"

import { ScatterChart } from "@/components/ui/charts"

// Study hours vs test scores with trend line
const data = [
  {
    name: "Student Performance",
    color: "#2563eb",
    data: [
      { x: 2, y: 55 },
      { x: 3, y: 62 },
      { x: 4, y: 68 },
      { x: 5, y: 72 },
      { x: 6, y: 75 },
      { x: 7, y: 82 },
      { x: 8, y: 85 },
      { x: 9, y: 88 },
      { x: 10, y: 92 },
      { x: 4.5, y: 65 },
      { x: 5.5, y: 78 },
      { x: 6.5, y: 80 },
      { x: 7.5, y: 84 },
      { x: 8.5, y: 90 },
    ],
  },
]

export function ScatterChartTrendlineDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <ScatterChart
        data={data}
        width={500}
        height={320}
        showTrendLine
        showLegend={false}
        xAxisLabel="Study Hours"
        yAxisLabel="Test Score"
      />
    </div>
  )
}
<ScatterChart data={data} showTrendLine />

Multiple Symbols

Each series can have its own symbol type for better differentiation.

020406080100Price Point ($)20406080100Customer Rating
"use client"

import { ScatterChart } from "@/components/ui/charts"

// Different product categories with unique symbols
const data = [
  {
    name: "Electronics",
    color: "#1e40af",
    symbol: "circle" as const,
    data: [
      { x: 20, y: 75 },
      { x: 45, y: 82 },
      { x: 70, y: 68 },
      { x: 85, y: 90 },
    ],
  },
  {
    name: "Clothing",
    color: "#2563eb",
    symbol: "square" as const,
    data: [
      { x: 15, y: 45 },
      { x: 40, y: 55 },
      { x: 60, y: 62 },
      { x: 80, y: 48 },
    ],
  },
  {
    name: "Food & Beverage",
    color: "#3b82f6",
    symbol: "triangle" as const,
    data: [
      { x: 25, y: 35 },
      { x: 50, y: 42 },
      { x: 65, y: 38 },
      { x: 90, y: 52 },
    ],
  },
  {
    name: "Home & Garden",
    color: "#60a5fa",
    symbol: "diamond" as const,
    data: [
      { x: 30, y: 58 },
      { x: 55, y: 72 },
      { x: 75, y: 65 },
      { x: 95, y: 78 },
    ],
  },
]

export function ScatterChartSymbolsDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <ScatterChart
        data={data}
        width={500}
        height={340}
        size={10}
        showLegend
        xAxisLabel="Price Point ($)"
        yAxisLabel="Customer Rating"
      />
    </div>
  )
}
const data = [
  { name: "Series A", symbol: "circle", data: [...] },
  { name: "Series B", symbol: "square", data: [...] },
  { name: "Series C", symbol: "triangle", data: [...] },
]
 
<ScatterChart data={data} />

Correlation Analysis

Visualize correlations between variables with trend lines.

5060708090Temperature (°F)100200300400500600Daily Sales ($)
"use client"

import { ScatterChart } from "@/components/ui/charts"

// Temperature vs ice cream sales (positive correlation)
const data = [
  {
    name: "Ice Cream Sales",
    color: "#2563eb",
    data: [
      { x: 55, y: 120 },
      { x: 60, y: 180 },
      { x: 65, y: 220 },
      { x: 70, y: 280 },
      { x: 75, y: 350 },
      { x: 80, y: 420 },
      { x: 85, y: 480 },
      { x: 90, y: 520 },
      { x: 58, y: 150 },
      { x: 68, y: 260 },
      { x: 78, y: 390 },
      { x: 88, y: 495 },
    ],
  },
]

export function ScatterChartCorrelationDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <ScatterChart
        data={data}
        width={500}
        height={320}
        showTrendLine
        showLegend={false}
        symbol="circle"
        size={9}
        xAxisLabel="Temperature (°F)"
        yAxisLabel="Daily Sales ($)"
      />
    </div>
  )
}
<ScatterChart
  data={data}
  showTrendLine
  xAxisLabel="Variable X"
  yAxisLabel="Variable Y"
/>

API Reference

PropTypeDefaultDescription
dataScatterChartSeries[]requiredArray of data series
symbol"circle" | "square" | "triangle" | "diamond" | "cross""circle"Default point symbol
sizenumber8Default point size
showTrendLinebooleanfalseShow linear regression line
sizeRange[number, number][6, 20]Size range for bubble charts
xAxisLabelstring-Label for x-axis
yAxisLabelstring-Label for y-axis
showGridbooleantrueShow grid lines
showLegendbooleantrueShow legend
showTooltipbooleantrueShow tooltip on hover

Data Types

interface ScatterChartDataPoint {
  x: number // X-axis value
  y: number // Y-axis value
  size?: number // Optional size for bubble charts
  label?: string // Optional label for the point
}
 
interface ScatterChartSeries {
  name: string // Series name for legend/tooltip
  data: ScatterChartDataPoint[] // Array of data points
  color?: string // Optional: override series color
  symbol?: "circle" | "square" | "triangle" | "diamond" | "cross" // Point symbol
}

Notes

  • Scatter charts are best for showing relationships and correlations between two continuous variables.
  • Use bubble charts (with size property) to add a third dimension of data.
  • Different symbols help distinguish multiple series when color alone isn't sufficient.
  • Trend lines use linear regression to show the general direction of the data.
  • For optimal readability, limit the number of data series to 5 or fewer.
  • Consider using logarithmic scales for data spanning multiple orders of magnitude.
  • Grid lines help users estimate values but can be disabled for a cleaner look.