在我的页面上,我想显示通过 AJAX 加载的多个图表。所以我得到了类似如下的html:
<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>
正如您所看到的,图表可以是不同的类型,我有一个对象保存每种类型的图表的所有配置
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
}
}
}
然后我循环遍历所有的画布来初始化它们。
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);
});
但问题是所有的图表都呈现相同的-标签和数据。我假设这是因为chartOptions
是一个通过引用复制的。这是一个非常困难的任务来做一个深复制,因为这是一个嵌套的对象,我还需要在其中的函数。但即使我以某种方式做了这个任务,这将是一个内存管理噩梦,因为有很多图表在页面上。
如果你以前做过类似的事情,请分享一个更好的方法。
1条答案
按热度按时间rjzwgtxy1#
一个 * 快速的解决方案 * 是克隆对象的所需部分,使用方便的函数
JSON.parse
和JSON.stringify
,这很容易,并确保它打破了所有的引用(如mentioned on mdn)。因为我看不到对象
chartOptions
中的任何函数,所以序列化和反序列化应该没有问题吧?更新,对于具有函数的对象 (针对您的特定情况):
我看到两个简单的选择,
1.只从基对象中提取函数并传递当前对象
1.或者如果你不想改变
chartConfigs
对象,就使用prototype
函数call
(link to documentation)。换句话说,把函数调用改为:testFunction
是一个函数,具有2个参数(id
,value
))*不是很性感,但是一个快速的解决方案,将需要很少的代码修改.