Initialize several charts in a loop
On my page, I want to show multiple charts that are loaded via ajax. So I get html that is something like this:
<h4>Chart 1</h4>
<canvas data-type="bar" data-labels='["Label 1", "Label 2"]' data-data='[10,20]'></canvas>
<h4>Chart 2</h4>
<canvas data-type="pie" data-labels='["Label 3", "Label 4"]' data-data='[30,40]'></canvas>
As you can see, the charts can be of different types and I have an object holding all the configuration of charts for each type
const chartConfigs = {
bar: {
type: 'bar',
data: {
labels: [],
datasets: [{
data: [],
pointRadius: 2,
backgroundColor: '',
maxBarThickness: 50
}]
},
options: {
legend: {
display: false
},
scales: barScalesOptions
}
},
pie: {
type: 'pie',
data: {
labels: [],
datasets: [{
data: [],
backgroundColor: ['#84c267', '#c9556a'],
borderWidth: 0
}],
},
options: {
legend: {
labels: {
fontColor: '#CCC',
}
},
aspectRatio: 1,
responsive: true
}
}
}
And I loop through all the canvases to initialize them.
container.querySelectorAll('canvas').forEach(canv => {
const chartOptions = chartConfigs[canv.dataset.type];
chartOptions.data.datasets[0].data = JSON.parse(canv.dataset.data);
if(canv.dataset.labels != undefined)
chartOptions.data.labels = JSON.parse(canv.dataset.labels);
console.log(JSON.stringify(chartOptions));
new Chart(canv, chartOptions);
});
But the problem is that all the charts are rendered the same - Labels and Data. I'm assuming its because chartOption开发者_如何学运维s
is a copy by reference. Its a pretty difficult task to do a deep copy as this is a nested object and I also need functions in them. But even if I somehow did this task, it would be a memory management nightmare as there are many charts on the page.
If you have done something like this before, please share a better way of doing this.
A quick fix is just too clone the needed part of the object, with the handy function(s) JSON.parse
and JSON.stringify
, it is a quick & dirty solution, but makes sure it breaks al references.
container.querySelectorAll('canvas').forEach(canv => {
const chartOptions = JSON.parse(JSON.stringify(chartConfigs[canv.dataset.type]));
chartOptions.data.datasets[0].data = JSON.parse(canv.dataset.data);
if(canv.dataset.labels != undefined){
chartOptions.data.labels = JSON.parse(canv.dataset.labels);
console.log(JSON.stringify(chartOptions));
new Chart(canv, chartOptions);
});
Since I can't see any functions in the object
chartOptions
the serializing and deserializing should be no problem.
精彩评论