web-dev-qa-db-fra.com

Graphique à barres Chartjs montrant les anciennes données en vol stationnaire

J'ai un graphique à barres créé à l'aide de chart.js. Tout fonctionne correctement lors du chargement de la page, mais lorsque je modifie la période à l'aide d'un sélecteur de distance, un problème apparaît. Les nouvelles données sont importées, mais lorsque je survole celles-ci, les anciennes données sont affichées. Je suis nouveau sur javascript et j'espère obtenir de l'aide. Il semble que j'ai besoin d'incorporer .destroy (); en quelque sorte, mais je ne sais pas comment. Un extrait de mon code est ci-dessous:

function loadFTPRChart(startdate, enddate){
var BCData = {
labels: [],
datasets: [
 {
  label: "Pass %",
  backgroundColor: "#536A7F",
  data: [],
  stack: 1
},
{
  label: "Fail %",
  backgroundColor: "#e6e6e6",
  data: [],
  stack: 1
},
{
  label: "Auto %",
  backgroundColor: "#286090",
  data: [],
  stack: 2
},
{
  label: "Manual %",
  backgroundColor: "#f0f0f0",
  data: [],
  stack: 2
}
 ]
};
  $.getJSON( "content/FTPR_AM_Graph_ajax.php", {
    startdate: startdate,
    enddate: enddate,
    location: "M"
})
.done(function( data ) {
    console.log("data", data);
    $.each( data.aaData, function( key, val ) {
      if(val == ""){return true}
      BCData.labels.Push("Coater " + val[0]);
      BCData.datasets[0].data.Push(parseFloat(val[2]));
      BCData.datasets[1].data.Push(parseFloat(100-val[2]));
      BCData.datasets[2].data.Push(parseFloat(val[1]));
      BCData.datasets[3].data.Push(parseFloat(100-val[1]));
    });

    var option = {   
     responsive:true,
};
console.log("BCData", BCData);


//console.log("PrevData", data);
var ctx = document.getElementById("mybarChart2").getContext("2d");
new Chart(ctx, {
  type: 'groupableBar',
  data: BCData,
  options: {
    scales: {
      yAxes: [{
        ticks: {
          max: 100,
        },
        stacked: true,
      }]
    }
  }
});
});

}


loadFTPRChart($('#reportrange').data().daterangepicker.startDate.format('MM/DD/YYYY'), $('#reportrange').data().daterangepicker.endDate.format('MM/DD/YYYY'));

Quel est le meilleur moyen de détruire les données d'origine afin que, lorsque je change de plage de dates et que je survole le nouveau graphique, les anciennes données ne clignotent plus?

Merci

12
Djones12

Avec l'approche que vous adoptez (par exemple, en créant un nouvel objet Graphique chaque fois que la plage de dates change), vous devez d'abord détruire le graphique précédent, puis en créer un nouveau.

Vous pouvez utiliser la méthode .destroy() prototype pour le faire. Voici exactement ce que dit l'API.

Utilisez cette option pour détruire toutes les instances de graphique créées. Cette volonté nettoie toutes les références stockées dans l'objet graphique dans Chart.js, avec tous les écouteurs d'événements associés attachés par Chart.js. Ce doit être appelé avant que la toile ne soit réutilisée pour un nouveau graphique.

Par conséquent, votre code ressemblerait à quelque chose comme ceci (notez que nous détruisons et recréons).

// define a variable to store the chart instance (this must be outside of your function)
var myChart;

function loadFTPRChart(startdate, enddate) {
  var BCData = {
    labels: [],
    datasets: [{
      label: "Pass %",
      backgroundColor: "#536A7F",
      data: [],
      stack: 1
    }, {
      label: "Fail %",
      backgroundColor: "#e6e6e6",
      data: [],
      stack: 1
    }, {
      label: "Auto %",
      backgroundColor: "#286090",
      data: [],
      stack: 2
    }, {
      label: "Manual %",
      backgroundColor: "#f0f0f0",
      data: [],
      stack: 2
    }]
  };

  $.getJSON("content/FTPR_AM_Graph_ajax.php", {
      startdate: startdate,
      enddate: enddate,
      location: "M"
    })
    .done(function(data) {
      console.log("data", data);
      $.each(data.aaData, function(key, val) {
        if (val == "") {
          return true
        }
        BCData.labels.Push("Coater " + val[0]);
        BCData.datasets[0].data.Push(parseFloat(val[2]));
        BCData.datasets[1].data.Push(parseFloat(100 - val[2]));
        BCData.datasets[2].data.Push(parseFloat(val[1]));
        BCData.datasets[3].data.Push(parseFloat(100 - val[1]));
      });

      var option = {
        responsive: true,
      };
      console.log("BCData", BCData);

      // if the chart is not undefined (e.g. it has been created)
      // then destory the old one so we can create a new one later
      if (myChart) {
        myChart.destroy();
      }

      var ctx = document.getElementById("mybarChart2").getContext("2d");
      myChart = new Chart(ctx, {
        type: 'groupableBar',
        data: BCData,
        options: {
          scales: {
            yAxes: [{
              ticks: {
                max: 100,
              },
              stacked: true,
            }]
          }
        }
      });
    });
}

Cela dit, il est coûteux de détruire/créer encore et encore et ce n'est même pas nécessaire. Il existe une autre méthode prototype appelée .update() que vous pouvez utiliser pour restituer le graphique si vous avez modifié ses données sous-jacentes ou ses objets libellés.

Voici un jsfiddle montrant un exemple de modification des données et des étiquettes sous-jacentes, puis du rendu du graphique. Je vous recommande vivement de prendre cette approche à la place.

Voici à quoi ressemblerait votre code en adoptant cette meilleure approche.

// define a variable to store the chart instance (this must be outside of your function)
var myChart;

function loadFTPRChart(startdate, enddate) {
  var BCData = {
    labels: [],
    datasets: [{
      label: "Pass %",
      backgroundColor: "#536A7F",
      data: [],
      stack: 1
    }, {
      label: "Fail %",
      backgroundColor: "#e6e6e6",
      data: [],
      stack: 1
    }, {
      label: "Auto %",
      backgroundColor: "#286090",
      data: [],
      stack: 2
    }, {
      label: "Manual %",
      backgroundColor: "#f0f0f0",
      data: [],
      stack: 2
    }]
  };

  $.getJSON("content/FTPR_AM_Graph_ajax.php", {
      startdate: startdate,
      enddate: enddate,
      location: "M"
    })
    .done(function(data) {
      console.log("data", data);
      $.each(data.aaData, function(key, val) {
        if (val == "") {
          return true
        }
        BCData.labels.Push("Coater " + val[0]);
        BCData.datasets[0].data.Push(parseFloat(val[2]));
        BCData.datasets[1].data.Push(parseFloat(100 - val[2]));
        BCData.datasets[2].data.Push(parseFloat(val[1]));
        BCData.datasets[3].data.Push(parseFloat(100 - val[1]));
      });

      var option = {
        responsive: true,
      };
      console.log("BCData", BCData);

      // if the chart is not undefined (e.g. it has been created)
      // then just update the underlying labels and data for each
      // dataset and re-render the chart
      if (myChart) {
        myChart.data.labels = BCData.labels;
        myChart.data.datasets[0].data = BCData.datasets[0].data;
        myChart.data.datasets[1].data = BCData.datasets[1].data;
        myChart.data.datasets[2].data = BCData.datasets[2].data;
        myChart.data.datasets[3].data = BCData.datasets[3].data;
        myChart.update();
      } else {
        // otherwise, this is the first time we are loading so create the chart
        var ctx = document.getElementById("mybarChart2").getContext("2d");
        myChart = new Chart(ctx, {
          type: 'groupableBar',
          data: BCData,
          options: {
            scales: {
              yAxes: [{
                ticks: {
                  max: 100,
                },
                stacked: true,
              }]
            }
          }
        });
      }
    });
}
22
jordanwillis

C'est le truc de chartjs que j'ai trouvé

var ctxLine = document.getElementById("line-chart").getContext("2d");
if(window.bar != undefined) 
window.bar.destroy(); 
window.bar = new Chart(ctxLine, {});

https://therichpost.com/solved-hovering-chartjs-bar-chart-showing-old-data

2
Rodener Dajes

Cela vous aidera...

Vérifiez si MyChart ont déjà des configurations ou non, s'il existe, supprimez-le avec destroy () ; méthode, et lier une nouvelle configuration à la toile.

Exemple de code ..

if (window.MyChart != undefined)
{
    window.MyChart.destroy();
}
window.MyChart = new Chart(ctx, MyChartconfig);
2
Dinesh Chile

Il existe une solution simple pour cela, ce qui peut être fait dans JS lui-même.

disons que votre HTML a quelque chose comme ci-dessous

<div id="chartContainer">
 <canvas id="mybarChart2"></canvas>
</div>

Ensuite, dans votre script, vous pouvez ajouter des lignes de code ci-dessous avant de mettre à jour les données.

document.getElementById("chartContainer").innerHTML = '&nbsp;';
document.getElementById("chartContainer").innerHTML = '<canvas id="mybarChart2"></canvas>';
var ctx = document.getElementById("mybarChart2").getContext("2d");

Cela a résolu mon problème.

1
Rajeshwar

J'ai trouvé le problème et ma solution est de les supprimer du code HTML en premier et avant de charger un nouveau graphique, puis d'ajouter un canevas.

Html

 $('#chart').empty();
    
$('#chart').html('<canvas id="survey_result"  width="400" height="200"></canvas>'); // then load chart.
    
var ctx = document.getElementById("survey_result");
    <div id="chart" class="display>
    </div>

1
Chet Tudtude Aiem

Le code des échantillons fournis par chartjs.org a montré qu’ils ne détruisaient pas () le graphique et ne en créaient pas un nouveau. Au lieu de cela, ils ajoutent () les données existantes du graphique et poussent le nouvel ensemble de données vers le graphique, puis mettent à jour () le graphique.

Ce code provient du site Web chartjs.org qui supprime l'ensemble de données du graphique par POP (). 

    document.getElementById('removeDataset').addEventListener('click', function() {
        horizontalBarChartData.datasets.pop();
        window.myHorizontalBar.update();
    });

Et ce code sert à ajouter le jeu de données au graphique avec Push (): 

    document.getElementById('addDataset').addEventListener('click', function() {
        var colorName = colorNames[horizontalBarChartData.datasets.length % colorNames.length];
        var dsColor = window.chartColors[colorName];
        var newDataset = {
            label: 'Dataset ' + (horizontalBarChartData.datasets.length + 1),
            backgroundColor: color(dsColor).alpha(0.5).rgbString(),
            borderColor: dsColor,
            data: []
        };

        for (var index = 0; index < horizontalBarChartData.labels.length; ++index) {
            newDataset.data.Push(randomScalingFactor());
        }

        horizontalBarChartData.datasets.Push(newDataset);
        window.myHorizontalBar.update();
    });

La dernière étape de ces deux blocs de code consiste à mettre à jour le graphique.

De manière générale, il est nécessaire de supprimer les données que vous souhaitez supprimer du graphique, puis d'envoyer les nouvelles données et enfin de mettre à jour le graphique. Par conséquent, les données précédentes ne seront pas affichées lors du survol. 

0
Reza