VivekDev
VivekDev

Reputation: 25349

How to specify custom children and parent property for tree layout in D3

If I give the following JSON to d3, it works.

  {
      "name": "Top Level",
      "parent": "null",
      "children": [
        {
            "name": "Level 2: A",
            "parent": "Top Level",
            "children": [
              {
                  "name": "Son of A",
                  "parent": "Level 2: A"
              },
              {
                  "name": "Daughter of A",
                  "parent": "Level 2: A"
              }
            ]
        },
        {
            "name": "Level 2: B",
            "parent": "Top Level"
        }
      ]
  }

But if I change to following it does not work. Note the changes are CAPITAL C in children, P in parent and instead of name I have DeptCode So the question is is there a way to instruct d3 to work with a json with Children instead of children, Parent instead of parent and DeptCode instead of name?

  {
      "DeptCode": "Top Level",
      "Parent": "null",
      "Children": [
        {
            "DeptCode": "Level 2: A",
            "Parent": "Top Level",
            "Children": [
              {
                  "DeptCode": "Son of A",
                  "Parent": "Level 2: A"
              },
              {
                  "DeptCode": "Daughter of A",
                  "Parent": "Level 2: A"
              }
            ]
        },
        {
            "DeptCode": "Level 2: B",
            "Parent": "Top Level"
        }
      ]
  }

EDIT: I just found this. But I could not decipher what to do. Can someone elaborate please?

Upvotes: 3

Views: 3012

Answers (2)

Danny Harding
Danny Harding

Reputation: 1745

This is actually much more simple than the accepted answer. All you need to do is let d3 format your data in the correct way (using children instead of Children and parent instead of Parent. In d3 v3 this is done with d3.layout.hierarchy()` like so:

var myJSON = {
  "DeptCode": "Top Level",
  "Parent": "null",
  "Children": [
    {
        "DeptCode": "Level 2: A",
        "Parent": "Top Level",
        "Children": [
          {
              "DeptCode": "Son of A",
              "Parent": "Level 2: A"
          },
          {
              "DeptCode": "Daughter of A",
              "Parent": "Level 2: A"
          }
        ]
    },
    {
        "DeptCode": "Level 2: B",
        "Parent": "Top Level"
    }
  ]
}
var hierarchy = d3.layout.hierarchy()
   .children(function(d) {
       return d.Children;
   });

hierarchy(myJSON);

// use myJSON like you normally would

This will add children and parent keys to the correct objects, and now d3 will be able to use your json without you having to make the extra changes suggested above.

EDIT: Working code here

Upvotes: 3

Cyril Cherian
Cyril Cherian

Reputation: 32327

For the given dataset

var treeData = [
  {
      "DeptCode": "Top Level",
      "Parent": "null",
      "Children": [
        {
            "DeptCode": "Level 2: A",
            "Parent": "Top Level",
            "Children": [
              {
                  "DeptCode": "Son of A",
                  "Parent": "Level 2: A"
              },
              {
                  "DeptCode": "Daughter of A",
                  "Parent": "Level 2: A"
              }
            ]
        },
        {
            "DeptCode": "Level 2: B",
            "Parent": "Top Level"
        }
      ]
  }
];

This is how you wire it:

Since the data has Children instead of default children.

var tree = d3.layout.tree()
    .size([height, width])
    .children(function(d){return d.Children;});//this will provide children.

For text on the nodes do:

  nodeEnter.append("text")
      .attr("x", function(d) { return d.children || d._children ? -13 : 13; })
      .attr("dy", ".35em")
      .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
      .text(function(d) { return d.DeptCode; })//the new label name
      .style("fill-opacity", 1e-6);

For collapsable node do:

// Toggle children on click.
function click(d) {
  if (d.Children) {
    d._children = d.Children;//since the children is stored in Children.
    d.Children = null;
  } else {
    d.Children = d._children;
    d._children = null;
  }
  update(d);
}

Working code here

Hope this helps!

Upvotes: 4

Related Questions