Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
413 views
in Technique[技术] by (71.8m points)

d3.js - D3: update data with multiple elements in a group

I have a combined bar / line chart. For each row in the input file, I create a group that contains multiple elements (lines, rectangles, texts):

var myGroups = svg.selectAll('g').data(myData)
myGroups.enter().append('g')
...
myGroups.append('line')
...
myGroups.append('polygon')
...
myGroups.append('text')
...

I currently just

svg.selectAll('*').remove()

and create everything from scratch every time the data are updated. However, I'd like to have a smooth transition for all elements.

I've gone through this tutorial several times, but I still don't understand how I can do it in my case.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The key is to handle all the selections, not just the enter selection:

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();

There are two things here that warrant further explanation. First, elements in the enter selection that have had new elements appended merge into the update selection. That is, there is no need to set attributes on the elements in the enter selection if the same thing happens in the update selection. This allows you to append new elements and update existing ones without duplicating code.

The second thing becomes important on subsequent calls with updated data. As the elements you're binding the data to are not the ones that are actually drawn, the new data needs to be propagated to them. This is what .select() does. That is, by doing myGroups.select("line"), you're propagating the new data bound to the g elements to their children line elements. So the code to set attributes is the same as for the enter case.

Now you can simply add transitions where desired before setting the new attributes.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...