Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3: update data with multiple elements in a group

Tags:

d3.js

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.

like image 653
Mikhail Avatar asked Jul 23 '14 13:07

Mikhail


1 Answers

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.

like image 63
Lars Kotthoff Avatar answered Oct 21 '22 23:10

Lars Kotthoff