D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
calvinmetcalf
Full window
Github gist
N-Body Problem
A recreation of an
earlier Protovis example
.
<!DOCTYPE html> <meta charset="utf-8"> <style> body { background: #000; } </style> <canvas width="960" height="500"></canvas> <script src="//d3js.org/d3.v3.min.js"></script> <script> var canvas = document.querySelector("canvas"), context = canvas.getContext("2d"), width = canvas.width, height = canvas.height; var n = 200, tau = 2 * Math.PI, nodes = d3.range(n).map(function() { return {radius: Math.random() * 8 + 2}; }); var force = d3.layout.force() .charge(0.1) .gravity(0) .friction(0.9) .nodes(nodes) .size([width, height]) .start(); var stroke = d3.scale.linear() .domain([0, 1]) .range(["steelblue", "brown"]); force.on("tick", function(e) { var q = d3.geom.quadtree(nodes), node, i, vx, vy; context.clearRect(0, 0, width, height); context.lineWidth = 1.5; for (i = 0; i < n; ++i) { q.visit(collide(nodes[i])); } for (i = 0; i < n; ++i) { node = nodes[i]; context.beginPath(); context.arc(node.x, node.y, node.radius - 0.75, 0, tau); context.strokeStyle = stroke((vx = node.x - node.px) * vx + (vy = node.y - node.py) * vy); context.stroke(); } context.beginPath(); for (i = 0; i < n; ++i) { node = nodes[i]; context.moveTo(node.x, node.y); context.lineTo(node.x + (node.x - node.px) * 3, node.y + (node.y - node.py) * 3); } context.strokeStyle = "#fff"; context.stroke(); force.resume(); }); function collide(node) { var r = node.radius + 16, nx1 = node.x - r, nx2 = node.x + r, ny1 = node.y - r, ny2 = node.y + r; return function(quad, x1, y1, x2, y2) { if (quad.point && (quad.point !== node)) { var x = node.x - quad.point.x, y = node.y - quad.point.y, l = Math.sqrt(x * x + y * y), r = node.radius + quad.point.radius; if (l < r) { l = (l - r) / (l * 2); node.x -= x *= l; node.y -= y *= l; quad.point.x += x; quad.point.y += y; } } return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; } } </script>
https://d3js.org/d3.v3.min.js