Tableau Périodique Interactif
Vue d'ensemble
Tableau périodique des 118 éléments entièrement intégré au portfolio, accessible via /projects/tableau-periodique. Conçu comme un outil pédagogique à double vocation : visualisation scientifique pour les chercheurs/étudiants, et apprentissage ludique de la chimie pour le grand public.
Public cible : étudiants en chimie, enseignants, curieux de sciences. Contexte : projet personnel pour illustrer la maîtrise de React/TypeScript et l'intérêt pour la chimie (lié au travail sur Datalab).
Ressources clés
- Next.js App Router — routing,
page.tsx,layout.tsx - React
useMemo— mémorisation des calculs de heatmap (évite recalcul à chaque render) - React
useEffect+ fetch — chargement du JSON enrichi - Tailwind CSS v4 — utilitaires de layout et de couleur
- HSL color model — MDN — base des fonctions de heatmap (
hslColor,heatColor) - Turbopack limitations — raison pour laquelle les JSON sont en
fetch()et non enimportdynamique - PubChem Periodic Table data — référence pour les valeurs physico-chimiques (électronégativité, énergie d'ionisation, rayon atomique)
- NMR-active nuclei — SDBS — référence pour
nmrSpinMap(spin par numéro atomique)
Stack technique
| Lib | Usage |
|---|---|
| React 19 + Next.js App Router | Rendu, routing |
| TypeScript strict | Typage des données éléments, modes de vue |
| Tailwind CSS v4 | Layout et styles |
fetch() + useEffect | Chargement du JSON enrichi (incompatible Turbopack avec import dynamique) |
Pas de lib de visualisation externe — les heatmaps et couleurs sont calculées manuellement via des fonctions HSL.
Architecture
src/app/projects/tableau-periodique/
page.tsx # Orchestrateur principal : état global, rendu du tableau, onglets
AnecdotesView.tsx # Mode apprentissage — onglet Anecdotes
MnemoniquesView.tsx # Mode apprentissage — onglet Mnémotechniques
QuizView.tsx # Mode apprentissage — onglet Quiz
FriseView.tsx # Mode apprentissage — onglet Frise chronologique
elements-data.ts # 118 éléments statiques (Z, symbole, nom FR/EN, famille, masse, etc.)
public/data/
elements-enriched.json # 118 éléments enrichis : anecdotes FR/EN + données découverte
Responsabilités de page.tsx
- Gère l'état du mode de vue (
pageTab:"visualisation"|"apprentissage") - Gère le mode de couleur (
viewMode:"family"|"nmr"|"electronegativity"|"ionization"|"radius") - Gère l'élément sélectionné et le tooltip
- Rend le tableau périodique complet (grille CSS manuelle avec positionnement par période/groupe)
- Passe
langaux sous-composants du mode apprentissage
Fonctionnalités
Mode Visualisation
Cinq modes de coloration sélectionnables via des boutons de filtre :
Familles chimiques (family)
Chaque famille a une couleur fixe définie dans catColors :
- Métal alcalin → orange
#ff6b35 - Métal alcalino-terreux → beige
#f7c59f - Métal de transition → bleu
#4a9eff - Métal post-transition → vert
#34d399 - Métalloïde → violet
#a78bfa - Non-métal → jaune
#facc15 - Halogène → rose
#fb7185 - Gaz noble → cyan
#22d3ee - Lanthanide → fuschia
#e879f9 - Actinide → teal
#0d9488
RMN (nmr)
Coloration selon le spin nucléaire, déterminé par nmrSpinMap (record Z → type) :
- Spin 0 (inactif) → gris
- Spin 1/2 → vert
- Spin > 1/2 (quadrupolaire) → bleu
Heatmaps continues
Pour electronegativity, ionization, radius : la fonction heatColor(value, min, max, invert?) mappe la valeur sur une plage hue HSL 220° (bleu froid) → 0° (rouge chaud). Les valeurs null sont affichées en gris ardoise.
Tooltip élément
Au clic ou survol, un tooltip affiche : symbole, nom, Z, masse atomique, famille, et la valeur dans le mode courant.
Mode Apprentissage
Quatre onglets, chacun dans un composant dédié :
AnecdotesView
- Charge
elements-enriched.jsonviafetch()dans unuseEffect - Affiche le tableau périodique miniature ; au clic sur un élément, affiche l'anecdote correspondante (FR ou EN selon
lang) - Le tableau est rendu avec les couleurs par famille (reproduites localement dans
CAT_COLORS)
MnemoniquesView
- Affiche les moyens mnémotechniques pour mémoriser l'ordre des éléments par période
- Contenu statique inline (pas de fetch)
QuizView
Quatre types de quiz :
- Nom → Symbole : donné le nom, trouver le symbole
- Z → Nom : donné le numéro atomique, trouver le nom
- Symbole → Famille : donné le symbole, trouver la famille
- Symbole → Nom : donné le symbole, trouver le nom
Chaque question propose 4 choix (1 correct + 3 distracteurs tirés aléatoirement). Score affiché en fin de session.
FriseView
- Charge
elements-enriched.jsonpour récupérer les données de découverte (année, découvreur) - Affiche une frise chronologique interactive des découvertes d'éléments
Données
elements-data.ts (statique, importé)
118 objets ElementData avec au minimum :
atomicNumber(Z)symbolname(string, FR par défaut)category(clé decatColors)period,groupatomicMasselectronegativity,ionizationEnergy,atomicRadius(nullable)
elements-enriched.json (fetch dynamique)
Chargé via fetch('/data/elements-enriched.json') dans les composants qui en ont besoin.
Structure par élément :
{
"atomicNumber": 1,
"symbol": "H",
"name": { "fr": "Hydrogène", "en": "Hydrogen" },
"anecdote": { "fr": "...", "en": "..." },
"discoveryYear": 1766,
"discoverer": "Henry Cavendish"
}
i18n
- Le composant possède son propre toggle de langue indépendant du contexte global (
useLang()), car la page est souvent utilisée de façon autonome - Les chaînes UI (titres, onglets, labels, placeholders) sont dans
i18n/fr.tseti18n/en.tssous la cléperiodic_table.*— accédées via(lang === 'fr' ? frStrings : enStrings).periodic_table - Les labels de catégories/NMR/états sont dans des records locaux (
catColors,nmrColors,stateLabel) avec leurs variantes EN dansCAT_LABELS_EN,NMR_LABELS_EN,STATE_LABELS_EN— ces données restent locales car elles sont couplées aux données de rendu - Les noms d'éléments dans
elements-data.tssont en FR uniquement ; les variantes EN sont dansELEMENT_NAMES_EN - Les anecdotes et noms dans
elements-enriched.jsonsont bilingues FR/EN
Points d'attention
- Turbopack incompatible avec
import()dynamique sur les JSON : utiliserfetch()dansuseEffectuniquement. - Positionnement du tableau : la grille CSS est construite manuellement (pas de lib). Les lanthanides/actinides sont séparés en bas comme dans la convention standard.
- Performance : 118 éléments rendus simultanément — pas de virtualisation. Acceptable car les cellules sont légères.
- NMR data :
nmrSpinMapest un record manuel (Z → type), non exhaustif pour certains isotopes rares. Seul l'isotope le plus courant est pris en compte.
Évolutions possibles
- Configuration électronique par élément dans le tooltip (notation
1s² 2s²...) - Mode "découverte géographique" (carte du monde avec pin par lieu de découverte)
- Filtrage par propriété (ex: afficher uniquement les éléments radioactifs, les solides, les liquides)
- Persistance du quiz : score historique + streak via localStorage
- Heatmap supplémentaire : point de fusion/ébullition
- Mode comparaison : sélectionner 2 éléments et voir leurs propriétés côte à côte