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:
@@ -124,7 +124,7 @@ export default function HomePage() {
|
|||||||
Vue d'ensemble de vos compétences
|
Vue d'ensemble de vos compétences
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-slate-400 text-sm">
|
<p className="text-slate-400 text-sm">
|
||||||
Graphique radar représentant votre niveau moyen par catégorie
|
Radar chart représentant votre niveau par catégorie
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-80">
|
<div className="h-80">
|
||||||
@@ -155,8 +155,8 @@ export default function HomePage() {
|
|||||||
const currentSkillCategory = skillCategories.find(
|
const currentSkillCategory = skillCategories.find(
|
||||||
(sc) => sc.category === category.category
|
(sc) => sc.category === category.category
|
||||||
);
|
);
|
||||||
const CategoryIcon = currentSkillCategory
|
const CategoryIcon = currentSkillCategory
|
||||||
? getCategoryIcon(currentSkillCategory.icon)
|
? getCategoryIcon(currentSkillCategory.icon)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -15,9 +15,13 @@ interface SkillsRadarChartProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function SkillsRadarChart({ data }: SkillsRadarChartProps) {
|
export function SkillsRadarChart({ data }: SkillsRadarChartProps) {
|
||||||
// Transform data for the chart
|
// Transform data for the chart with abbreviated labels
|
||||||
const chartData = data.map((item) => ({
|
const chartData = data.map((item) => ({
|
||||||
category: item.category,
|
category: item.category,
|
||||||
|
shortLabel:
|
||||||
|
item.category.length > 8
|
||||||
|
? item.category.substring(0, 8) + "..."
|
||||||
|
: item.category,
|
||||||
score: item.score,
|
score: item.score,
|
||||||
maxScore: item.maxScore,
|
maxScore: item.maxScore,
|
||||||
}));
|
}));
|
||||||
@@ -31,34 +35,105 @@ export function SkillsRadarChart({ data }: SkillsRadarChartProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-[400px]">
|
<div className="w-full h-[400px] relative">
|
||||||
<ResponsiveContainer width="100%" height="100%">
|
<ResponsiveContainer width="100%" height="100%">
|
||||||
<RadarChart
|
<RadarChart
|
||||||
data={chartData}
|
data={chartData}
|
||||||
margin={{ top: 20, right: 30, bottom: 20, left: 30 }}
|
margin={{ top: 40, right: 60, bottom: 40, left: 60 }}
|
||||||
>
|
>
|
||||||
<PolarGrid gridType="polygon" />
|
{/* Grid with better visibility */}
|
||||||
<PolarAngleAxis
|
<PolarGrid
|
||||||
dataKey="category"
|
gridType="polygon"
|
||||||
tick={{ fontSize: 12, fill: "hsl(var(--foreground))" }}
|
stroke="rgba(255, 255, 255, 0.2)"
|
||||||
className="text-xs"
|
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
|
<PolarRadiusAxis
|
||||||
angle={90}
|
angle={90}
|
||||||
domain={[0, 3]}
|
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}
|
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
|
<Radar
|
||||||
name="Niveau"
|
name="Niveau"
|
||||||
dataKey="score"
|
dataKey="score"
|
||||||
stroke="hsl(var(--primary))"
|
stroke="#3b82f6"
|
||||||
fill="hsl(var(--primary))"
|
fill="url(#radarGradient)"
|
||||||
fillOpacity={0.2}
|
fillOpacity={0.3}
|
||||||
strokeWidth={2}
|
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>
|
</RadarChart>
|
||||||
</ResponsiveContainer>
|
</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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,28 +66,19 @@
|
|||||||
"id": "golang",
|
"id": "golang",
|
||||||
"name": "Go",
|
"name": "Go",
|
||||||
"description": "Langage de programmation développé par Google",
|
"description": "Langage de programmation développé par Google",
|
||||||
"links": [
|
"links": ["https://golang.org/", "https://golang.org/doc/"]
|
||||||
"https://golang.org/",
|
|
||||||
"https://golang.org/doc/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rust",
|
"id": "rust",
|
||||||
"name": "Rust",
|
"name": "Rust",
|
||||||
"description": "Langage de programmation système sûr et performant",
|
"description": "Langage de programmation système sûr et performant",
|
||||||
"links": [
|
"links": ["https://www.rust-lang.org/", "https://doc.rust-lang.org/"]
|
||||||
"https://www.rust-lang.org/",
|
|
||||||
"https://doc.rust-lang.org/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "java-spring",
|
"id": "java-spring",
|
||||||
"name": "Java Spring",
|
"name": "Java Spring",
|
||||||
"description": "Framework Java pour applications d'entreprise",
|
"description": "Framework Java pour applications d'entreprise",
|
||||||
"links": [
|
"links": ["https://spring.io/", "https://docs.spring.io/"]
|
||||||
"https://spring.io/",
|
|
||||||
"https://docs.spring.io/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "csharp-dotnet",
|
"id": "csharp-dotnet",
|
||||||
@@ -102,64 +93,43 @@
|
|||||||
"id": "php-laravel",
|
"id": "php-laravel",
|
||||||
"name": "PHP Laravel",
|
"name": "PHP Laravel",
|
||||||
"description": "Framework PHP moderne pour applications web",
|
"description": "Framework PHP moderne pour applications web",
|
||||||
"links": [
|
"links": ["https://laravel.com/", "https://laravel.com/docs"]
|
||||||
"https://laravel.com/",
|
|
||||||
"https://laravel.com/docs"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ruby-rails",
|
"id": "ruby-rails",
|
||||||
"name": "Ruby on Rails",
|
"name": "Ruby on Rails",
|
||||||
"description": "Framework web en Ruby",
|
"description": "Framework web en Ruby",
|
||||||
"links": [
|
"links": ["https://rubyonrails.org/", "https://guides.rubyonrails.org/"]
|
||||||
"https://rubyonrails.org/",
|
|
||||||
"https://guides.rubyonrails.org/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "graphql",
|
"id": "graphql",
|
||||||
"name": "GraphQL",
|
"name": "GraphQL",
|
||||||
"description": "Langage de requête pour APIs",
|
"description": "Langage de requête pour APIs",
|
||||||
"links": [
|
"links": ["https://graphql.org/", "https://graphql.org/learn/"]
|
||||||
"https://graphql.org/",
|
|
||||||
"https://graphql.org/learn/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "prisma",
|
"id": "prisma",
|
||||||
"name": "Prisma",
|
"name": "Prisma",
|
||||||
"description": "ORM moderne pour Node.js et TypeScript",
|
"description": "ORM moderne pour Node.js et TypeScript",
|
||||||
"links": [
|
"links": ["https://www.prisma.io/", "https://www.prisma.io/docs"]
|
||||||
"https://www.prisma.io/",
|
|
||||||
"https://www.prisma.io/docs"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "trpc",
|
"id": "trpc",
|
||||||
"name": "tRPC",
|
"name": "tRPC",
|
||||||
"description": "Framework TypeScript pour APIs type-safe",
|
"description": "Framework TypeScript pour APIs type-safe",
|
||||||
"links": [
|
"links": ["https://trpc.io/", "https://trpc.io/docs"]
|
||||||
"https://trpc.io/",
|
|
||||||
"https://trpc.io/docs"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "nest-js",
|
"id": "nest-js",
|
||||||
"name": "NestJS",
|
"name": "NestJS",
|
||||||
"description": "Framework Node.js pour applications scalables",
|
"description": "Framework Node.js pour applications scalables",
|
||||||
"links": [
|
"links": ["https://nestjs.com/", "https://docs.nestjs.com/"]
|
||||||
"https://nestjs.com/",
|
|
||||||
"https://docs.nestjs.com/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "fastify",
|
"id": "fastify",
|
||||||
"name": "Fastify",
|
"name": "Fastify",
|
||||||
"description": "Framework web rapide pour Node.js",
|
"description": "Framework web rapide pour Node.js",
|
||||||
"links": [
|
"links": ["https://www.fastify.io/", "https://www.fastify.io/docs/"]
|
||||||
"https://www.fastify.io/",
|
|
||||||
"https://www.fastify.io/docs/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "rabbitmq",
|
"id": "rabbitmq",
|
||||||
|
|||||||
@@ -6,10 +6,7 @@
|
|||||||
"id": "aws",
|
"id": "aws",
|
||||||
"name": "Amazon Web Services",
|
"name": "Amazon Web Services",
|
||||||
"description": "Plateforme de services cloud d'Amazon",
|
"description": "Plateforme de services cloud d'Amazon",
|
||||||
"links": [
|
"links": ["https://aws.amazon.com/", "https://docs.aws.amazon.com/"]
|
||||||
"https://aws.amazon.com/",
|
|
||||||
"https://docs.aws.amazon.com/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "azure",
|
"id": "azure",
|
||||||
@@ -24,10 +21,7 @@
|
|||||||
"id": "gcp",
|
"id": "gcp",
|
||||||
"name": "Google Cloud Platform",
|
"name": "Google Cloud Platform",
|
||||||
"description": "Services cloud de Google",
|
"description": "Services cloud de Google",
|
||||||
"links": [
|
"links": ["https://cloud.google.com/", "https://cloud.google.com/docs"]
|
||||||
"https://cloud.google.com/",
|
|
||||||
"https://cloud.google.com/docs"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "terraform",
|
"id": "terraform",
|
||||||
@@ -69,10 +63,7 @@
|
|||||||
"id": "s3",
|
"id": "s3",
|
||||||
"name": "Amazon S3",
|
"name": "Amazon S3",
|
||||||
"description": "Service de stockage d'objets d'AWS",
|
"description": "Service de stockage d'objets d'AWS",
|
||||||
"links": [
|
"links": ["https://aws.amazon.com/s3/", "https://docs.aws.amazon.com/s3/"]
|
||||||
"https://aws.amazon.com/s3/",
|
|
||||||
"https://docs.aws.amazon.com/s3/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "ec2",
|
"id": "ec2",
|
||||||
|
|||||||
@@ -66,19 +66,13 @@
|
|||||||
"id": "ansible",
|
"id": "ansible",
|
||||||
"name": "Ansible",
|
"name": "Ansible",
|
||||||
"description": "Outil d'automatisation IT et de gestion de configuration",
|
"description": "Outil d'automatisation IT et de gestion de configuration",
|
||||||
"links": [
|
"links": ["https://www.ansible.com/", "https://docs.ansible.com/"]
|
||||||
"https://www.ansible.com/",
|
|
||||||
"https://docs.ansible.com/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "jenkins",
|
"id": "jenkins",
|
||||||
"name": "Jenkins",
|
"name": "Jenkins",
|
||||||
"description": "Serveur d'automatisation open source",
|
"description": "Serveur d'automatisation open source",
|
||||||
"links": [
|
"links": ["https://www.jenkins.io/", "https://www.jenkins.io/doc/"]
|
||||||
"https://www.jenkins.io/",
|
|
||||||
"https://www.jenkins.io/doc/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "gitlab-ci",
|
"id": "gitlab-ci",
|
||||||
@@ -93,19 +87,13 @@
|
|||||||
"id": "prometheus",
|
"id": "prometheus",
|
||||||
"name": "Prometheus",
|
"name": "Prometheus",
|
||||||
"description": "Système de monitoring et d'alerting",
|
"description": "Système de monitoring et d'alerting",
|
||||||
"links": [
|
"links": ["https://prometheus.io/", "https://prometheus.io/docs/"]
|
||||||
"https://prometheus.io/",
|
|
||||||
"https://prometheus.io/docs/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "grafana",
|
"id": "grafana",
|
||||||
"name": "Grafana",
|
"name": "Grafana",
|
||||||
"description": "Plateforme de visualisation et monitoring",
|
"description": "Plateforme de visualisation et monitoring",
|
||||||
"links": [
|
"links": ["https://grafana.com/", "https://grafana.com/docs/"]
|
||||||
"https://grafana.com/",
|
|
||||||
"https://grafana.com/docs/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "elk-stack",
|
"id": "elk-stack",
|
||||||
@@ -120,46 +108,31 @@
|
|||||||
"id": "nginx",
|
"id": "nginx",
|
||||||
"name": "Nginx",
|
"name": "Nginx",
|
||||||
"description": "Serveur web et proxy inverse",
|
"description": "Serveur web et proxy inverse",
|
||||||
"links": [
|
"links": ["https://nginx.org/", "https://nginx.org/en/docs/"]
|
||||||
"https://nginx.org/",
|
|
||||||
"https://nginx.org/en/docs/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "apache",
|
"id": "apache",
|
||||||
"name": "Apache HTTP Server",
|
"name": "Apache HTTP Server",
|
||||||
"description": "Serveur web open source",
|
"description": "Serveur web open source",
|
||||||
"links": [
|
"links": ["https://httpd.apache.org/", "https://httpd.apache.org/docs/"]
|
||||||
"https://httpd.apache.org/",
|
|
||||||
"https://httpd.apache.org/docs/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "traefik",
|
"id": "traefik",
|
||||||
"name": "Traefik",
|
"name": "Traefik",
|
||||||
"description": "Proxy inverse moderne et load balancer",
|
"description": "Proxy inverse moderne et load balancer",
|
||||||
"links": [
|
"links": ["https://traefik.io/", "https://doc.traefik.io/"]
|
||||||
"https://traefik.io/",
|
|
||||||
"https://doc.traefik.io/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "helm",
|
"id": "helm",
|
||||||
"name": "Helm",
|
"name": "Helm",
|
||||||
"description": "Gestionnaire de packages pour Kubernetes",
|
"description": "Gestionnaire de packages pour Kubernetes",
|
||||||
"links": [
|
"links": ["https://helm.sh/", "https://helm.sh/docs/"]
|
||||||
"https://helm.sh/",
|
|
||||||
"https://helm.sh/docs/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "istio",
|
"id": "istio",
|
||||||
"name": "Istio",
|
"name": "Istio",
|
||||||
"description": "Service mesh pour microservices",
|
"description": "Service mesh pour microservices",
|
||||||
"links": [
|
"links": ["https://istio.io/", "https://istio.io/latest/docs/"]
|
||||||
"https://istio.io/",
|
|
||||||
"https://istio.io/latest/docs/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "vault",
|
"id": "vault",
|
||||||
@@ -174,10 +147,7 @@
|
|||||||
"id": "consul",
|
"id": "consul",
|
||||||
"name": "HashiCorp Consul",
|
"name": "HashiCorp Consul",
|
||||||
"description": "Service discovery et configuration",
|
"description": "Service discovery et configuration",
|
||||||
"links": [
|
"links": ["https://www.consul.io/", "https://learn.hashicorp.com/consul"]
|
||||||
"https://www.consul.io/",
|
|
||||||
"https://learn.hashicorp.com/consul"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "nomad",
|
"id": "nomad",
|
||||||
|
|||||||
Reference in New Issue
Block a user