◆ Portail Antalaha

Annuaire › Code ouvert

Pluviométrie mensuelle - tableau de bord (p5.js)

tutorial · Voir le site ↗
Connectez-vous pour copier ce site

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;
}