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,...