1

we are trying to create a visualisation with D3 which represents a stock portfolios assets with relative sized weightings with 3 levels deep nested data. We have used D3 Pack and a zoom function such as this as a template https://bl.ocks.org/mbostock/7607535

The issue we are facing is D3 pack works from the children up the parent chain, and the parents sizes are not relative to each other due to the fact D3 pack tries to pack the children most efficiently as possible and depending on the number and size of the circles in each container they will be more or less efficient by volume (2 circles of equal size is 50% efficient to its parent circle volume, where as 3 circles is approx. 75% efficient). This means the object with 3 circles appears smaller than the object with 2 circles, even both add up to the same weighting, lets say 50,50 and 33,33,33.

Is there a way to make the parents equal by size for such a visualisation? Essentially this would require additional padding on the smaller circles or scale the children of the larger one down to match. Its an interesting problem and I think the reverse of what D3 pack was set out to achieve but a very practical application.

Thanks in advance.

James Harris
  • 109
  • 1
  • 2
  • 2
    No, unfortunately there is not. Actually this has nothing to do with D3: what you're asking is **not** the purpose and definition of a circle packing, a circle packing is about the size (area) of the children. The area of the parents are meaningless. Have a look at the discussion I had with this user here: https://stackoverflow.com/q/50894731/5768908 – Gerardo Furtado Jun 21 '18 at 05:08
  • Thanks Gerardo, I have read that question also and believe the question remains unsolved. I feel this would be a great feature of D3 to have the ability to scale proportionally from the top down which would better satisfy many UX requirements out there. After all a tool is only as good as the problem it solves. Thanks again. – James Harris Jun 21 '18 at 06:11
  • I'll tell you again what I told that user: this proposed feature makes little sense. – Gerardo Furtado Jun 21 '18 at 06:30
  • 1
    If you want **only** the parents (the root's first generation children) to be scaled (in area) proportionate to their value, this can be done with fairly easily with `d3.pack()`. If however, you want multiple or all generations to have the same areal scaling factor then a circle pack cannot achieve this: a parent would have child circles that occupy the same amount of space as the parent - something that is only possible if you can pack the child circles without void space - which naturally you can't. Unless I misread, I think you're asking for the first option, is that right? – Andrew Reid Jun 21 '18 at 10:12
  • 1
    @AndrewReid *"something that is only possible if you can pack the child circles without void space - which naturally you can't"*. Good point, a circle packing without the void space would be... a treemap! Actually, a treemap is what both this OP and the OP of the linked question are asking, if you stop to think. – Gerardo Furtado Jun 21 '18 at 10:35
  • @GerardoFurtado, obvious solution now that you mention it - proportional the whole way through and hierarchical. A perfect example of why I need to take a step back sometimes, otherwise I completely fail to see the obvious. – Andrew Reid Jun 21 '18 at 23:51
  • @JamesHarris. I've provided an answer to the question Gerardo linked to - the answer I have written covers the situation you appear to be asking about and a few other potential organizational strategies for a circle pack (that question felt like a better match for the answer, especially given the comments). The second strategy in the answer there explains how to make an arbitrary generation (say top level parents) scale uniformly in a circle pack. Though I agree with Gerardo, a tree map is likely more ideal. And is something more quickly and intuitively understood at all hierarchical levels. – Andrew Reid Jun 22 '18 at 02:29
  • 1
    @AndrewReid Thanks! That is a very good answer indeed, and I believe exactly what I was looking for. In fact I had implemented a similar solution to your '2. Proportional Areas For A Single Generation'. However I then ran into problems with the zoom panning function, but your way is much cleaner and does it in 1 render pass which probably solves my issue (I tried to have multiple render passes one child at a time recursively). I will give it a try! Thanks again. – James Harris Jun 22 '18 at 05:00
  • @JamesHarris, Thanks, glad that it covers what you were looking for - it's rare that D3 circle packing questions end with a happy resolution on SO, in my experience, because of the restrictions of the algorithm. Hope that you manage to implement the zoom. – Andrew Reid Jun 22 '18 at 05:26

0 Answers0