Built with blockbuilder.org
forked from easadler's block: Force Layout
license: mit |
Built with blockbuilder.org
forked from easadler's block: Force Layout
<!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> |