79 lines
1.8 KiB
TypeScript
79 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
Radar,
|
|
RadarChart as RechartsRadar,
|
|
PolarGrid,
|
|
PolarAngleAxis,
|
|
PolarRadiusAxis,
|
|
ResponsiveContainer,
|
|
Legend,
|
|
Tooltip,
|
|
} from "recharts";
|
|
import { useTheme } from "./ThemeProvider";
|
|
|
|
interface DataPoint {
|
|
dimension: string;
|
|
score: number;
|
|
fullMark: number;
|
|
}
|
|
|
|
interface RadarChartProps {
|
|
data: DataPoint[];
|
|
/** Compact mode for cards (smaller, no legend) */
|
|
compact?: boolean;
|
|
}
|
|
|
|
const LIGHT = {
|
|
grid: "#d4d4d8",
|
|
tick: "#71717a",
|
|
axis: "#a1a1aa",
|
|
tooltipBg: "#fafafa",
|
|
tooltipBorder: "#e4e4e7",
|
|
tooltipText: "#18181b",
|
|
};
|
|
const DARK = {
|
|
grid: "#71717a",
|
|
tick: "#a1a1aa",
|
|
axis: "#d4d4d8",
|
|
tooltipBg: "#27272a",
|
|
tooltipBorder: "#52525b",
|
|
tooltipText: "#fafafa",
|
|
};
|
|
|
|
export function RadarChart({ data, compact }: RadarChartProps) {
|
|
const { theme } = useTheme();
|
|
const c = theme === "dark" ? DARK : LIGHT;
|
|
|
|
if (data.length === 0) return null;
|
|
|
|
return (
|
|
<div className={compact ? "h-28 w-full" : "h-72 w-full"}>
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<RechartsRadar data={data}>
|
|
<PolarGrid stroke={c.grid} />
|
|
<PolarAngleAxis dataKey="dimension" tick={{ fontSize: compact ? 7 : 9, fill: c.axis }} />
|
|
<PolarRadiusAxis angle={30} domain={[0, 5]} tick={false} />
|
|
<Radar
|
|
name="Score"
|
|
dataKey="score"
|
|
stroke="#0891b2"
|
|
fill="#0891b2"
|
|
fillOpacity={0.2}
|
|
/>
|
|
<Tooltip
|
|
contentStyle={{
|
|
backgroundColor: c.tooltipBg,
|
|
border: `1px solid ${c.tooltipBorder}`,
|
|
borderRadius: "4px",
|
|
color: c.tooltipText,
|
|
fontSize: "12px",
|
|
}}
|
|
/>
|
|
{!compact && <Legend wrapperStyle={{ fontSize: "11px" }} />}
|
|
</RechartsRadar>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
);
|
|
}
|