我们说我有一个名为state
的名为[[0,1,0],[1,1,0],[1,2,1]]
的二维数组。该阵列的成员不断更新。我有D3使用以下代码成功渲染数组的每个成员:
function view(state)
const vis = d3.select('body')
.selectAll('div')
.data(state)
.enter()
.append('div')
.attr('style', 'display: flex')
.selectAll('span')
.data((d,i) => d)
.enter()
.append('span')
.text(d => d)
return vis
}
现在考虑每次view
更改时调用此state
函数。如何让D3仅重新渲染自上次渲染以来已更改的元素?目前,页面最初呈现,但D3从不重新呈现任何元素,尽管在每次状态更改时都会调用view
函数。
如果您想查看完整的来源,我发布了here
答案 0 :(得分:1)
是的,要处理这种情况,您需要使用正在执行的enter
来创建新元素,并exit
删除当前数组中没有的任何元素
我建议你这样做:
function view(state)
var visData = d3.select('body')
.selectAll('div')
.data(state, function(d){/*uniquely identify each element in array*/return d;});
const vis = visData.enter()
.append('div')
.attr('style', 'display: flex')
.selectAll('span')
.data((d,i) => d)
.enter()
.append('span')
.text(d => d);
//remove the unnecessary data divs.
visData.exit().remove();
return vis
}
进一步输入exit read
答案 1 :(得分:0)
当您想要渲染数据时,有两种情况:添加新视图元素(div,span和文本)时以及更新数据(文本)时。在您的代码中,您只完成了第一步。你应该做第二个。
d3.js提供两种情况的选择。当你写
var div = d3.select('body').selectAll('div');
您获得了视图中已存在的内容。但是如果你添加.enter()
,即
var div = d3.select('body').selectAll('div').enter();
已经是第二种情况了。你正在获得尚不存在的东西,应该被创造出来。
由于您的数据正在发生变化,您应该将代码分为两部分:视图创建,视图更新。
以下是a JSFiddle example如何为您的代码完成。可以改进示例,并且可以将创建/更新代码部分分开并放入相应的函数see there。
无论如何,我建议您阅读d {j}的general update pattern。