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

Stack technique

LibUsage
React 19 + Next.js App RouterRendu, routing
TypeScript strictTypage des données éléments, modes de vue
Tailwind CSS v4Layout et styles
fetch() + useEffectChargement 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 lang aux 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.json via fetch() dans un useEffect
  • 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 :

  1. Nom → Symbole : donné le nom, trouver le symbole
  2. Z → Nom : donné le numéro atomique, trouver le nom
  3. Symbole → Famille : donné le symbole, trouver la famille
  4. 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.json pour 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)
  • symbol
  • name (string, FR par défaut)
  • category (clé de catColors)
  • period, group
  • atomicMass
  • electronegativity, 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.ts et i18n/en.ts sous 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 dans CAT_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.ts sont en FR uniquement ; les variantes EN sont dans ELEMENT_NAMES_EN
  • Les anecdotes et noms dans elements-enriched.json sont bilingues FR/EN

Points d'attention

  • Turbopack incompatible avec import() dynamique sur les JSON : utiliser fetch() dans useEffect uniquement.
  • 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 : nmrSpinMap est 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