简体   繁体   中英

Multiple charts with different data using chart.js

I have 3 charts on the HTML page, I use class instead of id to avoid repeating code, I need help to change the data of one of them, I tried several ways but the issue still exists, This is the code

 const charts = document.getElementsByClassName('doughnut-chart') for (chart of charts) { const ctx = chart.getContext('2d'); const config = { type: 'doughnut', data: { datasets: [{ data: [50, 60, 20, 33], backgroundColor: ["#1CCFEC", "#A9EDF8", "#BDECDC", "#00D295"], label: 'Energy usage' }], labels: ["VISA", "AMEX", "MC", "DEBIT"] }, options: { responsive: true, cutoutPercentage: 85, legend: { display: false }, legendCallback: function (chart) { // Return the HTML string here. console.log(chart.data.datasets); const text = []; text.push(`<ul class="${chart.id}-legend flex-center-vh flex-space-evenly">`); for (let i = 0; i < chart.data.datasets[0].data.length; i++) { text.push(`<li class="flex-center-vh"><span class="item-bg" id="legend-${i}-item" style="background-color:${chart.data.datasets[0].backgroundColor[i]}">`); text.push(`</span>`); if (chart.data.labels[i]) { text.push(`<span class="legent-item text-gray fw600 fs10">${chart.data.labels[i]}</span>`); } text.push(`</li>`); } text.push(`</ul>`); return text.join(""); }, } }; const legendContainer = document.querySelectorAll('.doughnut-legend') legendContainer.forEach(function (thisLegend) { thisLegend.innerHTML = window.chartInstance.generateLegend(); }) var chartInstance = new Chart(ctx, config); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.min.js"></script> <div class="chart-container"> <canvas id="chart1" class="doughnut-chart"></canvas> <div class="doughnut-legend"></div> </div> <div class="chart-container"> <canvas id="chart2" class="doughnut-chart"></canvas> <div class="doughnut-legend"></div> </div> <div class="chart-container"> <canvas id="chart3" class="doughnut-chart"></canvas> <div class="doughnut-legend"></div> </div>

The window.chartInstance is not set and moreover, my understanding of the logic is to expect three different instances in order to call generateLegend() for each of them.

UPDATED to show how to change the data of one of the charts: Moved legendContainer outside of the charts loop; Now using an array of chart instance as suggested by K Scandrett.

Here is a proposal (excerpt). Mind the instanciation of the charts inside the primary loop and the generation of the legends outside of the primary loop.

let allCharts = [];

const charts = document.getElementsByClassName("doughnut-chart");
for (chart of charts) {
  const ctx = chart.getContext("2d");
  const config = {
    // ...
  };

  var chartInstance = new Chart(ctx, config);
  allCharts.push(chartInstance);
}

let legendContainer = document.querySelectorAll(".doughnut-legend");
legendContainer.forEach(function (thisLegend, i) {
  thisLegend.innerHTML = allCharts[i].generateLegend();
});

// update data
const chartToModify = allCharts[1]
chartToModify.data.datasets[0].data.pop();
chartToModify.data.datasets[0].data.pop();
chartToModify.data.labels.pop();
chartToModify.data.labels.pop();
chartToModify.update();

// update legends
legendContainer = document.querySelectorAll(".doughnut-legend");
legendContainer.forEach(function (thisLegend, i) {
  thisLegend.innerHTML = allCharts[i].generateLegend();
});

Changing the data of one of the charts is documented at https://www.chartjs.org/docs/3.3.2/developers/updates.html . Mind the call to update() .

Complete code here https://codepen.io/beezital/pen/yLzRqXz

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM