Skip to content

Instantly share code, notes, and snippets.

@pbogden
Last active February 1, 2022 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pbogden/854425acb57b4e5a4fdf4242c068a127 to your computer and use it in GitHub Desktop.
Save pbogden/854425acb57b4e5a4fdf4242c068a127 to your computer and use it in GitHub Desktop.
Clustered Force Layout v4
<!DOCTYPE html>
<meta charset="utf-8">
<title>Clustered Force Layout</title>
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var width = 960,
height = 500,
maxRadius = 12;
var n = 200, // total number of circles
m = 10; // number of distinct clusters
var color = d3.scaleOrdinal(d3.schemeCategory10)
.domain(d3.range(m));
// The largest node for each cluster.
var clusters = new Array(m);
var nodes = d3.range(n).map(function() {
var i = Math.floor(Math.random() * m),
r = Math.sqrt((i + 1) / m * -Math.log(Math.random())) * maxRadius,
d = {cluster: i, radius: r};
if (!clusters[i] || (r > clusters[i].radius)) clusters[i] = d;
return d;
});
var forceCollide = d3.forceCollide()
.radius(function(d) { return d.radius + 1.5; })
.iterations(1);
var force = d3.forceSimulation()
.nodes(nodes)
.force("center", d3.forceCenter())
.force("collide", forceCollide)
.force("cluster", forceCluster)
.force("gravity", d3.forceManyBody(30))
.force("x", d3.forceX().strength(.7))
.force("y", d3.forceY().strength(.7))
.on("tick", tick);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
var circle = svg.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", function(d) { return d.radius; })
.style("fill", function(d) { return color(d.cluster); })
// TODO: Update for v4
// .call(force.drag);
function tick() {
circle
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
function forceCluster(alpha) {
for (var i = 0, n = nodes.length, node, cluster, k = alpha * 1; i < n; ++i) {
node = nodes[i];
cluster = clusters[node.cluster];
node.vx -= (node.x - cluster.x) * k;
node.vy -= (node.y - cluster.y) * k;
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment