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, wiring up data, using a function to define 
  //how it's suppossed to know what is...