Search code examples
javascriptsvgd3.jssunburst-diagram

Selecting arc/element


In the sunburst, how can I make code select a root arc, just after all arcs was generated?

For example, in the code:

var first_arc = ""
.json("../data/flare.json", function(json) {
   var path = vis.data([json]).selectAll("path")
       .data(partition.nodes)
     .enter().append("path")
       .attr("display", function(d) { return d.depth ? null : "none"; })
       .attr("d", arc)
       .attr("t_name", function(d) {return d.name})
       .style("fill-rule", "evenodd")
       .on("click", function(d)...

it would be passed as "d" to the "function" on click on the middle arc.

(its data goes first in the json file)

Update 1: Changing the code like so…

.style("fill-rule", function(d) {
   if (first_arc == "") first_arc = d; return "evenodd"})

…solved the problem, it returns object:

name: "flare"
children: Array[10]
...

but this solution doesn't look right and isn't general.

Update 2: I tried several selects, for example:

first_arc = d3.select("[name='flare']")

it usually returns array:

0: null
length: 1
parentNode: HTMLHtmlElement
__proto__: Array[0]

or "undefined"

Update 3:

first_arc = d3.select("[t_name='flare']")

returns array of size 1 with children:

0: SVGPathElement
   __data__: Object

, where __data__ is the object I'm after, but I can't manage to select it.


Solution

  • The root node is the one with a "depth" attribute set to 0. So you can say:

    d3.selectAll("path").filter(function(d) { return d.depth === 0; })
    

    Your attempts above weren't working because D3 uses CSS3 to select elements. So you can only use d3.select and d3.selectAll with CSS3 selectors i.e. you can't access the data bound to each element this way. The way to filter on the bound data is to use selection.filter.

    D3 selections are literally an array of elements, see the "Operating on Selections" section.

    Lastly, you can get the bound __data__ property for an element using selection.datum().