D3:Learning:Force Directed Graph:Collapsible

A starting point to clone and get investigating quickly.

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="viz" />

CSS

.node circle {
    cursor: pointer;
    stroke: #3182bd;
    stroke-width: 1.5px;
}
.node text {
    font: 10px sans-serif;
    pointer-events: none;
    text-anchor: middle;
}
line.link {
    fill: none;
    stroke: #9ecae1;
    stroke-width: 1.5px;
}

JavaScript

//Notes:
// Src: http://bl.ocks.org/mbostock/1093130
//Notes:
// * Each dom element is using 
//   children to store refs to expanded children
//   _children to store refs to collapsed children
//* It's using both a tree and a graph layout.


$(function () {
    var x = new G();
    x.render(data);
});



function G() {
    this.width = 960;
    this.height = 500;

    //original data:
    this.data = null;

    //d3 sets:    
    this.link = null;
    this.node = null;
    this.force = null;
}







G.prototype.render = function (data) {
    var self = this;

    this.data = data;

    //Create a sized SVG surface within viz:
    var svg = d3.select("#viz")
        .append("svg")
        .attr("width", this.width)
        .attr("height", this.height);

    this.link = svg.selectAll(".link"),
    this.node = svg.selectAll(".node");

    //Create a graph layout engine:
    this.force = d3.layout.force()
        .linkDistance(80)
        .charge(-120)
        .gravity(0.05)
        .size([self.width, self.height])
    //that invokes the tick method to draw the elements in their new location:
    .on("tick", function () { self._tick();});

    //Draw the graph for the first time:
    //Note that this method is invoked again
    //when clicking nodes:
    self._update();
};






//invoked once at the start, 
//and again when from 'click' method
//which expands and collapses a node.

G.prototype._update=function() {
    
    var self = this;

    //iterate through original nested data, 
    //and get one dimension array of nodes.
    var nodes = this._flatten(this.data);

    //Each node extracted above has a children attribute.
    //from them, we can use a tree() layout function in order
    //to build a links selection.
    var links = d3.layout.tree().links(nodes);

    // pass both of those sets to the graph layout engine, and restart it
    this.force.nodes(nodes)
        .links(links)
        .start();

    //-------------------
    //update a subselection,...