Radar Chart
Spider/radar chart for multi-metric comparison across categories
Installation
Dependencies
Examples
Comparison
"use client"
import RadarChart, { RadarArea, RadarAxis, RadarGrid, RadarLabels } from "@/components/vritti/radar-chart"
const metrics = [
{ key: "react", label: "React" },
{ key: "typescript", label: "TypeScript" },
{ key: "css", label: "CSS" },
{ key: "testing", label: "Testing" },
{ key: "perf", label: "Performance" },
{ key: "a11y", label: "Accessibility" },
]
const data = [
{
label: "Frontend",
color: "hsl(217, 91%, 60%)",
values: { react: 95, typescript: 80, css: 90, testing: 65, perf: 75, a11y: 70 },
},
{
label: "Fullstack",
color: "hsl(142, 71%, 45%)",
values: { react: 75, typescript: 85, css: 65, testing: 80, perf: 70, a11y: 60 },
},
]
export function RadarChartComparisonDemo() {
return (
<div className="flex justify-center p-4">
<RadarChart data={data} metrics={metrics} size={320}>
<RadarGrid />
<RadarAxis />
<RadarLabels />
{data.map((_, i) => (
<RadarArea key={i} index={i} />
))}
</RadarChart>
</div>
)
}
Legend
Campaign Performance
Google Search70%
Display Ads58%
Newsletter71%
Social58%
"use client"
import { useState } from "react"
import RadarChart, {
Legend,
LegendItem,
LegendLabel,
LegendMarker,
LegendValue,
RadarArea,
RadarAxis,
RadarGrid,
RadarLabels,
type LegendItemData,
type RadarData,
type RadarMetric,
} from "@/components/vritti/radar-chart"
const metrics: RadarMetric[] = [
{ key: "engagement", label: "Engagement" },
{ key: "pagesPerSession", label: "Pages/Session" },
{ key: "sessionDuration", label: "Duration" },
{ key: "conversionRate", label: "Conversion" },
{ key: "bounceInverse", label: "Retention" },
]
const campaignData: RadarData[] = [
{
label: "Google Search",
color: "#3b82f6",
values: {
engagement: 72,
pagesPerSession: 68,
sessionDuration: 70,
conversionRate: 75,
bounceInverse: 65,
},
},
{
label: "Display Ads",
color: "#f59e0b",
values: {
engagement: 85,
pagesPerSession: 45,
sessionDuration: 40,
conversionRate: 30,
bounceInverse: 88,
},
},
{
label: "Newsletter",
color: "#10b981",
values: {
engagement: 45,
pagesPerSession: 90,
sessionDuration: 92,
conversionRate: 88,
bounceInverse: 42,
},
},
{
label: "Social",
color: "#ec4899",
values: {
engagement: 95,
pagesPerSession: 35,
sessionDuration: 25,
conversionRate: 55,
bounceInverse: 78,
},
},
]
export function RadarChartLegendDemo() {
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)
const legendItems: LegendItemData[] = campaignData.map((d, index) => ({
label: d.label,
value:
Object.values(d.values).reduce((a, b) => a + b, 0) / metrics.length,
maxValue: 100,
color: d.color ?? `var(--chart-${index + 1})`,
}))
return (
<div className="flex flex-col items-center justify-center gap-8 p-4 lg:flex-row lg:gap-12">
<RadarChart
data={campaignData}
hoveredIndex={hoveredIndex}
metrics={metrics}
onHoverChange={setHoveredIndex}
size={260}
>
<RadarGrid />
<RadarAxis />
<RadarLabels />
{campaignData.map((item, index) => (
<RadarArea index={index} key={item.label} />
))}
</RadarChart>
<Legend
hoveredIndex={hoveredIndex}
items={legendItems}
onHoverChange={setHoveredIndex}
title="Campaign Performance"
>
<LegendItem className="flex items-center gap-3">
<LegendMarker />
<LegendLabel className="flex-1 text-sm font-medium" />
<LegendValue formatValue={(v) => `${v.toFixed(0)}%`} />
</LegendItem>
</Legend>
</div>
)
}
Minimal
"use client"
import RadarChart, {
RadarArea,
RadarAxis,
RadarGrid,
RadarLabels,
type RadarData,
type RadarMetric,
} from "@/components/vritti/radar-chart"
const simpleMetrics: RadarMetric[] = [
{ key: "speed", label: "Speed" },
{ key: "power", label: "Power" },
{ key: "technique", label: "Technique" },
{ key: "stamina", label: "Stamina" },
{ key: "agility", label: "Agility" },
]
const simpleData: RadarData[] = [
{
label: "Player A",
color: "#6366f1",
values: { speed: 85, power: 70, technique: 90, stamina: 75, agility: 88 },
},
{
label: "Player B",
color: "#f97316",
values: { speed: 65, power: 95, technique: 60, stamina: 88, agility: 55 },
},
]
export function RadarChartMinimalDemo() {
return (
<div className="flex justify-center p-4">
<RadarChart data={simpleData} levels={4} metrics={simpleMetrics} size={300}>
<RadarGrid showLabels={false} />
<RadarAxis />
<RadarLabels fontSize={12} offset={20} />
{simpleData.map((item, index) => (
<RadarArea index={index} key={item.label} />
))}
</RadarChart>
</div>
)
}