Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active October 16, 2021 11:08
Show Gist options
  • Select an option

  • Save mbostock/3231298 to your computer and use it in GitHub Desktop.

Select an option

Save mbostock/3231298 to your computer and use it in GitHub Desktop.

Revisions

  1. mbostock revised this gist Sep 16, 2020. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -1 +1,2 @@
    license: gpl-3.0
    redirect: https://observablehq.com/@d3/collision-detection/2
  2. mbostock revised this gist Feb 9, 2016. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    license: gpl-3.0
  3. mbostock revised this gist Oct 31, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script>

    var width = 960,
  4. mbostock revised this gist Jun 11, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script>

    var width = 960,
  5. mbostock revised this gist Nov 21, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    Mouseover to repel nodes. Adapted from my [talk on force layouts](http://vimeo.com/29458354).
    Mouseover to repel nodes. Adapted from my [talk on force layouts](http://vimeo.com/29458354). Compare to the [canvas version](/mbostock/3231307).
  6. mbostock revised this gist Nov 21, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <body>
    <script src="http://d3js.org/d3.v2.min.js?2.9.7"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>

    var width = 960,
    @@ -22,7 +22,7 @@

    force.start();

    var svg = d3.select("body").append("svg:svg")
    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

  7. mbostock revised this gist Oct 12, 2012. 1 changed file with 0 additions and 0 deletions.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  8. mbostock revised this gist Aug 1, 2012. 1 changed file with 1 addition and 9 deletions.
    10 changes: 1 addition & 9 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,5 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>

    circle {
    stroke: #000;
    stroke-opacity: .5;
    }

    </style>
    <body>
    <script src="http://d3js.org/d3.v2.min.js?2.9.7"></script>
    <script>
    @@ -37,7 +29,7 @@
    svg.selectAll("circle")
    .data(nodes.slice(1))
    .enter().append("circle")
    .attr("r", function(d) { return d.radius - 2; })
    .attr("r", function(d) { return d.radius; })
    .style("fill", function(d, i) { return color(i % 3); });

    force.on("tick", function(e) {
  9. mbostock created this gist Aug 1, 2012.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Mouseover to repel nodes. Adapted from my [talk on force layouts](http://vimeo.com/29458354).
    86 changes: 86 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>

    circle {
    stroke: #000;
    stroke-opacity: .5;
    }

    </style>
    <body>
    <script src="http://d3js.org/d3.v2.min.js?2.9.7"></script>
    <script>

    var width = 960,
    height = 500;

    var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }),
    root = nodes[0],
    color = d3.scale.category10();

    root.radius = 0;
    root.fixed = true;

    var force = d3.layout.force()
    .gravity(0.05)
    .charge(function(d, i) { return i ? 0 : -2000; })
    .nodes(nodes)
    .size([width, height]);

    force.start();

    var svg = d3.select("body").append("svg:svg")
    .attr("width", width)
    .attr("height", height);

    svg.selectAll("circle")
    .data(nodes.slice(1))
    .enter().append("circle")
    .attr("r", function(d) { return d.radius - 2; })
    .style("fill", function(d, i) { return color(i % 3); });

    force.on("tick", function(e) {
    var q = d3.geom.quadtree(nodes),
    i = 0,
    n = nodes.length;

    while (++i < n) q.visit(collide(nodes[i]));

    svg.selectAll("circle")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; });
    });

    svg.on("mousemove", function() {
    var p1 = d3.mouse(this);
    root.px = p1[0];
    root.py = p1[1];
    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 * .5;
    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>