Radar Chart

Charts

Radar/spider chart for multi-axis data.

Preview

SpeedPowerDefenseRangeMagicStamina

Usage

example.jsx
import { RadarChart } from "@/components/ui/radar-chart";

export default function Example() {
  return <RadarChart />;
}

Source Code

Copy this file into components/ui/radar-chart.jsx in your project.

radar-chart.jsx
"use client";

import { forwardRef } from "react";
import { cn } from "@/lib/utils";

const RadarChart = forwardRef(({ className, data = [], size = 250, color = "var(--primary)", ...props }, ref) => {
  const cx = size / 2, cy = size / 2, r = size / 2 - 30;
  const maxVal = Math.max(...data.map((d) => d.value), 1);
  const n = data.length;
  const angles = data.map((_, i) => (2 * Math.PI * i) / n - Math.PI / 2);

  const gridLevels = [0.25, 0.5, 0.75, 1];
  const points = data.map((d, i) => {
    const ratio = d.value / maxVal;
    return { x: cx + r * ratio * Math.cos(angles[i]), y: cy + r * ratio * Math.sin(angles[i]) };
  });
  const polygonPoints = points.map((p) => `${p.x},${p.y}`).join(" ");

  return (
    <div ref={ref} className={cn("inline-block", className)} {...props}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        {gridLevels.map((level) => (
          <polygon key={level}
            points={angles.map((a) => `${cx + r * level * Math.cos(a)},${cy + r * level * Math.sin(a)}`).join(" ")}
            fill="none" stroke="currentColor" opacity="0.15"
          />
        ))}
        {angles.map((a, i) => (
          <g key={i}>
            <line x1={cx} y1={cy} x2={cx + r * Math.cos(a)} y2={cy + r * Math.sin(a)} stroke="currentColor" opacity="0.15" />
            <text x={cx + (r + 15) * Math.cos(a)} y={cy + (r + 15) * Math.sin(a)}
              textAnchor="middle" dominantBaseline="middle" className="fill-muted-foreground text-[10px]"
            >{data[i].label}</text>
          </g>
        ))}
        <polygon points={polygonPoints} fill={color} fillOpacity="0.2" stroke={color} strokeWidth="2" />
        {points.map((p, i) => <circle key={i} cx={p.x} cy={p.y} r="3" fill={color} />)}
      </svg>
    </div>
  );
});
RadarChart.displayName = "RadarChart";

export { RadarChart };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge