Cours Vibe coding avec l'IA · Module 8: Clone de Slack

Tableau de bord analytique - métriques et graphiques

4 min de lecture
Dans cette leçon3

Le capitaine veut savoir si Communications du navire vit : combien de visiteurs, combien de clics, et combien font ce qui compte vraiment. Sans chiffres, on navigue dans le brouillard. Construisons un tableau de bord avec cartes de statistiques et graphique, la table de navigation de la passerelle.

Les mesures

D'abord, un lexique : views désigne les vues, clicks les clics, conversions les objectifs atteints, comme une inscription ou un achat. Chaque étape attire moins de monde : les conversions sont en général le plus petit nombre. On montre donc aussi la variation par rapport à la période précédente, car un nombre seul ne dit pas si l'on va dans la bonne direction.

Graphiques avec Recharts

Pour les graphiques, on utilise Recharts, qui fournit des graphiques sous forme de composants React. L'installation tient en une commande :

1npm install recharts

La commande ajoute recharts aux dépendances de package.json, mais ne dessine encore rien. Le README recommande aussi le paquet react-is, dans la version de ton React. Ensuite, tu assembles un graphique linéaire avec des briques :

1import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts';
2
3function ViewsChart() {
4  const data = [
5    { date: '2024-01', views: 400 },
6    { date: '2024-02', views: 300 },
7    { date: '2024-03', views: 600 },
8    { date: '2024-04', views: 800 }
9  ];
10
11  return (
12    <LineChart width={600} height={300} data={data}>
13      <CartesianGrid strokeDasharray="3 3" />
14      <XAxis dataKey="date" />
15      <YAxis />
16      <Tooltip />
17      <Line type="monotone" dataKey="views" stroke="#3b82f6" />
18    </LineChart>
19  );
20}

Recharts lit les champs des objets de données par le nom donné dans dataKey. XAxis prend le mois dans dataKey="date", et Line trace les valeurs de dataKey="views". CartesianGrid ajoute une grille en pointillés, Tooltip affiche la valeur au survol et type="monotone" lisse la courbe. Les données ne changent pas, seule leur image change. Un width={600} fixe déborde d'un écran de téléphone : enveloppe le graphique dans ResponsiveContainer pour qu'il prenne la largeur du parent. Avec l'App Router de Next.js, place le graphique dans un composant 'use client', car Recharts tourne dans le navigateur.

Cartes de statistiques

Au-dessus du graphique, des cartes montrent les chiffres clés :

1function StatsGrid() {
2  const stats = [
3    { label: 'Total Views', value: '12.5K', change: '+12%', up: true },
4    { label: 'Clicks', value: '3.2K', change: '+5%', up: true },
5    { label: 'Conversions', value: '450', change: '-2%', up: false }
6  ];
7
8  return (
9    <div className="grid grid-cols-3 gap-4">
10      {stats.map(stat => (
11        <div key={stat.label} className="border rounded p-4 bg-white">
12          <p className="text-sm text-gray-600">{stat.label}</p>
13          <p className="text-3xl font-bold">{stat.value}</p>
14          <p className={`text-sm ${stat.up ? 'text-green-600' : 'text-red-600'}`}>
15            {stat.change}
16          </p>
17        </div>
18      ))}
19    </div>
20  );
21}

Chaque carte (stat) a quatre champs : label, value, change et up. Quand up est vrai, la variation est verte (text-green-600), et en cas de baisse rouge (text-red-600). Une expression conditionnelle dans className choisit la couleur : les données n'ont pas à connaître les couleurs. La variation est ici écrite en dur ; dans un vrai tableau de bord, tu la calcules à partir de deux périodes :

1const changePercent = Math.round(((current - previous) / previous) * 100);
2const up = changePercent >= 0;

Pour 450 conversions contre 460 un mois plus tôt, on obtient -2 %, donc up vaut false. Les nombres eux-mêmes restent intacts, ils produisent seulement deux nouveaux champs.

Un graphique à barres simple se passe même de bibliothèque : avec des div, la hauteur d'une barre est un pourcentage de la plus grande valeur :

1const maxViews = Math.max(...chartData.map(d => d.views));
2
3function barHeight(views: number) {
4  return `${(views / maxViews) * 100}%`;
5}

La plus haute barre obtient 100 %, les autres moins, en proportion. Le résultat va dans style={{ height: barHeight(d.views) }}, et les données d'entrée restent intactes.

Conseil du Capitaine Barbe-Rouge : avant de dessiner un graphique, demande-toi quelle décision il doit faciliter. Une jolie courbe sans conclusion n'est qu'une décoration sur le mât.

À retenir : une carte montre un nombre et le sens de la variation, un graphique la tendance. Dans l'éditeur ci-dessous, tu as un tableau de bord analytique avec des cartes de statistiques ; les exercices porteront sur la bibliothèque de graphiques et les cartes.

Code de cette leçon : App.jsx
1// Tableau de bord analytique - cartes de statistiques + graphique en barres
2import { useState } from 'react';
3
4const stats = [
5  { label: 'Vues totales', value: '12.5K', change: '+12%', up: true },
6  { label: 'Clics', value: '3.2K', change: '+5%', up: true },
7  { label: 'Conversions', value: '450', change: '-2%', up: false }
8];
9
10const chartData = [
11  { month: 'Janv.', views: 400 },
12  { month: 'Févr.', views: 300 },
13  { month: 'Mars', views: 600 },
14  { month: 'Avr.', views: 800 }
15];
16
17export default function App() {
18  const maxViews = Math.max(...chartData.map(d => d.views));
19
20  return (
21    <div className="min-h-screen bg-gray-100 p-8">
22      <div className="max-w-4xl mx-auto">
23        <h1 className="text-2xl font-bold mb-6">Tableau de bord analytique</h1>
24
25        {/* Grille des cartes de statistiques */}
26        <div className="grid grid-cols-3 gap-4 mb-8">
27          {stats.map(stat => (
28            <div key={stat.label} className="border rounded p-4 bg-white">
29              <p className="text-sm text-gray-600">{stat.label}</p>
30              <p className="text-3xl font-bold">{stat.value}</p>
31              <p className={`text-sm ${stat.up ? 'text-green-600' : 'text-red-600'}`}>
32                {stat.change}
33              </p>
34            </div>
35          ))}
36        </div>
37
38        {/* Graphique en barres simple */}
39        <div className="bg-white border rounded p-6">
40          <h2 className="font-semibold mb-4">Vues par mois</h2>
41          <div className="flex items-end gap-4 h-48">
42            {chartData.map(d => (
43              <div key={d.month} className="flex-1 flex flex-col items-center justify-end">
44                <div
45                  className="w-full bg-blue-500 rounded-t"
46                  style={{ height: `${(d.views / maxViews) * 100}%` }}
47                ></div>
48                <span className="text-xs text-gray-600 mt-2">{d.month}</span>
49                <span className="text-xs font-semibold">{d.views}</span>
50              </div>
51            ))}
52          </div>
53        </div>
54      </div>
55    </div>
56  );
57}

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelle bibliothèque utilise-t-on pour les graphiques du tableau de bord ?

  2. 2. Quels champs possède une carte de statistique (stat) ?

Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.

Tâches pratiques dans le jeu

  • Éditeur de code

    Tableau de bord analytique avec cartes et graphique

  • Tri horizontal

    Ordonne la commande pour installer la bibliothèque de graphiques (une ligne, de gauche à droite) :

Articles utiles