Annuaire › Code ouvert
Code publié par son auteur, en lecture seule. « Copier dans mon espace » crée un nouveau site à vous (non publié) que vous pouvez modifier librement.
js/donnees.js · 6.1 Ko
/* ============================================================
donnees.js - calculs sur les données (sans aucun dessin)
============================================================
Séparer les CALCULS du DESSIN rend le code plus clair : ici on
ne trouve que des fonctions qui prennent des tableaux et
renvoient des nombres ou du texte.
Convention : une "série" est un tableau de 12 nombres (un par mois).
Le choix « moyenne » correspond à la moyenne de toutes les années.
============================================================ */
/* ------------------------------------------------------------
listeAnnees()
But : donner la liste des années disponibles, triées.
Retour : tableau de nombres, ex. [2021, 2022, 2023, 2024]
------------------------------------------------------------ */
function listeAnnees() {
// Object.keys() donne les clés de l'objet (en texte) ; map(Number) les convertit en nombres.
return Object.keys(PLUIE_PAR_ANNEE).map(Number).sort(function (a, b) { return a - b; });
}
/* ------------------------------------------------------------
serieMoyenne()
But : calculer, pour chaque mois, la moyenne sur toutes les années.
Retour : tableau de 12 nombres.
------------------------------------------------------------ */
function serieMoyenne() {
const annees = listeAnnees();
const moyenne = [];
for (let mois = 0; mois < 12; mois++) {
let somme = 0;
for (const a of annees) {
somme += PLUIE_PAR_ANNEE[a][mois]; // valeur de ce mois pour l'année a
}
moyenne.push(somme / annees.length);
}
return moyenne;
}
/* ------------------------------------------------------------
serieChoisie(choix)
But : renvoyer la série correspondant au choix de l'utilisateur.
Paramètre : choix = 'moyenne' ou une année (ex. '2023' ou 2023)
Retour : tableau de 12 nombres
------------------------------------------------------------ */
function serieChoisie(choix) {
if (choix === 'moyenne') return serieMoyenne();
const serie = PLUIE_PAR_ANNEE[choix];
// Si l'année n'existe pas (ne devrait pas arriver), on se rabat sur la moyenne.
return serie ? serie : serieMoyenne();
}
/* ------------------------------------------------------------
libelleChoix(choix)
But : texte à afficher pour le choix (« 2023 » ou « Moyenne 2021-2024 »).
------------------------------------------------------------ */
function libelleChoix(choix) {
if (choix === 'moyenne') {
const annees = listeAnnees();
return 'Moyenne ' + annees[0] + '-' + annees[annees.length - 1];
}
return String(choix);
}
/* ------------------------------------------------------------
maximumGlobal()
But : trouver la plus grande valeur de TOUTES les années.
On s'en sert pour fixer l'échelle verticale : ainsi, quand on
change d'année, l'échelle ne bouge pas et les comparaisons restent justes.
------------------------------------------------------------ */
function maximumGlobal() {
let maxi = 0;
for (const a of listeAnnees()) {
maxi = Math.max(maxi, ...PLUIE_PAR_ANNEE[a]); // "..." étale le tableau en arguments
}
return maxi;
}
/* ------------------------------------------------------------
echelleVerticale()
But : calculer la valeur maximale de l'axe (arrondie au-dessus)
et le pas des graduations.
Retour : {maxi, pas} ex. {maxi: 500, pas: 100}
------------------------------------------------------------ */
function echelleVerticale() {
const m = maximumGlobal();
const pas = (m <= 300) ? PAS_GRADUATION_FIN : PAS_GRADUATION;
// Math.ceil arrondit à l'entier supérieur : 455 / 100 = 4,55 -> 5 -> 500.
return { maxi: Math.ceil(m / pas) * pas, pas: pas };
}
/* ------------------------------------------------------------
total(serie)
But : somme des 12 valeurs (cumul annuel).
------------------------------------------------------------ */
function total(serie) {
let somme = 0;
for (const v of serie) somme += v;
return somme;
}
/* ------------------------------------------------------------
indexMaximum(serie) / indexMinimum(serie)
But : numéro du mois (0 à 11) le plus / le moins pluvieux.
------------------------------------------------------------ */
function indexMaximum(serie) {
let meilleur = 0;
for (let i = 1; i < serie.length; i++) {
if (serie[i] > serie[meilleur]) meilleur = i;
}
return meilleur;
}
function indexMinimum(serie) {
let meilleur = 0;
for (let i = 1; i < serie.length; i++) {
if (serie[i] < serie[meilleur]) meilleur = i;
}
return meilleur;
}
/* ------------------------------------------------------------
texteResume(choix)
But : phrase de résumé (affichée sous le graphique et utilisée
pour la description accessible du canevas).
------------------------------------------------------------ */
function texteResume(choix) {
const s = serieChoisie(choix);
const imax = indexMaximum(s);
const imin = indexMinimum(s);
return libelleChoix(choix) + ' (valeurs d\'illustration) : cumul d\'environ ' +
Math.round(total(s)) + ' mm. Mois le plus pluvieux : ' + MOIS_COMPLETS[imax] +
' (' + Math.round(s[imax]) + ' mm). Mois le plus sec : ' + MOIS_COMPLETS[imin] +
' (' + Math.round(s[imin]) + ' mm).';
}
/* ------------------------------------------------------------
remplirTableauHTML()
But : construire le tableau HTML de toutes les données
(alternative texte au graphique, pour l'accessibilité).
On fabrique du texte HTML puis on l'insère dans <table>.
------------------------------------------------------------ */
function remplirTableauHTML() {
const annees = listeAnnees();
const moyenne = serieMoyenne();
let html = '<thead><tr><th scope="col">Mois</th>';
for (const a of annees) html += '<th scope="col">' + a + '</th>';
html += '<th scope="col">Moyenne</th></tr></thead><tbody>';
for (let m = 0; m < 12; m++) {
html += '<tr><th scope="row">' + MOIS_COMPLETS[m] + '</th>';
for (const a of annees) html += '<td>' + PLUIE_PAR_ANNEE[a][m] + '</td>';
html += '<td>' + Math.round(moyenne[m]) + '</td></tr>';
}
html += '</tbody>';
document.getElementById('tableau-donnees').innerHTML = html;
}