mnt
mnt

Reputation: 93

d3.js on-demand data loading to get the next node for a tree

I am trying to use this example in D3 (http://bl.ocks.org/mbostock/1093025), which is the expanding tree. From all the examples I see all the data is always loaded from a single JSON dataset.

The issue I am facing is that the data could potentially drill down into many, many nodes and the JSON would be huge...

Is there a way to make an ajax call when the user clicks on a branch and then add the data to the set and exapnd the tree branch?

thanks in advance

Matt

Upvotes: 3

Views: 2106

Answers (1)

K.E.
K.E.

Reputation: 838

I was searching for a very similar solution like you and solved my problem by doing this.

In the given example (http://bl.ocks.org/mbostock/1093025) you have a click method:

// Toggle children on click.
function click(d) {
  if (d.children) {
     d._children = d.children;
     d.children = null;
  } else {
     d.children = d._children;
     d._children = null;
  }
  update(d);
}

I changed the given one a bit:

 function click(d) {

          if (!d.children && !d._children) {

              var nameOfTheFile = d.jsonPath;
              var childObjects;

                 d3.json(nameOfTheFile, function(error, json) {

                    childObjects = json; 
                    childObjects.forEach(function(node) {
                            if(node.name != d.name){
                                (d._children || (d._children = [])).push(node);
                            }
                        });

                    if (d.children) {
                        d._children = d.children;
                        d.children = null;
                     } else {
                        d.children = d._children;
                        d._children = null;
                    }   
                    update(d);

                   }); 


          } else {
              if (d.children) {
                    d._children = d.children;
                    d.children = null;
              } else {
                    d.children = d._children;
                    d._children = null;
              }
              update(d);    
          }

  }

Explanation: I have added a property to my node where the a rest service URL is defined which returns me a JSON file with the children of the given node (Here you can also place the path to the JSON file itself). If the given node in the click(d) method does not have any children in his array then I read the property and call the URL to extract his children. The returned children I push to the d._children array and run the normal logic (also the update method).

So you can load the childs of a node on demand without having one big JSON file. For me it is a very good solution. Thanks to Distributed json loading in force collapsable layout, where the idea comes from.

Upvotes: 4

Related Questions