d3:更新数据集不更新DOM

d3: update dataset not updating the DOM

本文关键字:更新 DOM 数据集 d3      更新时间:2023-09-26

我想使用D3使用以下数据创建一个列表:

var dataSet = [
    { label: 'a', value: 10},
    { label: 'b', value: 20},
    { label: 'c', value: 30},
    { label: 'd', value: 40}
];
var circle = svg.selectAll('circle')
    .data(dataSet)
    .enter()
    .append('circle')
    .attr({
        r:function(d){ return d.value },
        cx:function(d, i){ return i * 100 + 50 },
        cy:50,
        fill: 'red'
    });

这是有效的。现在过了一段时间,我更改了数据

dataSet[0].value = 40;
dataSet[1].value = 30;
dataSet[2].value = 20;
dataSet[3].value = 10;

我想再画一次清单:

setTimeout(function () {
    var circle = svg.selectAll('circle')
      .data(dataSet, function (d) {
          return d.label;   
      })
     .sort(function (a,b){ return d3.ascending(a.value, b.value);})
     .enter()
     .append('circle')
     .attr({
        r:function(d){ return d.value },
        cx:function(d, i){ return i * 100 + 50 },
        cy:50,
        fill: 'red'
     });
},1000);

演示

然而,这个列表并没有真正更新。有什么建议可以解决这个问题吗?

问题是您只处理输入选择,在更新时它将为空——您需要处理更新选择:

svg.selectAll('circle')
.data(dataSet, function (d) {
    return d.label;   
})
.sort(function (a,b){ return d3.ascending(a.value, b.value);})
.transition()
.attr({
    r:function(d){ return d.value },
    cx:function(d, i){ return i * 100 + 50 },
    cy:50,
    fill: 'red'
});

此处更新了fiddle。有关不同选择的更多信息,请参阅本教程。

您需要清除setTimeout中的svg.html('');
DEMO

这可以通过首先调用来移除现有的圆圈来实现

svg.selectAll('circle').remove()

然后使用不同的数据集再次添加它们。我更新了你的小提琴http://jsfiddle.net/Q5Jag/1183/

希望这能有所帮助。

这里是一些进入和退出动画的相同小提琴http://jsfiddle.net/Q5Jag/1184/