Controlling order of circles in D3 circle pack layout algorithm

2.2k Views Asked by At

I was wondering if it's possible to slightly change packing algorithm in d3.layout. Namely, I'd like to know if instead of putting a child node with highest value at the position where it touches parent node one can put it in the middle of it. Right now it looks like all children go by spiral with smallest child deep inside of the parent.

I hope it's not too confusing. I'll gladly clarify whatever is unclear.

2

There are 2 best solutions below

1
On BEST ANSWER

It is possible.

You only need to replace this code in d3.js:

  function d3_layout_packSort(a, b) {
    return a.value - b.value;
  }

with this code:

  function d3_layout_packSort(a, b) {
    return -(a.value - b.value);
  }

(just a change of sign)

Largest circles will not be at the very center of the parent, however they will tend to be close to the center. My understanding is that you don't need exact placement at the center, just approximate, so I hope this will satisfy your idea.

Following picture illustrates circular pack example obtained with regular and modified d3.js, side-by-side:

Regular and modified packing

I a kind of tend to like modified packing more. :) So I guess it was a good idea. Check how it looks with your data.

You can access these examples here: regular, modified.

My modified d3.js is here.

Let me know if you have additional questions.

3
On

D3 is open source, so you can do whatever modifications you like to it. For the packing layout, placing elements in the center of the containing shape would require potentially quite extensive modifications though because in doing so, you're further restricting the available space.

That is, with a circle at the edge the remainder of the space until the other edge can be used for other circles. If the circle is in the center, there is less space until the edge and therefore less space for circles. To preserve the visual correlation between size and data, the circle in the center would have to be smaller and so on.

So what you're talking about is not a simple modification, but a change of the implemented algorithm. Depending on what exactly you're trying to do, it may be easier to achieve this with another of D3's layouts.