Home > Enterprise >  When to do slice vs non-slice in .data section in d3?
When to do slice vs non-slice in .data section in d3?

Time:07-31

I have a code which plots lines and circles.

I know what does slice do below. But when do we use slice vs non slice way of a variable in .data section?

 var link = g.selectAll(".link")
             .data(nodes.descendants().slice(1))
             .enter().append("path")
             .attr("class", "link")
             .style("stroke", function(d) { return d.data.level;})
             .attr("d", function(d)
             {
                return "M"   d.x   ","   d.y
                  "L"   d.parent.x   ","   d.parent.y;
             });

  var node = g.selectAll(".node")
             .data(nodes.descendants())
             .enter().append("g")
             .attr("class", "node")
             .attr("transform", function(d)
             {
               return "translate("   d.x   ","   d.y   ")";
             });

var circle = node.append("circle").attr("r",30);

CodePudding user response:

I take it you are using descendants() with d3.hierarchy - notice in the console output below that Eve has no parent because it is the 'root' node, and that all the other nodes in the descendants() array do have a parent.

const nodes = d3.hierarchy(data);
for (let d of nodes.descendants()) {
  let name = d.data.name;
  let depth = d.depth;
  let parentName = d.parent ? d.parent.data.name : 'no parent - no link!';
  let msg = `Name: ${name}; Depth: ${depth}; Parent: ${parentName}`;
  console.log(msg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script>
const data = {
  "name": "Eve",
  "children": [
    {
      "name": "Cain"
    },
    {
      "name": "Seth",
      "children": [
        {
          "name": "Enos"
        },
        {
          "name": "Noam"
        }
      ]
    },
    {
      "name": "Abel"
    },
    {
      "name": "Awan",
      "children": [
        {
          "name": "Enoch"
        }
      ]
    },
    {
      "name": "Azura"
    }
  ]
}
</script>

Then note d function:

.attr("d", function(d)
{
  return "M"   d.x   ","   d.y
    "L"   d.parent.x   ","   d.parent.y;
});

Which says Move the the centre of the 'child' circle and draw the Line to the middle of the 'parent' circle. Because your 'root' node (Eve) has no parent then this node should be eliminated from the link layout hence slice(1). But because all the other nodes should be connected to Eve then this root node is not sliced from here:

var node = g.selectAll(".node")
  .data(nodes.descendants())

In order that the circle for the Eve node is drawn and therefore the links from the child nodes of Eve can connect to something.

  • Related