Génération d’une page web à partir de données csv

Document élève

Objectif

L’objectif de cette activité est faire découvrir l’utilisation du format csv et d’en extraire les informations souhaités en utilisant les listes, de générer une page web dynamique en utilisant JQuery, un framework pour la mise en page et une librairie de conception de graphique.

L’activité s’appuie sur les données de qualité de l’air sur la ville d’Avignon. On souhaite en extraire les informations permettant de caractériser la qualité de l’air, les présenter dans un tableau et un graphique sur une page web afin de mettre en évidence les causes de pollutions.

Prérequis

  • Utilisation d’un environnement de développement (pycharm)

  • Types élémentaires : numériques et chaines de caractères

  • Types construis : tableaux

  • Structure algorithmique de base : boucle, test, écriture de fonction

  • Structure d’une page HTML

  • Utilisation d’une feuille de style css

  • Utilisation d’un script js

  • Utilisation des outils de développement web

Conditions

  • Activité su PC avec connexion internet

  • Niveau première

  • Type d’activité TD/TP

  • Durée : 8h

Rubriques du programme :

  • Représentation des données : types construits :

    • Les tableaux

  • Langage et programmation :

    • Constructions élémentaires

    • Spécification

    • Mise au point

  • Interactions entre l’homme et la machine sur le Web :

    • Examiner et compléter le code HTML d’une page web/css/js

Introduction

L’air que nous respirons peut contenir des centaines de polluants sous forme gazeuse, liquide ou solide. L’histoire de la surveillance des polluants en Provence-Alpes-Côte d’Azur a commencé il y a plus de 40 ans avec la mesure des concentrations d’acidité forte.

Depuis, le spectre des polluants surveillés n’a cessé de s’élargir, conformément au renforcement préconisé par les directives européennes.

Parmis ceux-ci, on trouve les NOx. Le terme « oxydes d’azote » désigne le monoxyde d’azote (NO) et le dioxyde d’azote (NO2). Ces composés sont formés par oxydation de l’azote atmosphérique (N2) lors des combustions (essentiellement à haute température) de carburants et de combustibles fossiles. Le dioxyde d’azote (NO2) est émis lors des phénomènes de combustion, principalement par combinaison de l’azote et de l’oxygène de l’air. Les sources principales sont les véhicules et les installations de combustion.

Le pot catalytique a permis depuis 1993, une diminution des émissions des véhicules à essence, mais l’effet reste encore peu perceptible compte tenu de la forte augmentation du trafic et de la durée de renouvellement du parc automobile. De plus, les véhicules diesel, en forte progression ces dernières années, rejettent davantage de NOx.

Téléchargement des données

Le site https://www.atmosud.org met à disposition les données des capteurs de qualité de l’air de différentes communes de la région PACA.

A faire

Sur le site https://www.atmosud.org, cliquer sur le bouton DONNEES & PUBLICATION puis sur sur le menu Stations de mesures et données. Choisir la station Avignon Mairie et télécharger les données des 30 derniers jours et des 12 derniers mois.

Les données sont au format csv (Comma-separated values). C’est un format texte ouvert représentant des données tabulaires sous forme de valeurs séparées par des virgules. La virgule étant le séparateur décimal en français, c’est un autre caractère qui est utilisé pour séparer les champs.

A l’aide d’un éditeur de texte simple, ouvrir les documents et identifier le séparateur de champs.

Préparation de la page web

On souhaite réaliser une page web sur laquelle se trouve :

  • La localisation de la station de mesure

  • La nature des polluants mesurés

  • Leurs effet sur la santé et sur l’environnement

  • Un tableau dynamique qui présente selon le choix de l’utilisateur les données sur les 30 derniers jours ou sur les 12 derniers mois

  • Un graphique dynamique qui présente selon le choix de l’utilisateur les courbes d’évolutions sur les 30 derniers jours ou sur les 12 derniers mois

A faire

Ecrire le squelette de la page web en préparant une div par élément à faire figurer et à renseigner avec le contenu adéquat :

<body>
	<div id="localisation">
		...
	</div>
	<div id="polluants">
		...
	</div>
	<div id="effets">
		...
	</div>
	<div id="tableau">
		...
	</div>
	<div id="graph">
		...
	</div>
</body>

Pour accélérer le développement de cette page web, utiliser les polices de https://fonts.google.com/ et le framework https://bulma.io :

Préparation des données

Pour rendre dynamique le tableau et le graphique, nous aurons besoin de javascript. Nous utiliserons ici jquery pour facilité l’accès aux éléments de la page (on parle d’éléments de l’abre DOM : Document Object Model).

Les données présentes dans les fichiers csv doivent être exploitées pour fournir un tableau javascript. C’est un script python qui sera chargé de cette tâche.

A faire

Ecrire un script python qui ouvre les fichiers csv, et fourni deux listes javascript contenant la date de mesure et la concentration de NOx avec la structure suivante :

_30jours = [[date, valeur], ['01/06/2019', 27,2], ...]
_12mois  = [[date, valeur], ['01/07/2018', 32.8], ...]

Le script python ci-dessous montre comment ouvrir et lire ligne par ligne un fichier csv. La méthode append permet d’insérer un nouvel élément à la liste data qui sera ensuite écrite dans le fichier tableau.js.

Les fichiers csv exportés depuis https://www.atmosud.org présentent leur données en lignes. Vous pourrez éventuellement les transposer en colonnes avant de les traiter avec votre script python.

import csv
data = []
for line in csv.reader(open("fichier.csv")):
    data.append(line) # une ligne entière
    data.append([line[0], float(line[1]), int(line[2])]) # un élément d'une ligne
open("tableau.js", "w").write('raw_data = ' + str(data))

Génération du tableau sur la page web

Dans une page web un tableau est matérialisé par un ensemble de balises :

<table>
	<tr>
		<th>Une cellule dans l'entête du tableau</th>
		<th>Une autre cellule</th>
	</tr>

	<tr>
		<td>Une cellule dans une ligne du tableau</td>
		<td>Une autre cellule</td>
	</tr>

	<tr>
		<td>Une cellule dans une ligne du tableau</td>
		<td>Une autre cellule</td>
	</tr>
</table>
Une cellule dans l’entête du tableau Une autre cellule

Une cellule dans une ligne du tableau

Une autre cellule

Une cellule dans une ligne du tableau

Une autre cellule

Le code javascript suivant, inclus dans le html de la page, permet de générer un tableau :

...
<head>
	...
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="tableau.js"></script>

    <script>

        function get_date(_liste) {
        	// Retourne une liste de date extaite de _liste passé en paramètre
        	// et issue du fichier tableau.js
        }

        function get_data(_liste) {
        	// Retourne une liste de données extaite de _liste passé en paramètre
        	// et issue du fichier tableau.js
        }

        function get_tableau(tableId, _date, _data) {
        	// Construit le tableau html dans la division tableId avec en colonnes
        	// les valeurs des listes _date et _data
        }

        // Code exécuter à l'ouverture de la page :
        $(function () {

            get_tableau("#tableau", get_date(_30jours), get_data(_30jours));

        });
    </script>
</head>
<body>
	...
	<div id="tableau"></div>
	...
</body>

A faire

Compléter le code de la fonction get_date(_liste) :

Utiliser les outils de développement web du navigateur pour observer le contenu de item

	function get_date(_liste) {
        var line;
        var data = [];
        _liste.forEach(function (item) {
            console.log(item);
            data.push(item[...]); //indice de l'item qui contient la date
        });
        return data;
    }

Sur le même modèle, écrire le code de la fonction get_data(_liste)

Le code javascript suivant permet de créer un tableau html :

var table = $("<table>");
table.attr('id', 'mon_tableau');
table.attr('class','table is-fullwidth');

head = $("<thead>").html("<tr><th>cellule entête 1</th><th>cellule entête 2</th></tr>");
table.append(head);

body = $("<tbody>");
table.append(body);

for (var i = 1; i < _liste1.length; i += 1) {
    line = $("<tr>");
    line.append($("<td>").text(_liste1[i]));
    line.append($("<td>").text(_liste2[i]));

    body.append(line);
}
//
$("#un_div").html(table);

A partir du code ci-dessus, écrire le code de la fonction get_tableau(tableId, _date, _data) et le commenter.

Les styles de bulma applicables aux tableaux sont détaillés ici : https://bulma.io/documentation/elements/table/

Gestion d’événements :

Avec JQuery, il est possible d’associer une action à un évènement. Par exemple on pourra executer une action lorsque l’utilisateur clique à un endroit du site, ou survol un élément, etc…​

La syntaxe générale d’un événement JQuery est :

$(<element>).<event>(<function>);

Exemple :

$("body").click(function(){ alert("On a cliquer ?") });

En savoir plus plus sur les événements JQuery : https://api.jquery.com/category/events/

Proposer à l’utilisateur la possibilité de choisir entre les données des 30 derniers jours ou des 12 derniers mois. On pourra utiliser une boite de sélection assocée à l’événement .change(). Faire bon usage des outils de développement pour s’assurer de la bonne gestion de l’événement.

...
<script>
	$("#voiture").change(function(){$("#la_voiture").html($("#voiture").val())})
</script>

...

<select id="voiture">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>

<p id="la_voiture"></p>

Graphique

Pour générer le graphique montrant la concentration en NOx soit pendant les 30 derniers jours, soit pendant les 12 derniers mois suivant le choix de l’utilisateur, on utilisera la bibliothèque http://chartjs.org :

<head>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
</head>

<script>


	new Chart(document.getElementById("line-chart"), {
		  type: 'line',
		  data: {
		    labels: liste_elements_en_absisse,
		    datasets: [{
		        data: liste_elements_en_ordonnee,
		        label: "Nom de la courbe",
		        borderColor: "#3e95cd",
		        fill: false
		      },
		  options: {
		    title: {
		      display: true,
		      text: 'Titre du graphique'
		    }
		  }
		});

</script>

<body>
	...
	<canvas id="line-chart" width="800" height="450"></canvas>
	...
</body>

A faire

Ecrire une fonction qui permet d’afficher un graphique dans un canvas et dont les données à afficher sont celles choisies par l’utilisateur.

<head>
	...
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="tableau.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>

    <script>
        function get_date(_liste) {
        }
        function get_data(_liste) {
        }
        function get_tableau(tableId, _date, _data) {
        }

        function get_chart(_date, _data, label, titre) {
		// Code pour afficher un graphique avec _date en X et _data en Y
        }
        // Code exécuter à l'ouverture de la page :
        $(function () {
            get_tableau("#tableau", get_date(_30jours), get_data(_30jours));

            get_chart(get_date(_30jours), get_data(_30jours),
			"Concentration (µg/m^3) sur les 30 derniers jours",
			"Concentration de NOx à Avignon Mairie")

        });
    </script>
</head>

<body>
	...

	<div id="tableau"></div>

	<div id="graph">
		<canvas id="line-chart" width="800" height="450"></canvas>
	</div>

</body>

Exemple de réalisation

exemple

Conclusion

Ce que l’on a appris :

Le format csv

Un fichier CSV est un fichier texte. Chaque ligne du texte correspond à une ligne du tableau et les virgules (ou les point-virgules) correspondent aux séparations entre les colonnes.

Python dispose d’un module csv qui facilite la lecture des fichiers csv et l’extractions des données qu’ils contiennent.

Les tableaux javascript

Les tableaux javascript peuvent être itérés par l’application de la méthode forEach(). :

	tableau.forEach(function (item) {
        console.log(item);
    })

Manipuler les éléments d’une page web avec JQuery

On accède à un élément d’une page web à l’aide de son identifiant : $("#id_element"). :

Par exemple, obtenir le texte d’un élément d’une page web

<script>la_periode = $(#titre_periode).html()</script>
...
<p id="titre_periode">Période :</p>

Modifier ou renseigner le texte d’un élément d’une page web

<script>la_periode = $(#titre_periode).html("Nouveau texte à afficher")</script>
...
<p id="titre_periode"></p>

De même, on pourra modifier ou renseigner une propriété css d’un élément d’une page web

<script>la_periode = $(#titre_periode).css("color", "red")</script>
...
<p id="titre_periode"></p>

Gérer des événements avec JQuery

Avec JQuery, il est possible d’associer une action à un évènement. Par exemple on pourra executer une action lorsque l’utilisateur clique à un endroit du site, ou survol un élément, etc…​

La syntaxe générale d’un événement JQuery est :

$(<element>).<event>(<function>);

Exemple :

$("body").click(function(){ alert("On a cliquer ?") });

Les principaux événements sont :

Evénement Description

.blur()

Lorsque l’on perd le focus

.change()

Changement de valeur

.click()

Click de la souris

.dblclick()

Double click

.focus()

Lorsque l’on focalise un élément

.hover()

Survol de la souris

.keydown()

Pression sur une touche

.keyup()

Lorsqu’on relache la pression d’une touche

.mousedown()

Lorsque l’on presse sur un bouton de la souris

.mouseup()

Lorsque l’on relache la pression du click

.ready()

Lorsque la page est chargée entièrement

.resize()

Lorsque l’on modifie la taille du navigateur

.scroll()

Scroll de l’élement

.submit()

Envoi du formulaire

En savoir plus plus sur les événements JQuery : https://api.jquery.com/category/events/