Line Graph
SVG défilant en temps réel : la courbe et son remplissage en dégradé se mettent à jour image par image via rAF en combinant onde sinusoïdale et bruit aléatoire.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Atmosphère comprend 57 effets, dont 10 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le composant repose sur un <svg viewBox="0 0 300 100" preserveAspectRatio="none"> contenant deux chemins superposés : <path class="area"> pour la zone remplie sous la courbe et <path class="line"> pour le trait. preserveAspectRatio="none" force le SVG à s'étirer pour remplir exactement son conteneur CSS — la proportion n'est pas conservée, ce qui rend le graphe adaptatif à n'importe quelle largeur sans JavaScript.
L'animation repose sur un tableau glissant de 60 valeurs, initialisées à 50 (centre du viewBox). À chaque frame requestAnimationFrame, la fonction animateLineGraph exécute lineData.shift() pour éjecter le point le plus ancien, puis pousse un nouveau point calculé comme 50 + Math.sin(time × 0.005) × 30 + Math.random() × 20 − 10 : une onde sinusoïdale d'amplitude ±30 définit l'allure générale de la courbe, tandis que le bruit aléatoire ±10 simule la volatilité de données réelles. Pas d'interpolation ni de lissage — chaque point génère un segment L SVG brut.
Les attributs d des deux chemins sont reconstruits intégralement à chaque frame via setAttribute. Le chemin de la ligne part de M0,y[0] puis enchaîne L xi,yi pour les 59 points restants. Le chemin de la zone suit le même tracé mais ferme la forme par L300,100 Z — le bas du viewBox — pour former le polygone rempli.
La règle CSS fill: url(#areaGradient) attend un <linearGradient id="areaGradient"> déclaré dans un bloc <defs> du SVG. Ce gradient est absent du HTML de base : sans lui, la zone s'affiche noire ou transparente selon le navigateur. L'animation est pilotée par un requestAnimationFrame partagé avec d'autres effets du même IIFE — seule animateLineGraph est active quand les éléments id="linePath" et id="lineArea" sont présents dans le DOM.
Accessibilité
- prefers-reduced-motion absent du code : l'animation tourne inconditionnellement, quelle que soit la préférence système. Pour une conformité WCAG 2.3.3, ajoutez un guard
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;avant le premierrequestAnimationFrame. - Le
<svg>ne porte niaria-hidden, nirole, niaria-label— il est traité comme contenu générique par les lecteurs d'écran. Ajoutezaria-hidden="true"si le graphe est purement décoratif, ourole="img" aria-label="…"s'il transmet une information. - Pas de
<title>dans le SVG : les technologies d'assistance ne reçoivent aucune description de la courbe. - La couleur de trait
#6366f1sur fond#0a0a0foffre un ratio de contraste d'environ 4,6:1 — au niveau WCAG AA pour le texte normal, et largement suffisant pour un élément graphique décoratif. - Aucune interaction clavier ou souris n'est implémentée — l'effet est purement décoratif, ce qui limite les besoins d'accessibilité interactive.
Compatibilité navigateur
Requiert SVG inline et requestAnimationFrame — supportés dans tous les navigateurs modernes depuis 2013.
Si SVG n'est pas rendu (navigateurs très anciens ou lecteurs d'écran en mode texte), les chemins <code><path></code> n'apparaissent pas — aucune erreur JS, la page reste fonctionnelle avec les éventuels éléments texte overlay.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="demo-preview">
<div class="line-graph" id="lineGraph">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<!-- Déclarez le gradient pour le remplissage (absent du HTML de base) -->
<defs>
<linearGradient id="areaGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#6366f1" stop-opacity="0.35"/>
<stop offset="100%" stop-color="#6366f1" stop-opacity="0.03"/>
</linearGradient>
</defs>
<path class="area" id="lineArea"></path>
<path class="line" id="linePath"></path>
</svg>
</div>
</div>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| .line { stroke } | #6366f1 | Couleur de la courbe — remplacez par votre couleur brand. Toutes les valeurs CSS de couleur sont acceptées. |
| .line { stroke-width } | 2 | Épaisseur de la courbe en px. 1 = léger et discret, 3–4 = trait affirmé. |
| url(#areaGradient) dans |
non défini dans le HTML de base | Gradient sous la courbe : déclarez manuellement un <linearGradient id="areaGradient"> dans les <defs> du SVG (voir structure_html) avec stop-color et stop-opacity selon votre palette. |
| .line-graph { height } | 120px | Hauteur du conteneur SVG. La courbe s'étire proportionnellement (preserveAspectRatio="none") — ajustez sans toucher au viewBox. |
| Array(60) — taille du buffer | 60 | Nombre de points dans l'historique glissant. Plus ce nombre est grand, plus le défilement est lent (60 ≈ 1 seconde à 60 fps). Réduisez à 30 pour un défilement plus réactif. |
| time * 0.005 — fréquence sinusoïdale | 0.005 | Fréquence de l'onde sinusoïdale. 0.002 = courbe très lente et ample, 0.012 = ondulation rapide et nerveuse. |
| Math.random() * 20 - 10 — bruit | amplitude ±10 | Composante aléatoire ajoutée à chaque point. Réduisez à ±3 pour une courbe lisse (dashboard financier), augmentez à ±20 pour une forte volatilité (monitoring réseau). |
FAQ
.area { fill: url(#areaGradient) } référence un identifiant qui n'est pas défini dans le HTML de base. Ajoutez un bloc <defs> dans votre <svg> (voir structure_html) contenant un <linearGradient id="areaGradient"> avec deux stops de couleur et d'opacité — le remplissage apparaît immédiatement.const newValue = 50 + Math.sin(…) dans animateLineGraph par la valeur que vous souhaitez, normalisée dans l'intervalle [0, 100] pour rester dans le viewBox SVG. Poussez les valeurs depuis un callback WebSocket ou un fetch polling : lineData.push(valeurNormalisée); lineData.shift(); suffit — la frame courante lira la nouvelle valeur au prochain appel requestAnimationFrame.getElementById('linePath') et getElementById('lineArea'), identifiants uniques par page. Pour plusieurs instances, extrayez la logique animateLineGraph dans une fonction qui reçoit les éléments cibles en paramètre, puis lancez un requestAnimationFrame séparé par instance — comme illustré dans les scènes 2 et 3 du fichier d'exemples de cet effet.