d3 通用更新模式
d3 General Update Pattern
我只是模仿代码 d3 update pattern 尝试用更新的数据渲染一些矩形
这是我的代码。
function update(data){
var r = g.selectAll("rect").data(data,function(d){return (d)});
r.exit().attr("class","exit").remove()
r
.attr("class","update")
.attr("x",(d, i) =>{return i* (50+interval)})
.attr("y", (d)=>{ return y(d)})
.attr("width", "20px")
.transition(t)
.attr("height",( d => { return height-padding.top-padding.bottom-y(d);}))
r.enter()
.append("rect")
.attr("width", "20px")
.attr("class","new")
.attr("x",(d, i) =>{ return i * (50+interval)})
.attr("y", (d)=>{return y(d)})
.attr("height",( d => { return height-padding.top-padding.bottom-y(d);}))
}
然后我调用更新函数两次
update([3,2,1,5,4,10,9,7,8,6])
setTimeout(()=>{update([2,3,1,5,4,10,9,7,8,6])},1000)
预期:只有第一个和第二个rect会被重新渲染并设置class“new”,但实际上,所有的rect都会被设置class“new”。
当数据是一组已识别对象时,enter/exit 模式有效。
替换此代码:
var r = g.selectAll("rect").data(data,function(d){return (d)});
与:
const _data = data.map((v,i) => ({id: i, value: v}));
const r = g.selectAll("rect").data(_data,d => d.id);
D3 将识别每个对象并相应地更新它,而不是替换为新对象。
看到它在 pen
中工作
更新:
如果要高亮显示值已更改的项目,可以将当前值保存在新添加项目的属性中:
r.enter()
.append("rect")
.attr('cur-value', d => d.value)
...
然后,在更新时,查询值并与数据中的值进行比较:
r.attr("class","update")
...
.each(function(d) {
const rect = d3.select(this);
const prevValue = parseInt(rect.attr('cur-value'));
rect.attr('cur-value', d.value);
rect.style('fill', prevValue === d.value ? 'black' : 'red')
});
您可以看到它在更新的笔中工作。
我只是模仿代码 d3 update pattern 尝试用更新的数据渲染一些矩形 这是我的代码。
function update(data){
var r = g.selectAll("rect").data(data,function(d){return (d)});
r.exit().attr("class","exit").remove()
r
.attr("class","update")
.attr("x",(d, i) =>{return i* (50+interval)})
.attr("y", (d)=>{ return y(d)})
.attr("width", "20px")
.transition(t)
.attr("height",( d => { return height-padding.top-padding.bottom-y(d);}))
r.enter()
.append("rect")
.attr("width", "20px")
.attr("class","new")
.attr("x",(d, i) =>{ return i * (50+interval)})
.attr("y", (d)=>{return y(d)})
.attr("height",( d => { return height-padding.top-padding.bottom-y(d);}))
}
然后我调用更新函数两次
update([3,2,1,5,4,10,9,7,8,6])
setTimeout(()=>{update([2,3,1,5,4,10,9,7,8,6])},1000)
预期:只有第一个和第二个rect会被重新渲染并设置class“new”,但实际上,所有的rect都会被设置class“new”。
当数据是一组已识别对象时,enter/exit 模式有效。 替换此代码:
var r = g.selectAll("rect").data(data,function(d){return (d)});
与:
const _data = data.map((v,i) => ({id: i, value: v}));
const r = g.selectAll("rect").data(_data,d => d.id);
D3 将识别每个对象并相应地更新它,而不是替换为新对象。
看到它在 pen
中工作更新: 如果要高亮显示值已更改的项目,可以将当前值保存在新添加项目的属性中:
r.enter()
.append("rect")
.attr('cur-value', d => d.value)
...
然后,在更新时,查询值并与数据中的值进行比较:
r.attr("class","update")
...
.each(function(d) {
const rect = d3.select(this);
const prevValue = parseInt(rect.attr('cur-value'));
rect.attr('cur-value', d.value);
rect.style('fill', prevValue === d.value ? 'black' : 'red')
});
您可以看到它在更新的笔中工作。