Files
peakskills/components/radar-chart.tsx
Julien Froidefond e6d4bbe13d Refactor radar chart and improve UI elements
- Updated radar chart to use abbreviated category labels for better readability.
- Enhanced chart visibility with improved grid and axis styling.
- Added a gradient background to the radar area for a more polished look.
- Simplified links in JSON files for backend, cloud, and devops skills.
- Adjusted HomePage text for clarity and consistency.
2025-08-20 16:10:28 +02:00

140 lines
3.8 KiB
TypeScript

"use client";
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
ResponsiveContainer,
} from "recharts";
import { RadarChartData } from "@/lib/types";
interface SkillsRadarChartProps {
data: RadarChartData[];
}
export function SkillsRadarChart({ data }: SkillsRadarChartProps) {
// Transform data for the chart with abbreviated labels
const chartData = data.map((item) => ({
category: item.category,
shortLabel:
item.category.length > 8
? item.category.substring(0, 8) + "..."
: item.category,
score: item.score,
maxScore: item.maxScore,
}));
if (data.length === 0) {
return (
<div className="flex items-center justify-center h-[400px] text-muted-foreground">
<p>Aucune donnée disponible</p>
</div>
);
}
return (
<div className="w-full h-[400px] relative">
<ResponsiveContainer width="100%" height="100%">
<RadarChart
data={chartData}
margin={{ top: 40, right: 60, bottom: 40, left: 60 }}
>
{/* Grid with better visibility */}
<PolarGrid
gridType="polygon"
stroke="rgba(255, 255, 255, 0.2)"
strokeWidth={1}
/>
{/* Category labels with better positioning */}
<PolarAngleAxis
dataKey="shortLabel"
tick={{
fontSize: 13,
fill: "rgba(255, 255, 255, 0.9)",
fontWeight: 500,
}}
tickFormatter={(value, index) => {
return chartData[index]?.category || value;
}}
/>
{/* Radial axis with custom ticks */}
<PolarRadiusAxis
angle={90}
domain={[0, 3]}
tick={{
fontSize: 11,
fill: "rgba(255, 255, 255, 0.6)",
fontWeight: 400,
}}
tickCount={4}
tickFormatter={(value) => {
if (value === 0) return "";
if (value === 1) return "Débutant";
if (value === 2) return "Autonome";
if (value === 3) return "Expert";
return value.toString();
}}
/>
{/* Main radar area with gradient */}
<Radar
name="Niveau"
dataKey="score"
stroke="#3b82f6"
fill="url(#radarGradient)"
fillOpacity={0.3}
strokeWidth={3}
dot={{
fill: "#3b82f6",
strokeWidth: 2,
stroke: "#ffffff",
r: 6,
}}
/>
{/* Background reference radar for max score */}
<Radar
name="Maximum"
dataKey="maxScore"
stroke="rgba(255, 255, 255, 0.2)"
fill="transparent"
strokeWidth={1}
strokeDasharray="5 5"
dot={false}
/>
{/* Gradient definition */}
<defs>
<linearGradient
id="radarGradient"
x1="0%"
y1="0%"
x2="100%"
y2="100%"
>
<stop offset="0%" stopColor="#3b82f6" stopOpacity={0.4} />
<stop offset="100%" stopColor="#1d4ed8" stopOpacity={0.1} />
</linearGradient>
</defs>
</RadarChart>
</ResponsiveContainer>
{/* Legend */}
<div className="absolute bottom-2 right-2 text-xs text-slate-400 space-y-1">
<div className="flex items-center gap-2">
<div className="w-3 h-0.5 bg-blue-500"></div>
<span>Votre niveau</span>
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-0.5 border-t border-dashed border-white/40"></div>
<span>Maximum</span>
</div>
</div>
</div>
);
}