Skip to content
← 1001 Widgets
N° 047 · ●●●

Weekly weather

Seven-day forecasts for Brussels, Geneva or Montreal, with a small chart of temperatures and rain. The right exercise to turn API data into an SVG drawing.

JSAPI
What you'll learn
  • Request daily forecasts from Open-Meteo
  • Convert values into SVG coordinates
  • Translate weather codes into words
Why this language

Pourquoi une météo de la semaine ? La météo du jour dit s'il faut un parapluie. Celle de la semaine dit quand organiser le barbecue. Et un graphique se lit bien plus vite qu'un tableau de chiffres.

Open-Meteo renvoie, pour chaque jour, la température maximale, la minimale, la pluie attendue et un code de temps. Il suffit d'ajouter le paramètre daily et de choisir les champs.

Pour dessiner, on transforme chaque température en hauteur : la plus chaude en haut, la plus froide en bas. Les points deviennent une polyline SVG, la pluie des barres. Pas de bibliothèque de graphiques : une règle de trois suffit.

Pourquoi en JavaScript simple ? Un fetch, deux fonctions d'échelle et quelques chaînes SVG. Hors ligne, la démo affiche des données d'exemple et le dit.

How it works
  1. LA REQUÊTE

    Une ville = des coordonnées. daily liste les champs voulus pour chaque jour.

    const url = 'https://api.open-meteo.com/v1/forecast'
      + '?latitude=50.85&longitude=4.35'
      + '&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,weather_code'
      + '&timezone=auto&forecast_days=7';
    const { daily } = await fetch(url).then(r => r.json());
  2. LES ÉCHELLES

    x : un jour tous les n pixels. y : la température la plus haute en haut.

    const W = 350, haut = 22, bas = 118, marge = 18;
    const toutes = [...daily.temperature_2m_max, ...daily.temperature_2m_min];
    const min = Math.min(...toutes) - 1, max = Math.max(...toutes) + 1;
    const x = i => marge + i * (W - 2 * marge) / 6;
    const y = t => bas - (t - min) / (max - min) * (bas - haut);
  3. LA COURBE

    Une polyline relie les points : "x1,y1 x2,y2 ...".

    const points = daily.temperature_2m_max.map((t, i) => `${x(i)},${y(t)}`).join(' ');
    svg.innerHTML = `<polyline points="${points}" fill="none" stroke="currentColor" stroke-width="2.5"/>`;
  4. LES CODES MÉTÉO

    L'API renvoie des codes standard : on les traduit en mots.

    const CIEL = { 0: 'Clair', 1: 'Éclaircies', 2: 'Nuages', 3: 'Couvert', 61: 'Pluie', 71: 'Neige', 95: 'Orage' };
    const ciel = code => CIEL[code] ?? 'Variable';
  5. LES JOURS

    Midi évite qu'un décalage horaire fasse glisser la date d'un jour.

    const jour = iso => new Intl.DateTimeFormat('fr-BE', { weekday: 'short' }).format(new Date(iso + 'T12:00:00'));
Pitfalls

PIÈGE 1 : Une échelle qui écrase tout

Pitfall

Mauvais : une échelle fixe de -20 à 40 degrés. Une semaine entre 9 et 15 degrés devient une ligne plate.

Fix

Correct : calculer le minimum et le maximum de la semaine, avec un degré de marge de chaque côté.

PIÈGE 2 : La date qui recule d'un jour

Pitfall

Mauvais : new Date('2026-10-19'). C'est minuit en UTC, donc encore le 18 au soir à Montréal.

Fix

Correct : ajouter une heure, comme T12:00:00, ou demander timezone=auto à l'API et formater sans conversion.

PIÈGE 3 : Un graphique muet

Pitfall

Mauvais : un SVG sans texte alternatif. Les lecteurs d'écran ne disent rien.

Fix

Correct : role="img" et un aria-label qui résume la semaine, par exemple les maximales de 9 à 15 degrés.

PERSONNALISER
  • La géolocalisation du navigateur pour la ville de l'utilisateur, avec son accord.
  • Le vent et l'indice UV, deux champs de plus dans la requête.
  • Un graphique heure par heure pour la journée sélectionnée.
OPTIMISATION
  • Gardez la réponse en cache une heure : les prévisions ne changent pas plus souvent.
  • Lissez la courbe avec un chemin SVG en courbes de Bézier plutôt qu'une polyline.
VERS REACT

La ville est un useState ; les prévisions se chargent dans un useEffect qui annule la requête précédente avec AbortController.

Le graphique devient un composant qui reçoit les tableaux et rend directement du SVG en JSX.

Pour un projet plus grand, une bibliothèque comme visx ou Recharts gère axes et infobulles.

Comments
0/1000

Loading comments…

Audience measurement

With your consent, this site measures its traffic with Google Analytics and the Meta pixel, via Google Tag Manager. Nothing is loaded until you choose, and you can change your mind at any time with the "Cookies" link at the bottom of the page.