Les langages du web > Le Javascript > Charting Libraries

Chart.js

version 2.9.x

Présentation

Exemples officiels (en anglais)
Ne pas oublier de cliquer dans le menu de gauche, pour obtenir différents exemples dans différents types de graphiques.

Ici, le type line
Ne pas oublier de cliquer sur les 5 boutons sous chaque graphique ...

Video

Citations

Chart.js est la deuxième bibliothèque de graphiques JS la plus populaire ... après D3.js.

Chart.js est une bibliothèque JavaScript open source gratuite pour la visualisation [graphique] de données, créée par le développeur web Nick Downie en 2013.

Dix ans plus tard (en 2023) : Chart.js is a good option for designers who need a simple, customizable, interactive visualization option.

It is one of the simplest visualization libraries for JavaScript, and comes with the many built-in chart types

Il est difficile de désigner le meilleur outil, car cela dépend des compétences de l'utilisateur, des fonctionnalités qu'il recherche, des versions de l'outil, ...

Installation

Dans ce micro-cours, les versions utilisées sont 2.9.x. car il suffit d'ajouter dans le <head> du fichier HTML, une seule ligne :
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>

L'inconvénient d'un CDN est qu'il faut une connexion internet.

Ou, si cette version de la librairie a été téléchargée (435 Ko) dans un dossier :
<script src="2.9.4/Chart.js"></script> (par exemple)

Ou mieux, si la version 2.9.3 compressée de la librairie a été téléchargée (169 Ko) dans un dossier :
<script src="chart.js"></script> (par exemple)

Source des versions compressées

Avec <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/Chart.js"></script>, cela ne fonctionne pas !

Documentation officielle.

Choisir la documentation en fonction de la version utilisée ... version 2.9.4
NB : La documentation officielle 2.9.3 n'existe pas (mais bien le code compressé de la librairie 2.9.3)

Ce micro-cours (une page) complète la page w3schools.com/graphics/plot_chartjs

Version 2.9.x

Après cette version (version 3.x.x ou plus), la version JS utilisée est 2015 ou plus ...
=> import ...

Code HTML

Exemple de code HTML (tensionAnalys.htm)

<!DOCTYPE html>
<html lang="fr-BE" xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr-BE">
  <head>
    ...
    <script src="chart.js"></script>
  ...
  </head>
  <body>
  ...
        <!-- Ici, le graphique prendra toute la page -->
        <canvas id="myChart">
          <p>Graphique lié à la tension systolique et diastolique</p>
        </canvas>
  ...

    <script src="tensionData.js"></script>
    <script src="tensionAnalys.js"></script>
  </body>
</html>
  1. La version est appelée dans le head.
  2. Un élément canvas est placé dans le body.

    Par défaut, le graphique prendra toute la taille du conteneur de canvas (ici, body), quelque soit les indications données via les attributs de cette balise. Mais, on peut placer canvas dans une div ...

  3. Le fichier JS contenant les données est appelé.
  4. Puis, est appelé le fichier JS contenant le code traitant ces données.
    L'ordre des appels des fichiers JS est important.

Données

Exemple de données (tensionData.js, où data est un objet)

Par commodité, logique et sécurité, les données sont situées dans un fichier séparé du fichier qui traite de l'affichage des données.

/* jour,heure,systolique,diastolique,pouls,température,note */
var data = {lignes:[

{j:"2023-10-08",h:"06:41",s:141,d:81,p:54,t:17.4,n:""},
{j:"2023-10-07",h:"06:24",s:123,d:78,p:51,t:17.4,n:""},
...
{j:"2023-10-01",h:"07:59",s:130,d:67,p:61,t:21.1,n:""},
{j:"2023-10-01",h:"05:33",s:147,d:85,p:54,t:21.1,n:""} 

]};

Pas de virgule après le dernier élément du tableau.

data est une variable objet (clé/valeur)

La clé est unique et s'appelle, ici, "lignes".
Sa valeur est un tableau d'objets (clés/valeurs).

Chacun des objets de ce tableau correspond à un enregistrement.

Code JS

Exemple de code JS (tensionAnalys.js), permettant de filtrer les lignes.

function myCtrl(){ /* appelée par un bouton */

 /* La variable-objet "data" (déclarée et initialisée dans "tensionData.js") n'est lue qu'une fois */
  let x = data.lignes; /* x = tableau d'objets (de lignes)
  => x[i] représente une ligne (= une prise de tensions) */

  tabCalculs=[] /* tableau des lignes filtrées */
  for (let i = 0; i < x.length; i++) { /* réduit le nombre de lignes */
    ...
  }

  ...

  drawChart(tabCalculs)

}


function drawChart(x) { /* x = tableau des données, réduit à certaines lignes */

  /* ordre des lignes inversé et date réduite à JJ */
  var xValues = []; var yValues1 = []; var yValues2 = []
  for (var i = x.length-1; i > -1 ; i--) {
    xValues.push(x[i]["j"].substr(8));
    yValues1.push(x[i]["s"]);
    yValues2.push(x[i]["d"]);
  }

  new Chart("myChart", {
    type: "line",
    data: {
      labels: xValues,
      datasets: [{
        data: yValues1,
        borderColor: "red",
        fill: false
      },{
        data: yValues2,
        borderColor: "blue",
        fill: false
      }]
    },
    options: {
      legend: {display: false}
    }
  });

}

Exemple

Toutefois, s'il n'est pas nécessaire de filtrer, les codes JS peuvent être plus courts.

Exemple de données (tensionData2.js, où lignes est un tableau)

/* jour,heure,systolique,diastolique,pouls,température,note */
var lignes = [

{j:"2023-10-08",h:"06:41",s:141,d:81,p:54,t:17.4,n:""},
{j:"2023-10-07",h:"06:24",s:123,d:78,p:51,t:17.4,n:""},
...
{j:"2023-10-01",h:"07:59",s:130,d:67,p:61,t:21.1,n:""},
{j:"2023-10-01",h:"05:33",s:147,d:85,p:54,t:21.1,n:""} 

];

Exemple de code JS (tensionAnalys2.js), sans filtrage des lignes.

function drawChart(x) {

  var xValues = []; var yValues1 = []; var yValues2 = []

  /* ordre des lignes inversé et date réduite à JJ */
  for (var i = x.length-1; i > -1 ; i--) {
    xValues.push(x[i]["j"].substr(8));
    yValues1.push(x[i]["s"]);
    yValues2.push(x[i]["d"]);
  }

  new Chart("myChart", {
    type: "line",
    data: {
      labels: xValues,
      datasets: [{
        data: yValues1,
        borderColor: "red",
        fill: false
      },{
        data: yValues2,
        borderColor: "blue",
        fill: false
      }]
    },
    options: {
      legend: {display: false}
    }
  });

}

drawChart(lignes);

Exemple 2

Chart(id,{...})

  new Chart("myChart", {
    type: "line",
    data: {...},
    options: {...}
  });

Le premier paramètre du constructeur de la class "Chart" est une référence à l'élément HTML canvas. Cette référence est la valeur de l'attribut id de cette balise.

Le second paramètre est un objet, {...}, dont le contenu est un ensemble de clé/valeur. Les deux premières clés sont obligatoires.

Rappel : Dans un objet {}, l'ordre des clés est sans importance.

type:

La valeur de cette clé est une string : "line" | "bar" | "horizontalBar" | "doughnut" | "pie" ...

Documentation

Avec le type pie, doughnut, ...il ne peut avoir qu'une seule série de données (y)

data:

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur.

Documentation

labels:

La valeur de cette clé (obligatoire *) est un tableau (ou une variable-tableau), dont les valeurs s'afficheront sur l'axe des X.

(*) lorsque le data du datasets n'est pas un tableau d'objets {x,y}.

datasets:

La valeur de cette clé est un tableau, contenant un ou plusieurs objets {}, où un objet correspond à une ligne (dans le cas d'un chart de type "line").

Plusieurs objets => plusieurs lignes (si type:"line")

data:

Seule cette clé/valeur est obligatoire. La valeur de cette clé est un tableau (ou une variable tableau) relatif à l'ensemble des valeurs Y correspondant à chaque valeur de X (de labels).

Valeurs par défaut de toutes les autres clés

Ci-dessous quelques clés courantes, lorsque le type de chart est "line" :

label:

Indique le nom attribué à cette ligne. La valeur de cette clé (facultative) est une string (ou une variable contenant une string)

Ce nom ne s'affichera en haut du tableau que si :

options: {
  legend: {display: true}
}

Cliquer sur un label permet d'afficher ou non les données correspondantes.

borderColor:

Indique la couleur du trait. La valeur de cette clé (facultative) est une string (ou une variable contenant une string) dont la valeur est : une fonction rgb() ou rgba())

fill:

Indique s'il existe une couleur sous la courbe (ou pas). La valeur de cette clé (facultative) est un booléen (ou une variable booléenne) : true (= valeur par défaut) | false.

backgroundColor:

Indiquant la couleur de fond des points. La valeur de cette clé (facultative) est une string (ou une variable contenant une string) ou un tableau (ou une variable-tableau) de strings, auquel cas le nombre de couleurs doit être égal au nombre de valeurs sur l'axe des X.

Si le type de chart est "bar",

La valeur de cette couleur est donnée comme dans borderColor:.
Par défaut, la valeur est "rgba(0, 0, 0, 0.1)".

borderWidth:

Indique l'épaisseur du trait. La valeur de cette clé (facultative) est un nombre entier (ou une variable contenant un nombre entier).

Par défaut, la valeur vaut 3

tension:

Indique la tension dans la courbe de Bézier. La valeur de cette clé (facultative) est un nombre positif inférieur à 1 (ou une variable contenant un nombre entier).

Par défaut, la valeur vaut 0.4

Avec la valeur 0, la ligne sera brisée.

borderDash:

Indique la forme de discontinuité du trait. La valeur de cette clé (facultative) est un tableau (ou une variable-tableau)

La valeur de ce tableau est expliqué sur MDN.

Par exemple, [10,10]

Outre la "Line Configuration" (partiellement expliquée ci-dessus), il existe une "Rectangle Configuration" pour les charts de type "bar" et une "Arc Configuration" pour les charts de type "pie", "doughnut" ou "polar area"

options:

Les options varient en fonction du type de chart.

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur qui permet de personnaliser le graphique.

title:

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur relatif au titre du graphique.

Documentation. Les deux clés les plus courantes sont :

display:

Indique s'il existe un titre (ou pas). La valeur de cette clé (facultative) est un booléen (ou une variable booléenne) : true (= valeur par défaut) | false.

text:

Indique le titre du graphique. La valeur de cette clé (facultative) est une string (ou une variable contenant une string)

legend:

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur relatif aux titres des séries de données (lignes, lorsque le type est "line").

Documentation. Les deux clés les plus courantes sont :

labels:

Indique les titres de séries de données. La valeur de cette clé (facultative) est une string (ou une variable contenant une string)

display:

Indique s'il existe des titre de séries de données (ou pas). La valeur de cette clé (facultative) est un booléen (ou une variable booléenne) : true (= valeur par défaut) | false.

Si true, alors on pourra cliquer sur ce titre pour faire apparaître ou disparaître les données correspondantes.

fontColor:

Indique la couleur d'un titre de série de données. La valeur de cette clé (facultative) est une string (ou une variable contenant une string)

animation:

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur relatif à l'animation du graphique.

Documentation. La clé la plus courante est :

duration:

Indique la durée. La valeur de cette clé (facultative) est un nombre entier (ou une variable contenant un nombre entier).

Par défaut, la valeur vaut 1000 millisecondes

Si la valeur vaut 0 => pas d'animation.

elements:

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur relatif à l'élément du graphique.

Documentation. La clé la plus courante est :

point:

La valeur de cette clé (facultative) est un objet, {...}, dont le contenu est un ensemble de clé/valeur relatif aux points du graphique.

Documentation. Les deux clés les plus courantes sont :

radius:

Indique la grosseur du point en pixels. La valeur de cette clé (facultative) est un nombre entier (ou une variable contenant un nombre entier).

pointStyle:

La valeur indiqué est une string ou une image

La string peut valoir : 'circle' | 'cross' | 'crossRot' | 'dash' | 'line' | 'rect' | 'rectRounded' | 'rectRot' | 'star' | 'triangle'

tooltips:

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur relatif aux messages qui s'affichent au survol de la souris sur un point.

Documentation. La clé la plus courante est :

enabled:

Indique s'il existe des messages (ou pas). La valeur de cette clé (facultative) est un booléen (ou une variable booléenne) : true (= valeur par défaut) | false.

layout:

La valeur de cette clé est un objet, {...}, dont le contenu est un ensemble de clé/valeur relatif aux cadrage du graphique dans le canvas. Peu usité.

Documentation. La seule clé est :

padding:

La valeur de cette clé est :

plugins:

Documentation

Données calculées

Dessin d'une droite

const a=2, b=7; /* Les coefficients de la droite : y = ax + b */
const xValues = [-10,10]; /* Les 2 bornes sur l'axe des X */

const yValues = [];
yValues.push(a*xValues[0]+b);
yValues.push(a*xValues[1]+b);

new Chart("myChart", {
  type: "line",
  data: {
    labels: xValues,
    datasets: [{
      data: yValues,
      borderColor: "red",
      fill: false,
      tension:0
    }]
  },
  options: {
    legend: {display: false}
  }
});

Afficher une droite, Afficher une droite avec de nombreux points sur la droite

Afficher une droite peut être fait en SVG. Toutefois, en remplissant un dataset par calculs, on peut alors ajouter une ligne droite au graphique.

Dessin d'une sinusoïdale

const x1=-Math.PI, x2=2*Math.PI, nbPts=36; /* Les 2 bornes et le nombre de points */

const step=(x2-x1)/nbPts;
const xValues = []; const yValues = [];
for (let x = x1; x <= x2 ; x +=step) {
  xValues.push(x); yValues.push(Math.sin(x)); /* L'équation */
}

new Chart("sinus", {
  type: "line",
  data: {
    labels: xValues,
    datasets: [{
      data: yValues,
      borderColor: "red",
      fill: false
    }]
  },
  options: {
    legend: {display: false}
  }
});

Afficher une sinusoïdale

JSON

Les données peuvent être au format JSON : (tensionData.json)

/* jour,heure,systolique,diastolique,pouls,température,note */
var data = {lignes:[

{"j":"2023-10-08","h":"06:41","s":141,"d":81,"p":54,"t":17.4,"n":"75.5 kg"},
{"j":"2023-10-07","h":"06:24","s":123,"d":78,"p":51,"t":17.4,"n":"*-16"},
...
{"j":"2023-10-01","h":"07:59","s":130,"d":67,"p":61,"t":21.1,"n":""},
{"j":"2023-10-01","h":"05:33","s":147,"d":85,"p":54,"t":21.1,"n":""}

]};

Via PHP-MySQL

Via PHP, on peut récupérer les données d'une base de données (telle que MySQL) et les renvoyer au format JSON pour ensuite afficher le graphique.

5 fichiers sont alors mis en œuvre :

  1. un fichier HTML qui appelle 2 librairies JS et un fichier JS
  2. La librairie chart.js pour afficher le graphique
  3. La librairie w3.js contenant la fonction getHttpObject() dont le premier paramètre est le fichier PHP qui lui envoye les données.
  4. Le fichier PHP qui requiert une connexion avant d'envoyer les données.
  5. Le fichier PHP qui se connecte à la base de données.

Code HTML : (ici, tensionsFromPHP.htm)

<!DOCTYPE html>
<html lang="fr-BE" xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr-BE">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="robots" content="noindex, nofollow" />
    <script src="chart.js"></script>
    <script src="w3P.js"></script>
    <title>
      Tensions
    </title>
  </head>
  <body>
    <canvas id="myChart">
      <p>
        Graphique lié à la tension systolique et diastolique
      </p>
    </canvas>
    <script src="tensionsFromPHP.js"></script>
  </body>
</html>

La librairie chart.js (version 2.9.3, 169 Ko) est appelée.

La librairie w3P.js (13 Ko) est appelée.

Code JS : (ici, tensionsFromPHP.js)

function drawChart(x) {

  var xValues = []; var yValues1 = []; var yValues2 = []
  for (let i = 0; i < x.length; i++) {
    xValues.push(x[i]["j"].substr(8));
    yValues1.push(x[i]["s"]);
    yValues2.push(x[i]["d"]);
  }

  new Chart("myChart", {
    type: "line",
    data: {
      labels: xValues,
      datasets: [{
        data: yValues1,
        borderColor: "red",
        fill: false
      },{
        data: yValues2,
        borderColor: "blue",
        fill: false
      }]
    },
    options: {
      legend: {display: false}
    }
  });

}

w3.getHttpObject("tensions.php",drawChart);

Code PHP qui envoie les données : (ici, tensions.php)

<?php
header("Content-Type: application/json; charset=UTF-8");
require("connexion.php");
$sql = "SELECT date AS j, systolique AS s, diastolique AS d FROM tensions";
$rep=$bdd->query($sql);
if ($rep===FALSE) sortir(1,"");
$data=$rep->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($data);
?>

Code PHP : (ici, connexion.php)

<?php
$typDB="mysql";
$host="localhost";
$dbname="toto";
$root="root";
$password=""; /* ou le mot de passe de root donné lors de l'installation de MySQL */
$cnx=$typDB.":host=".$host.";dbname=".$dbname;
try { $bdd = new PDO($cnx, $root, $password); }
catch (Exception $e) { die('Erreur : ' . $e->getMessage()); }
$bdd->exec('SET NAMES utf8');
?>

Les 5 fichiers sont encodés en UTF-8 et sont situés sur un serveur (Apache) qui peut communiquer avec un gestionnaire de base de données (MySQL).

Fichier SQL pour créer la table avec les données.