我有一张nvd3多栏图表(但饼图会出现同样的问题)。
我希望在用户启用或禁用系列时保存图例的状态,方法是在图例中单击它。所以我正在听 stateChange 事件。
在以下示例代码中,有两个系列。当用户点击 series1 以禁用它时,控制台应该记录:
New State: {"disabled":[true,false]}
使用服务器中的新数据刷新图表后会出现问题(在下面的代码中由 setInterval 模拟)。第一次刷新后,我总是收到错误的事件,即 已禁用属性的值被搞砸了。
也许我刷新图表的方式是错误的?
示例代码:
var initialData = [
{ key: 'series1', values: [
{ x: 0, y: 10},
{ x: 1, y: 44}
]},
{ key: 'series2', values: [
{ x: 0, y: 25},
{ x: 1, y: 11}
]}
];
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarChart()
.delay(0);
d3.select('#chart1 svg')
.datum(initialData)
.call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) {
nv.log('New State:', JSON.stringify(e));
});
setInterval(function ()
{
var newDataFromServer = [
{ key: 'series1', values: [
{ x: 0, y: Math.floor((Math.random()*100)+1)},
{ x: 1, y: Math.floor((Math.random()*100)+1)}
]},
{ key: 'series2', values: [
{ x: 0, y: Math.floor((Math.random()*100)+1)},
{ x: 1, y: Math.floor((Math.random()*100)+1)}
]}
];
d3.select('#chart1 svg')
.datum(newDataFromServer)
.call(chart);
nv.utils.windowResize(chart.update);
}, 5000);
return chart;
});
答案 0 :(得分:1)
我找到了一个有效的解决方案。我没有时间进一步调查,但在以下代码中( nvd3 / legend.js ):
.on('click', function(d,i) {
dispatch.legendClick(d,i);
if (updateState) {
if (radioButtonMode) {
// etc ...
}
else {
// Note: this 'd' doesn't belong to the 'data' array in the current scope
d.disabled = !d.disabled;
// etc ...
}
dispatch.stateChange({
// The old data is notified as event
disabled: data.map(function(d) { return !!d.disabled })
});
}
})
当行为不端时(即第一次更新后), d对象不属于此范围内的数据数组(假设去做)。我猜这个数据总是指向初始数据数组。
作为更新图表的解决方法,我获取了初始数组并就地更新了它:
// Get reference to data array object
var chartDatum = d3.select('#chart1 svg')
.datum();
// Clear array and copy new data into it
chartDatum.length = 0;
angular.extend(chartDatum, newDataFromServer); // Or jQuery extend, or equivalent
chart.update();