Search code examples
javascriptd3.jsicicle-diagram

Is it possible to have multiple parent/root nodes in a D3 Icicle plot?


I am new to d3 and currently working on the Icicle layout example. I have 2 questions:

  1. Is it possible to have multiple top-level nodes in this example? In other words, instead of a single top-level node of "flare", can we have 3 top-level nodes ("flare1", "flare 2" and "flare 3"), which can then have their respective children nodes? I have tried importing the json data as an array of objects but that did not work.

If it is not possible to have multiple top-level nodes, how can I hide the root node ("flare") so that the 2nd level nodes ("vis", "util", "animate") appear to be top-level nodes?

  1. How can we sort the nodes (on a particular level) based on their position in the json file, rather than their size? In other words, how can we sort the second level nodes in the above example so that they appear (from left to right) in the order of "analytics", "cluster", "graph" and so on (their order in json file); instead of their current order ("vis", "util", "animate", etc.).

Solution

  • Multiple parent/nodes is probably not possible with a single partition layout, since it's a hierarchical layout that assumes single-parent relationship. But it should be achievable using two partition layouts backed by two different hierarchical jsons. You can generate the two jsons out of a single flat array (i.e. unlike flare.json), by using d3.nest().

    The rendering code will likely need to get more sophisticated too, so that it can negotiate between the 2 layouts.

    For #2, you can use partition.sort() to order them however you'd like. In your case, you'd want to sort by their index in the input array.

    UPDATE

    You can achieve what you describe rather simply — if each node truly has exactly one parent. So if you want 3 nodes at the top, they still need to be "wrapped" in a single common parent, which you pass to the partition layout. Then you'll need to take care of NOT rendering the parent node, by either filtering it out before binding and appending DOM nodes, or by setting it to display none. In either case, you can check if d.depth == 0 to identify the root node. And you'll also need to translate all the nodes up to account for the gap left by the missing root node, since the layout will set all the x and y coords as if the root node is in the layout. (Maybe there's a way to have the layout "realize" the root node is gone when assigning x and y positions if you use the .size() function to return 0 for the root node).