Making Tree Diagram from Data (part I)

In the previous articles we have seen the different aspects of a tree diagram in D3.js. By now you know that tree diagram is a data visualization feature. We have talked a lot about visualization in the previous artiles. But the data also holds an important part in it.

The example which we are using throughout this article we have a data set with the hierarchial order. Like the following

var treeData = [
  {
    "name": "Parent 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": "Level 2: B",
        "children":[{
          "name": "Son of B",
            "parent": "Level 2: B"
        },
        {
          "name": "Son of B",
            "parent": "Level 2: B"
        },
        {
          "name": "Son of B",
            "parent": "Level 2: B"
        },
        ]
      }
    ]
  }
];

But in real life we won’t be getting data like this. We will be getting data as a “Flat” or from external source. So, in that case setting up the data like above will take a lot of crucial time.
So, let us see how we can get out of these problems?

Using Flat Data:

Most data in a raw form will be flat. That is to say, it won’t be formatted as an array with the parent – child relationships. Instead it will be a list of objects that might describe the relationship to each other, but they won’t be encoded that way. For example, the following is the flat representation of the example data we have been using thus far.

var data = [
   { "name" : "Parent Level", "parent":"null" },
    { "name" : "Level 2: A", "parent":"Parent Level" },
    { "name" : "Son of A", "parent":"Level 2: A" },
    { "name" : "Daughter of A", "parent":"Level 2: A" },
    { "name" : "Level 2: B", "parent":"Parent Level" },
    {"name" : "Son of B", "parent":"Level 2: B" },
    {"name" : "Son of B", "parent":"Level 2: B" },
    {"name" : "Son of B", "parent":"Level 2: B" }
    ];

It’s easy to see how this data could be developed into a hierarchical form, but it would take a little time and for a larger data set, that would be problematic. It’s worth noting here that we have also changed the name of the array (to data) since we are going to convert, then declare our newly massaged data with our original variable name treeData so that the remainder of our code thinks there have been no changes.

So, the first change will be that i used a .reduce method, which starts with an empty object and iterates over the data array, adding an entry for each node. Observe the code.

 var dataMap = data.reduce(function(map, node) {
 map[node.name] = node;
 return map;
}, {});

Then we iteratively add each child to its parents, or to the root array if no parent is found. The code is essentially working through each node in the array and if it has a child it adds it to the childrensub-array and if necessary creates the array. Likewise, if the node has no parent, it simply add it as a root node.

var treeData = [];
data.forEach(function(node) {
 // add to parent
 var parent = dataMap[node.parent];
 if (parent) {
  // create child array if it doesn't exist
  (parent.children || (parent.children = []))
   // add node to child array
   .push(node);
 } else {
  // parent is null or missing
  treeData.push(node);
 }
});

And we have the same result as before.

ver_tree
There is also possibility that data can be retrived from outer source. Which we will discuss the process in the next article.

If you find this article helpful, you can connect us in Google+ and Twitter.

Leave a Reply

Your email address will not be published. Required fields are marked *