Tracer plusieurs courbes avec chart.js

Bonsoir à toutes et à tous,

En espérant que certains d'entre vous aient déjà eu ce problème.

Dans la mémoire de mon ESP32, j'ai un fichier csv ayant trois colonnes. La première est l'index, la deuxième et la troisième représentent les valeurs de deux courbes liées aux index.

Je souhaite créer avec chart.js un graphique sur lequel je peux tracer les deux courbes relatives aux deuxième et troisième colonnes du fichier csv.

J'ai déjà fait le tracé d'une courbe, mais je n'arrive pas à trouver d'exemple montrant comment faire pour tracer les deux courbes sur le même graphique. Voilà ce que j'ai pour une courbe :

    <body>
      <h1 style="text-align: center;">ESP32 Routeur photovoltaïque</h1>
      <canvas id="myChart" width="800" height="300"></canvas>
      
      <script>
        const ctx = document.getElementById('myChart').getContext('2d');
        const chart = new Chart(ctx, {
          type: 'line',
          data: {
            labels: [],
            datasets: [{
              label: 'Forme donde',
              data: [],
              borderColor: 'rgb(75, 192, 192)',
              tension: 0.1
            }]
          }
        });

        function updateChart() {
          fetch('/data')
            .then(response => response.text())
            .then(data => {
              const rows = data.split('\n');
              const labels = [];
              const values = [];
              
              rows.forEach(row => {
                const [label, value] = row.split(',');
                labels.push(label);
                values.push(parseFloat(value));
              });
              
              chart.data.labels = labels;
              chart.data.datasets[0].data = values;
              chart.update();
            });
        }
        setInterval(updateChart, 5000); // Mise à jour toutes les 5 secondes
      </script>
    </body>


...

  server.on("/data", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/Onde2.csv", "text/csv");
  });

Et le début de mon fichier cvs (il comporte 72 lignes :

1,-84.05,42.025
2,-65.6,32.8
3,-36.9,18.45
4,-8.2,4.1
5,5.12,-2.56
6,29.72,-14.86
7,53.3,-26.65
8,79.95,-39.975
9,103.52,-51.76
10,126.07,-63.035
11,149.65,-74.825
12,168.1,-84.05
13,192.7,-96.35
...

Merci de votre aide.

Pierre.

Si j'en crois les exemples, il faut déclarer plusieurs datasets (voir l'onglet setup de l'exemple)

Merci " fdufnews" pour cette info.

C'est ce que j'avais compris et que j'avais appliqué : sans résultat autre qu'un deuxième titre de courbe

            datasets: [{
              label: 'Forme d\'onde 1',
              data: [],
              borderColor: 'rgb(75, 192, 192)',
              tension: 0.5 // Filtrage du signal ; doit être compris entre 0 (pas de filtrage) et 1 (filtrage max)
            },{
              label: 'Forme d\'onde 2',
              data: [],
              borderColor: 'rgb(192, 192, 75)',
              tension: 0.1
            }]

Pour autant, il doit y avoir autre chose à faire. Pourtant, dans l'exemple que tu me donnes en lien, les deux datasets sont aussi identiques :

  datasets: [
    {
      label: 'Dataset 1',
      data: Utils.numbers(NUMBER_CFG),
      borderColor: Utils.CHART_COLORS.red,
      backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
    },
    {
      label: 'Dataset 2',
      data: Utils.numbers(NUMBER_CFG),
      borderColor: Utils.CHART_COLORS.blue,
      backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
    }
  ]

Je ne vois pas de quel "chapeau" viennent les données. Aussi bien dans mon application que dans l'exemple donné.

Cordialement.

Pierre.

Il me semble que la solution vient de ce bout de code dans lequel j'ai mis des commentaires qui sont peut-être faux ! :

              rows.forEach(row => { // pour chaque ligne du fichier ... 
                const [label, value] = row.split(','); // le label et les valeurs sont séparés par de ','
                labels.push(label); // met à jour les labels
                values.push(parseFloat(value)); // met à jour les valeurs
              });
              
              chart.data.labels = labels; // Applique les labels
              chart.data.datasets[0].data = values; // Applique les valeurs
              chart.update(); // Met à jour le graphique
            });

En ajoutant une ligne chart.data.datasets[1].data = values; après chart.data.datasets[0].data = values;, je trace bien une deuxième courbe, mais elle reprend les mêmes valeurs que la première.

Je ne vois pas bien comment, dans ce code faire en sorte que chaque courbe prenne les bonnes valeurs de mon fichier.

Cordialement.

Pierre.

Regardes l'onglet actions où il y a l'ajout de datasets ou l'ajout de data aux datasets existants.

C'est ce que j'ai fait, mais la ligne qui me semble importante dans l'ajout d'un datasets : data: Utils.numbers({count: data.labels.length, min: -100, max: 100}), ne me renseigne guère sur ce qu'il faut faire par rapport à l'exploitation de mon fichier csv.

Cordialement.

Pierre.

ce sont ces lignes qui ajoutent les données dans les datasets

        for (let index = 0; index < data.datasets.length; ++index) {
          data.datasets[index].data.push(Utils.rand(-100, 100));
        }

ici c'est un rand puisque les données sont générées de manière aléatoire. Dans ton cas il faut passer en argument à push la donnée extraite de ton fichier.

Je pense avoir compris ce que tu veux dire. Pour autant, je ne vois pas comment placer cela dans mon code. J'ai écrit :

              let indx = 0;
              rows.forEach(row => {
                const [label, value] = row.split(',');
                labels.push(label);
                values.push(parseFloat(value));
                chart.data.datasets[indx].data = values;
                ++indx;
              });

du coup, plus rien ne s'affiche.

Est-ce que cette instruction const [label, value] = row.split(',');, appliquer à une ligne du fichier csv : n, v1,v2 fait bien qu'à la première passe, label = n et value = v1 et qu'à la deuxième passe, label = n et value = v2 ?

Est-ce qu'en ayant déclaré cela :

            datasets: [{
              label: 'Forme d\'onde 1',
              data: [],
              borderColor: 'rgb(75, 192, 192)',
              tension: 0.1
            },{
              label: 'Forme d\'onde 2',
              data: [],
              borderColor: 'rgb(192, 192, 75)',
              tension: 0.1
            }]

cela veut-il bien dire qu'il y a deux datasets?

Est-ce que le format du fichier csv tel que décrit précédemment est bon ?

Désolé, je ne sais pas comment faire.

Cordialement.

Pierre

Oui auxquels on accède par chart.data.datasets[0] et chart.data.datasets[1]

Bon, je pense avoir trouvé. En tous cas, mes deux courbes s'affichent. Le code utilisé est le suivant :

        function updateChart() {
          fetch('/data')
            .then(response => response.text())
            .then(data => {
              const rows = data.split('\n');
              const labels = [];
              const values0 = [];
              const values1 = [];
              rows.forEach(row => {
                const [label, value0, value1] = row.split(','); // J'ai supposé que de placer les deux valeurs l'une derrière l'autre fonctionnerait ! Apparemment oui.
                labels.push(label);
                values0.push(parseFloat(value0));
                values1.push(parseFloat(value1));
              });             
              chart.data.labels = labels;
              chart.data.datasets[0].data = values0;
              chart.data.datasets[1].data = values1;
              chart.update();
            });
        }

Cordialement.

Pierre.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.