67 lines
1.7 KiB
JavaScript
67 lines
1.7 KiB
JavaScript
|
drag = simulation => {
|
||
|
|
||
|
function dragstarted(event) {
|
||
|
if (!event.active) simulation.alphaTarget(0.3).restart();
|
||
|
event.subject.fx = event.subject.x;
|
||
|
event.subject.fy = event.subject.y;
|
||
|
}
|
||
|
|
||
|
function dragged(event) {
|
||
|
event.subject.fx = event.x;
|
||
|
event.subject.fy = event.y;
|
||
|
}
|
||
|
|
||
|
function dragended(event) {
|
||
|
if (!event.active) simulation.alphaTarget(0);
|
||
|
event.subject.fx = null;
|
||
|
event.subject.fy = null;
|
||
|
}
|
||
|
|
||
|
return d3.drag()
|
||
|
.on("start", dragstarted)
|
||
|
.on("drag", dragged)
|
||
|
.on("end", dragended);
|
||
|
}
|
||
|
|
||
|
var svg = d3.select("svg"),
|
||
|
width = +svg.attr("width"),
|
||
|
height = +svg.attr("height");
|
||
|
|
||
|
var simulation = d3.forceSimulation()
|
||
|
.force("charge", d3.forceManyBody().strength(-200))
|
||
|
.force("link", d3.forceLink().id(function(d) { return d.id; }).distance(40))
|
||
|
.force("x", d3.forceX(width / 2))
|
||
|
.force("y", d3.forceY(height / 2))
|
||
|
.on("tick", ticked);
|
||
|
|
||
|
var link = svg.selectAll(".link"),
|
||
|
node = svg.selectAll(".node");
|
||
|
|
||
|
graph = {{data}}
|
||
|
|
||
|
|
||
|
simulation.nodes(graph.nodes);
|
||
|
simulation.force("link").links(graph.links);
|
||
|
|
||
|
link = link
|
||
|
.data(graph.links)
|
||
|
.enter().append("line")
|
||
|
.attr("class", "link");
|
||
|
|
||
|
node = node
|
||
|
.data(graph.nodes)
|
||
|
.enter().append("circle")
|
||
|
.attr("class", "node")
|
||
|
.attr("r", 6)
|
||
|
.style("fill", function(d) { return d.id; });
|
||
|
|
||
|
|
||
|
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; });
|
||
|
}
|