D3:使用组中的多个元素更新数据

Mik*_*ail 19 d3.js

我有一个组合的条形图/折线图.对于输入文件中的每一行,我创建一个包含多个元素(行,矩形,文本)的组:

var myGroups = svg.selectAll('g').data(myData)
myGroups.enter().append('g')
...
myGroups.append('line')
...
myGroups.append('polygon')
...
myGroups.append('text')
...
Run Code Online (Sandbox Code Playgroud)

我目前只是

svg.selectAll('*').remove()
Run Code Online (Sandbox Code Playgroud)

每次更新数据时都从头开始创建所有内容.但是,我希望所有元素都能顺利过渡.

我已经多次阅读本教程,但我仍然不明白我是如何做到这一点的.

Lar*_*off 42

关键是要处理所有选择,而不仅仅是输入选择:

var myGroups = svg.selectAll('g').data(myData);

// enter selection
var myGroupsEnter = myGroups.enter().append("g");
myGroupsEnter.append("line");
myGroupsEnter.append("polygon");
// ...

// update selection -- this will also contain the newly appended elements
myGroups.select("line").attr(...);
// ...

// exit selection
myGroups.exit().remove();
Run Code Online (Sandbox Code Playgroud)

这里有两件事需要进一步解释.首先,输入选择中已附加新元素的元素将合并到更新选择中.也就是说,如果在更新选择中发生相同的事情,则无需在输入选择中的元素上设置属性.这允许您附加新元素并更新现有元素而无需复制代码.

第二件事对于使用更新数据的后续调用变得很重要.由于您将数据绑定到的元素不是实际绘制的元素,因此需要将新数据传播给它们.这是做什么的.select().也就是说,通过这样做myGroups.select("line"),您将绑定到g元素的新数据传播到其子line元素.因此,设置属性的代码与输入大小写相同.

现在,您可以在设置新属性之前简单地添加所需的过渡.

  • 你是我翅膀下的风! (6认同)
  • `myGroups`包含多个元素,`.select()`为每个元素执行选择.也就是说,您要为多个元素选择单个元素.`.selectAll()`可能无法正常工作,因为它不会更新数据. (3认同)
  • @LarsKotthoff ,您知道如何使用新的 d3 v4 API 进行更新吗?我一直试图让它在使用和不使用 `merge` 方法的情况下工作,但没有运气。非常感谢您的任何建议! (2认同)