Rickshaw图表数据修改冲突:如何隔离不同图表的数据集?
解决JavaScript引用赋值导致的数据集污染问题
要实现原数据集与堆叠面积图用的数据集完全隔离,核心是对原图表数据进行深拷贝,生成一份独立的副本后再做补0操作。因为JavaScript中对象和数组是引用类型,直接赋值只会传递引用,修改副本会同步影响原数据,深拷贝能彻底切断这种关联。
结合你代码里用到的Underscore.js,有两种可靠的深拷贝方式:
方法1:使用Underscore的深拷贝API
Underscore提供了_.clone()方法,传入第二个参数true即可实现深拷贝;如果是Underscore 1.8及以上版本,也可以用更直观的_.cloneDeep()。
修改你的Update函数中赋值stackData的部分:
this.Update = function (data) { console.log('Compare Kpis js 114, Data: ', data); if (_.isUndefined(data) || _.isNull(data)) { data = {}; } // 深拷贝原图表数据,生成独立副本 var stackData = _.clone(data.chartData, true); // 或者用_.cloneDeep(data.chartData); console.log('Kpis js 135, Series 1: ', stackData.series[0].data); console.log('Kpis js 136, Series 1 xAxis: ', stackData.xAxis); var newElement; if (stackData.series[0].data.length < stackData.xAxis.length) { var i = stackData.series[0].data.length; while (i < stackData.xAxis.length) { newElement = {x: i, y: 0}; console.log('Kpis js 147, chart element: ', newElement); stackData.series[0].data.push(newElement); i++; } } console.log('Compare Kpis js 153, Chart Data: ', data.chartData); if (this.Chart && data.chartData) { this.Chart.Update(data.chartData); } if (this.Bars && data.chartData) { this.Bars.Update(data.chartData); } if (this.Stack && stackData) { this.Stack.Update(stackData); } };
方法2:使用原生JSON序列化/反序列化
如果项目中没有依赖Underscore的深拷贝,也可以用原生JSON方法实现深拷贝(注意:此方法不适用于包含函数、undefined、Symbol等JSON不支持类型的数据):
var stackData = JSON.parse(JSON.stringify(data.chartData));
关键说明
- 深拷贝会递归复制所有嵌套的对象和数组,生成完全独立的新对象,修改
stackData的任何属性都不会影响原data.chartData。 - 你之前的代码中
var stackData = data.chartData;只是传递了对象引用,所以补0操作会直接修改原数据集,导致Line和Bars图表也显示0值。修改为深拷贝后,原数据会保持原样,仅堆叠面积图使用补全后的副本。
内容的提问来源于stack exchange,提问作者DavidN
相关产品推荐
相关产品推荐

