Playing with the new v4 force-layout example, using SVG to render the nodes.
forked from mbostock's block: Force-Directed Graph v4 (with SVG)
xxxxxxxxxx
<meta charset="utf-8">
<style>
body { margin: 0; }
svg, canvas {position: absolute; }
</style>
<canvas width="960" height="500"></canvas>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.0.0-alpha.35.min.js"></script>
<script>
var canvas = document.querySelector("canvas"),
context = canvas.getContext("2d"),
width = canvas.width,
height = canvas.height;
var simulation = d3.forceSimulation()
.force("charge", d3.forceManyBody())
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("center", d3.forceCenter());
var svg = d3.select("svg")
d3.json("miserables.json", function(error, graph) {
if (error) throw error;
var group = svg.append("g")
.attr("transform", "translate(" + [width/2, height/2] + ")")
var circles = group
.selectAll("circle.node")
.data(graph.nodes)
circles.enter().append("circle").classed("node", true)
.attr("r", 5)
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.beginPath();
graph.links.forEach(drawLink);
context.strokeStyle = "#aaa";
context.stroke();
context.beginPath();
graph.nodes.forEach(drawNode);
context.fill();
context.strokeStyle = "#fff";
context.stroke();
context.restore();
svg.selectAll("circle.node")
.attr("cx", function(d) { return d.x })
.attr("cy", function(d) { return d.y })
}
function drawLink(d) {
context.moveTo(d.source.x, d.source.y);
context.lineTo(d.target.x, d.target.y);
}
function drawNode(d) {
context.moveTo(d.x + 3, d.y);
context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
}
});
</script>
https://d3js.org/d3.v4.0.0-alpha.35.min.js