Skip to content

Instantly share code, notes, and snippets.

@easadler
Last active April 15, 2017 17:30
Show Gist options
  • Save easadler/b78f79cf71b10f9387e0ee0cc05a4612 to your computer and use it in GitHub Desktop.
Save easadler/b78f79cf71b10f9387e0ee0cc05a4612 to your computer and use it in GitHub Desktop.
Force Layout
license: mit
<!DOCTYPE html>
<style>
svg {
background-color: black;
}
.link line {
stroke: #aaa;
stroke-width: 2px;
}
.node circle {
pointer-events: all;
stroke: white;
stroke-width: 3px;
}
.center {
pointer-events: all;
stroke: orange;
stroke-width: 2px;
fill: none;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var radius = d3.scaleSqrt()
.domain([0, 20000])
.range([0, 20]);
var center = svg.append("g").append("circle")
.attr("class", "center");
var link = svg.append("g")
.attr("class", "link")
.selectAll("line");
var node = svg.append("g")
.attr("class", "node")
.selectAll("circle");
var drag = d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().distance(100))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.on("tick", ticked)
.stop();
var nodes = [{id: 'Music'}, {id: 'data'}, {id: 'vizualization'}]
var links = [{source: nodes[0], target: nodes[1]},{source: nodes[1], target: nodes[2]}, {source: nodes[2], target: nodes[0]}]
link = link.data(links).enter().append("line");
node = node.data(nodes).enter().append("circle")
.attr("r", function(d) { return 10; })
.call(drag);
simulation.nodes(nodes);
simulation.force("link").links(links);
simulation.restart();
function ticked() {
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; });
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x, d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x, d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null, d.fy = null;
}
center
.datum({x: width /2, y: height / 2})
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 3)
.call(d3.drag()
.on("start", dragstartedCenter)
.on("drag", draggedCenter)
.on("end", dragendedCenter));
function dragstartedCenter(d) {
d3.select(this).raise().classed("active", true);
}
function draggedCenter(d) {
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
simulation.force("center", d3.forceCenter(d3.event.x, d3.event.y))
simulation.alphaTarget(0.3).restart()
}
function dragendedCenter(d) {
d3.select(this).classed("active", false);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment