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.
This commit is contained in:
Julien Froidefond
2025-08-20 16:10:28 +02:00
parent 5c510ebd07
commit e6d4bbe13d
5 changed files with 114 additions and 108 deletions

View File

@@ -15,9 +15,13 @@ interface SkillsRadarChartProps {
}
export function SkillsRadarChart({ data }: SkillsRadarChartProps) {
// Transform data for the chart
// 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,
}));
@@ -31,34 +35,105 @@ export function SkillsRadarChart({ data }: SkillsRadarChartProps) {
}
return (
<div className="w-full h-[400px]">
<div className="w-full h-[400px] relative">
<ResponsiveContainer width="100%" height="100%">
<RadarChart
data={chartData}
margin={{ top: 20, right: 30, bottom: 20, left: 30 }}
margin={{ top: 40, right: 60, bottom: 40, left: 60 }}
>
<PolarGrid gridType="polygon" />
<PolarAngleAxis
dataKey="category"
tick={{ fontSize: 12, fill: "hsl(var(--foreground))" }}
className="text-xs"
{/* 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: 10, fill: "hsl(var(--muted-foreground))" }}
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="hsl(var(--primary))"
fill="hsl(var(--primary))"
fillOpacity={0.2}
strokeWidth={2}
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>
);
}