Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
- scripts/build-normales.mjs : agrégation TN/TX mensuelles par dept sur la période WMO 1991-2020 depuis les fichiers Q_<DEPT>_previous-1950-2024. Output src/data/normales.json (78 KB, committé). Run annuel max. - Corse : Météo France utilise le code historique "20" (avant split 2A/2B en 1976), donc 2A et 2B partagent la même normale issue de Q_20_*. - src/lib/normales.ts : computeAnomaly() qui moyenne TX/TN des 7 derniers jours, compare à la normale du mois, calcule l'écart en °C et en σ, catégorise (normal / warm / cool / anomaly_warm / anomaly_cool / extreme_warm / extreme_cool / unknown). - src/components/AnomalyBadge.astro : badge coloré (vert/jaune/orange/rouge) visible sur /departement/[code] juste au-dessus du graphe T°. Différencie "il fait chaud" de "il fait anormalement chaud pour ce mois". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
80 lines
2.5 KiB
Text
80 lines
2.5 KiB
Text
---
|
||
import type { Anomaly } from '../lib/normales';
|
||
|
||
interface Props {
|
||
anomaly: Anomaly;
|
||
}
|
||
|
||
const { anomaly } = Astro.props;
|
||
|
||
const CATEGORY_LABEL: Record<Anomaly['txCategory'], { label: string; cls: string; icon: string }> = {
|
||
normal: {
|
||
label: 'Températures dans la normale saisonnière',
|
||
cls: 'border-slate-200 bg-slate-50 text-slate-700',
|
||
icon: '🌡️',
|
||
},
|
||
warm: {
|
||
label: 'Légèrement au-dessus de la normale',
|
||
cls: 'border-yellow-200 bg-yellow-50 text-yellow-900',
|
||
icon: '↗',
|
||
},
|
||
cool: {
|
||
label: 'Légèrement en dessous de la normale',
|
||
cls: 'border-blue-200 bg-blue-50 text-blue-900',
|
||
icon: '↘',
|
||
},
|
||
anomaly_warm: {
|
||
label: 'Anormalement chaud',
|
||
cls: 'border-orange-300 bg-orange-50 text-orange-900',
|
||
icon: '🔥',
|
||
},
|
||
anomaly_cool: {
|
||
label: 'Anormalement frais',
|
||
cls: 'border-blue-300 bg-blue-100 text-blue-900',
|
||
icon: '❄',
|
||
},
|
||
extreme_warm: {
|
||
label: 'Extrêmement chaud (déviation extrême)',
|
||
cls: 'border-red-300 bg-red-50 text-red-900 font-semibold',
|
||
icon: '🚨',
|
||
},
|
||
extreme_cool: {
|
||
label: 'Extrêmement frais (déviation extrême)',
|
||
cls: 'border-blue-400 bg-blue-200 text-blue-900 font-semibold',
|
||
icon: '🚨',
|
||
},
|
||
unknown: {
|
||
label: 'Normale non disponible pour ce mois',
|
||
cls: 'border-slate-200 bg-slate-50 text-slate-500',
|
||
icon: '?',
|
||
},
|
||
};
|
||
|
||
const cat = CATEGORY_LABEL[anomaly.txCategory];
|
||
const signDiff = (anomaly.diffTx ?? 0) > 0 ? '+' : '';
|
||
---
|
||
|
||
<div class:list={['rounded-lg border p-4', cat.cls]}>
|
||
<div class="flex items-center gap-2 text-sm font-semibold">
|
||
<span aria-hidden="true">{cat.icon}</span>
|
||
<span>{cat.label}</span>
|
||
</div>
|
||
{anomaly.diffTx !== null && anomaly.normaleTx !== null && (
|
||
<p class="mt-2 text-sm">
|
||
<strong>T° max moyenne {anomaly.windowDays} derniers jours :</strong>{' '}
|
||
<span class="font-mono">{anomaly.meanTx}°C</span>
|
||
<span class="text-slate-500"> · normale du mois (1991-2020) : <span class="font-mono">{anomaly.normaleTx}°C</span></span>
|
||
</p>
|
||
<p class="mt-1 text-sm">
|
||
<strong>Écart :</strong>{' '}
|
||
<span class="font-mono">{signDiff}{anomaly.diffTx}°C</span>
|
||
{anomaly.sigmaTx !== null && (
|
||
<span class="text-xs text-slate-500"> ({anomaly.sigmaTx > 0 ? '+' : ''}{anomaly.sigmaTx}σ)</span>
|
||
)}
|
||
</p>
|
||
)}
|
||
<p class="mt-2 text-xs text-slate-500">
|
||
Comparaison sur la période de référence WMO 1991-2020. σ = écart-type, mesure de l'amplitude
|
||
historique du mois ; au-delà de 2σ l'événement est statistiquement rare.
|
||
</p>
|
||
</div>
|