2

Radar Chart

PreviousNext

Spider/radar charts for comparing multiple variables across multiple series with support for variants including comparison, legend, filled, and minimal styles.

PerformanceReliabilityUsabilityFeaturesSupportPrice2040597999
"use client"

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

const data = [
  {
    name: "Product A",
    color: "#2563eb",
    data: [
      { axis: "Performance", value: 85 },
      { axis: "Reliability", value: 90 },
      { axis: "Usability", value: 78 },
      { axis: "Features", value: 88 },
      { axis: "Support", value: 72 },
      { axis: "Price", value: 65 },
    ],
  },
  {
    name: "Product B",
    color: "#93c5fd",
    data: [
      { axis: "Performance", value: 72 },
      { axis: "Reliability", value: 85 },
      { axis: "Usability", value: 90 },
      { axis: "Features", value: 75 },
      { axis: "Support", value: 88 },
      { axis: "Price", value: 80 },
    ],
  },
]

export function RadarChartDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart data={data} showLegend fillOpacity={0.3} />
    </div>
  )
}

About

The Radar Chart (also known as spider or web chart) displays multivariate data on axes starting from the same point. Built with D3.js for precise radial calculations, it supports:

  • Multiple series comparison on the same chart
  • Polygon and circular grid styles
  • Interactive legend with hover highlighting
  • Custom axis labels showing values
  • Minimal mode without grid lines
  • Filled grid backgrounds for emphasis

Installation

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

Usage

import { RadarChart } from "@/components/ui/charts"
 
const data = [
  {
    name: "Product A",
    data: [
      { axis: "Speed", value: 80 },
      { axis: "Reliability", value: 90 },
      { axis: "Comfort", value: 70 },
      { axis: "Safety", value: 85 },
      { axis: "Efficiency", value: 75 },
    ],
  },
]
 
export function Example() {
  return <RadarChart data={data} />
}

Examples

Default

The default radar chart displays data points with dots, concentric level circles with value labels, axis lines, and an interactive legend for multiple series.

PerformanceReliabilityUsabilityFeaturesSupportPrice2040597999
"use client"

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

const data = [
  {
    name: "Product A",
    color: "#2563eb",
    data: [
      { axis: "Performance", value: 85 },
      { axis: "Reliability", value: 90 },
      { axis: "Usability", value: 78 },
      { axis: "Features", value: 88 },
      { axis: "Support", value: 72 },
      { axis: "Price", value: 65 },
    ],
  },
  {
    name: "Product B",
    color: "#93c5fd",
    data: [
      { axis: "Performance", value: 72 },
      { axis: "Reliability", value: 85 },
      { axis: "Usability", value: 90 },
      { axis: "Features", value: 75 },
      { axis: "Support", value: 88 },
      { axis: "Price", value: 80 },
    ],
  },
]

export function RadarChartDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart data={data} showLegend fillOpacity={0.3} />
    </div>
  )
}

Comparison

A clean comparison view for multiple data series. Optimized for comparing two or more datasets without dots, using thicker strokes for better visibility.

JanuaryFebruaryMarchAprilMayJune
"use client"

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

const data = [
  {
    name: "Desktop",
    color: "#2563eb",
    data: [
      { axis: "January", value: 186 },
      { axis: "February", value: 305 },
      { axis: "March", value: 237 },
      { axis: "April", value: 73 },
      { axis: "May", value: 209 },
      { axis: "June", value: 214 },
    ],
  },
  {
    name: "Mobile",
    color: "#93c5fd",
    data: [
      { axis: "January", value: 80 },
      { axis: "February", value: 200 },
      { axis: "March", value: 120 },
      { axis: "April", value: 190 },
      { axis: "May", value: 130 },
      { axis: "June", value: 140 },
    ],
  },
]

export function RadarChartComparisonDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart data={data} variant="comparison" />
    </div>
  )
}
<RadarChart data={data} config={config} variant="comparison" />

Legend

Multi-series chart with an interactive legend at the bottom. Hovering over legend items highlights the corresponding series while dimming others.

JanuaryFebruaryMarchAprilMayJune
"use client"

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

const data = [
  {
    name: "Desktop",
    color: "#2563eb",
    data: [
      { axis: "January", value: 186 },
      { axis: "February", value: 305 },
      { axis: "March", value: 237 },
      { axis: "April", value: 73 },
      { axis: "May", value: 209 },
      { axis: "June", value: 214 },
    ],
  },
  {
    name: "Mobile",
    color: "#93c5fd",
    data: [
      { axis: "January", value: 80 },
      { axis: "February", value: 200 },
      { axis: "March", value: 120 },
      { axis: "April", value: 190 },
      { axis: "May", value: 130 },
      { axis: "June", value: 140 },
    ],
  },
]

export function RadarChartLegendDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart
        data={data}
        variant="legend"
        margin={{ top: 30, right: 50, bottom: 50, left: 50 }}
      />
    </div>
  )
}
<RadarChart
  data={data}
  config={config}
  variant="legend"
  margin={{ top: 30, right: 50, bottom: 50, left: 50 }}
/>

Filled

A single-series variant with a filled polygon background for emphasis. The grid area is subtly highlighted to create depth.

JanuaryFebruaryMarchAprilMayJune
"use client"

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

const data = [
  {
    name: "Desktop",
    color: "#3b82f6",
    data: [
      { axis: "January", value: 186 },
      { axis: "February", value: 285 },
      { axis: "March", value: 237 },
      { axis: "April", value: 203 },
      { axis: "May", value: 209 },
      { axis: "June", value: 264 },
    ],
  },
]

export function RadarChartFilledDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart data={data} variant="filled" />
    </div>
  )
}
<RadarChart data={data} config={config} variant="filled" />

Circle Grid

Uses concentric circles instead of polygons for the grid. This creates a softer appearance while maintaining the radar chart functionality.

JanuaryFebruaryMarchAprilMayJune
"use client"

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

const data = [
  {
    name: "Desktop",
    color: "#3b82f6",
    data: [
      { axis: "January", value: 186 },
      { axis: "February", value: 305 },
      { axis: "March", value: 237 },
      { axis: "April", value: 273 },
      { axis: "May", value: 209 },
      { axis: "June", value: 214 },
    ],
  },
]

export function RadarChartCircleDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart data={data} variant="circle" />
    </div>
  )
}
<RadarChart data={data} config={config} variant="circle" />

You can also manually control the grid type:

<RadarChart data={data} gridType="circle" levels={4} />

Minimal

A clean, minimal variant without grid lines. Only shows the data area with prominent dots at each axis point. Ideal for simple visualizations or when the focus should be entirely on the data shape.

JanuaryFebruaryMarchAprilMayJune
"use client"

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

const data = [
  {
    name: "Desktop",
    color: "#3b82f6",
    data: [
      { axis: "January", value: 186 },
      { axis: "February", value: 305 },
      { axis: "March", value: 237 },
      { axis: "April", value: 273 },
      { axis: "May", value: 209 },
      { axis: "June", value: 214 },
    ],
  },
]

export function RadarChartMinimalDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart data={data} variant="minimal" />
    </div>
  )
}
<RadarChart data={data} config={config} variant="minimal" />

Custom Labels

Displays axis values alongside axis names. For multiple series, shows values separated by a slash (e.g., "186/80"). This is useful when precise values need to be visible without hovering.

186/80January305/200February237/120March73/190April209/130May214/140June
"use client"

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

const data = [
  {
    name: "Desktop",
    color: "#2563eb",
    data: [
      { axis: "January", value: 186 },
      { axis: "February", value: 305 },
      { axis: "March", value: 237 },
      { axis: "April", value: 73 },
      { axis: "May", value: 209 },
      { axis: "June", value: 214 },
    ],
  },
  {
    name: "Mobile",
    color: "#93c5fd",
    data: [
      { axis: "January", value: 80 },
      { axis: "February", value: 200 },
      { axis: "March", value: 120 },
      { axis: "April", value: 190 },
      { axis: "May", value: 130 },
      { axis: "June", value: 140 },
    ],
  },
]

export function RadarChartLabelsDemo() {
  return (
    <div className="w-full max-w-md">
      <RadarChart
        data={data}
        variant="labels"
        margin={{ top: 60, right: 60, bottom: 60, left: 60 }}
      />
    </div>
  )
}
<RadarChart
  data={data}
  config={config}
  variant="labels"
  margin={{ top: 60, right: 60, bottom: 60, left: 60 }}
/>

API Reference

PropTypeDefaultDescription
dataRadarChartSeries[]requiredArray of data series to display
variant"default" | "comparison" | "legend" | "filled" | "circle" | "minimal" | "labels""default"Chart style variant
configChartConfig-Color and label configuration
widthnumber500Chart width in pixels
heightnumber500Chart height in pixels
margin{ top, right, bottom, left }{ top: 50, ... }Chart margins
maxValuenumberautoMaximum axis value (auto-calculated from data)
levelsnumber5Number of concentric grid levels
gridType"polygon" | "circle""polygon"Shape of grid levels
showGridbooleantrueShow grid levels
showRadialLinesbooleantrueShow axis lines from center
showDotsbooleantrueShow data point dots
dotSizenumber4Radius of data point dots
fillOpacitynumber0.25Opacity of the filled area
strokeWidthnumber2Width of the area outline
showLabelsbooleantrueShow axis labels
labelOffsetnumber20Distance of labels from outer edge
showLevelLabelsbooleantrueShow value labels on grid levels
showLegendbooleantrueShow legend for multiple series
showTooltipbooleantrueEnable tooltip on hover

Data Types

interface RadarChartDataPoint {
  axis: string // Axis/dimension name
  value: number // Numeric value for this axis
}
 
interface RadarChartSeries {
  name: string // Series name for legend/tooltip
  data: RadarChartDataPoint[] // Data points for each axis
  color?: string // Optional: override color for this series
  fillOpacity?: number // Optional: override fill opacity
}
 
type RadarChartVariant =
  | "default"
  | "comparison"
  | "legend"
  | "filled"
  | "circle"
  | "minimal"
  | "labels"

Customization

Custom Colors

Use the config prop to define colors for each series:

const config = {
  "Product A": { label: "Product A", color: "hsl(var(--chart-1))" },
  "Product B": { label: "Product B", color: "hsl(var(--chart-2))" },
}
 
<RadarChart data={data} config={config} />

Or set colors directly in your data:

const data = [
  {
    name: "Performance",
    color: "#3b82f6",
    fillOpacity: 0.4,
    data: [
      { axis: "Speed", value: 90 },
      { axis: "Power", value: 85 },
      // ...
    ],
  },
]
 
<RadarChart data={data} />

Adjusting Scale

Control the maximum value to normalize multiple charts or emphasize differences:

// Fixed scale from 0-100
<RadarChart data={data} maxValue={100} />
 
// Let the chart auto-calculate with 10% padding
<RadarChart data={data} />

Grid Customization

Fine-tune the grid appearance:

// Circular grid with 4 levels
<RadarChart
  data={data}
  gridType="circle"
  levels={4}
  showRadialLines={false}
/>
 
// No grid at all (minimal style)
<RadarChart
  data={data}
  showGrid={false}
  showRadialLines={false}
  showDots
/>

Accessibility

  • Data points are interactive with hover states
  • Tooltips provide exact values on hover
  • Legend enables series identification without color-only cues
  • Consistent color assignment from ChartConfig ensures predictable styling

Notes

  • Radar charts work best with 3-8 axes. Too many axes can make the chart difficult to read.
  • All series should have the same axes in the same order for proper comparison.
  • The chart automatically scales to fit the container while maintaining aspect ratio.
  • Use the filled variant for single series to emphasize the data area.
  • The comparison variant is optimized for comparing multiple series without visual clutter.
  • Custom margins may be needed when using the labels variant to prevent label clipping.