Question

I have this http://jsfiddle.net/thechrisjordan/p4Fwm/11/, where I'm manipulating a d3 pack layout with an HTML5 slider. Everything is working as I would like except for how the nodes are ordered when updateVis() is called.

This code is pretty straight forward: I'm creating the layout, and then the slider emits an event which causes the layout to update.

What I'm hoping to achieve is this same behavior but to have the child nodes remain in their same general areas in the pack as they change size. As you can see, they reposition themselves here.

It looks like my issue is line 69 where pack.nodes(data); is called. I've dug into d3 source but can't figure out how to prevent this reordering (and it may very well not be possible...).

I suppose an alternative would be to try and squeeze the pack layout into a force layout.

I'm brand new to d3 and am grateful for any insight here.

Was it helpful?

Solution

If I understood what you're asking to do, I'm pretty sure this is doable. Here's the fiddle; I added some RGB fun to help keep track of the circles.

This is done using the pack layout's sort() method, which ensures they're laid out in a persistent order. To achieve it, I had to assign an index value to each of the objects you declared (and the optional RGB color):

data.children.forEach(function(d, i) {
    d.index = i;
    d.fill = ['#c33','#3c3','#33c'][i];
});

Then it's a matter of using index to sort:

var pack = d3.layout.pack()
  .size([diameter - 4, diameter - 4])
  .sort(function(a,b) { return d3.ascending(a.index, b.index); }) // <--- this
  .value(function(d) { return d.size; });

Hope this helped.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top