Force in a box is A d3.js force extension that implements the Group-in-a-box layout algorithm to distribute nodes in a network according to their clusters. The algorithm uses a treemap to compute focis that are later used to distribute each cluster into it's own box.
To use it you need to include the library, and use the forceInABox instead of the normal d3.layout.force
<script type="text/javascript" src="forceInABox.js"> </script>
//create the force and specify the grouping parameter
var force = d3.layout.forceInABox()
.groupBy("group");
//Add nodes and edges
force.nodes(nodes)
.edges(edges)
.start();
//Add the onTick method to the tick event
force.on("tick", function(e) {
force.onTick(e);
};
forked from john-guerra's block: Force in a Box algorithm
xxxxxxxxxx
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
.cell {
fill: none;
stroke: grey;
}
input[type=checkbox]
{
/* Triple-sized Checkboxes */
-ms-transform: scale(2); /* IE */
-moz-transform: scale(2); /* FF */
-webkit-transform: scale(2); /* Safari and Chrome */
-o-transform: scale(2); /* Opera */
padding: 10px;
}
.checkboxtext
{
/* Checkbox text */
font-family: sans-serif;
font-size: 110%;
display: inline;
}
.options {
margin-left: 20px;
}
</style>
<body>
<span class="options">
<input id="checkGroupInABox" type="checkbox">
<span class="checkboxtext">
Group in a Box
</span>
</input>
<input id="checkShowTreemap" type="checkbox">
<span class="checkboxtext">Show Treemap
</span>
</input>
</span>
<div id="chart"></div>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/john-guerra/forceinabox/forceinabox.js"></script>
<script>
var useGroupInABox = true,
drawTreeMap = false;
d3.select("#checkGroupInABox").property("checked", useGroupInABox);
d3.select("#checkShowTreemap").property("checked", drawTreeMap);
var width = 900,
height = 450;
var color = d3.scale.category20();
var force = d3.layout.forceInABox()
.charge(-120)
.linkDistance(50)
.linkStrengthInterCluster(0.01)
.gravityToFoci(0.2)
.gravityOverall(0.05)
.size([width, height])
.enableGrouping(useGroupInABox)
.groupBy("group");
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("miserables.json", function(error, graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.call(force.drag)
.style("fill", function(d) { return color(d.group); });
node.append("title")
.text(function(d) { return d.name; });
force.on("tick", function(e) {
if (useGroupInABox) {
force.onTick(e);
}
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
d3.select("#checkGroupInABox").on("change", function () {
force.stop();
useGroupInABox = d3.select("#checkGroupInABox").property("checked");
force.enableGrouping(useGroupInABox);
force.start();
});
d3.select("#checkShowTreemap").on("change", function () {
drawTreeMap = d3.select("#checkShowTreemap").property("checked");
if (drawTreeMap) {
force.drawTreemap(svg);
} else {
force.deleteTreemap(svg);
}
});
});
</script>
Updated missing url https://cdn.rawgit.com/john-guerra/forceInABox/master/forceInABox.js to https://cdn.jsdelivr.net/gh/john-guerra/forceinabox/forceinabox.js
https://d3js.org/d3.v3.min.js
https://cdn.rawgit.com/john-guerra/forceInABox/master/forceInABox.js