Reputation: 190
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>
Upvotes: 2
Views: 2128
Reputation: 658
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
Upvotes: 3