Edges represented only as a pointer from one node to another. They end up as vector edges? Clockface edges?
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Sankey Particles</title>
<style>
.node rect {
cursor: move;
fill-opacity: .9;
shape-rendering: crispEdges;
}
.node text {
pointer-events: none;
text-shadow: 0 1px 0 #fff;
}
.link {
fill: none;
stroke: #000;
stroke-opacity: .05;
}
.link:hover {
stroke-opacity: .25;
}
svg {
position: absolute;
}
canvas {
position: absolute;
}
</style>
</head>
<body>
<svg width="1000" height="1000" ></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js" charset="utf-8" type="text/javascript"></script>
<script type="text/javascript">
function arrowhead(d, headSize, bodySize) {
var bodySize = 2;
var diffX = d.target.y - d.source.y;
var diffY = d.target.x - d.source.x;
var angle0 = ( Math.atan2( diffY, diffX ) + ( Math.PI / 2 ) );
var angle1 = angle0 - ( Math.PI / 2 );
var angle2 = angle0 + ( Math.PI / 2 );
var x1 = d.source.x + (headSize * Math.cos(angle1));
var y1 = d.source.y - (headSize * Math.sin(angle1));
var x2 = d.source.x + (headSize * Math.cos(angle2));
var y2 = d.source.y - (headSize * Math.sin(angle2));
var x3 = d.target.x + (headSize * Math.cos(angle2));
var y3 = d.target.y - (headSize * Math.sin(angle2));
var x4 = d.target.x + (headSize * Math.cos(angle1));
var y4 = d.target.y - (headSize * Math.sin(angle1));
var mx1 = d.source.x + (bodySize * Math.cos(angle1));
var my1 = d.source.y - (bodySize * Math.sin(angle1));
var mx2 = d.source.x + (bodySize * Math.cos(angle2));
var my2 = d.source.y - (bodySize * Math.sin(angle2));
var mx3 = d.target.x + (bodySize * Math.cos(angle1));
var my3 = d.target.y - (bodySize * Math.sin(angle1));
var mx4 = d.target.x + (bodySize * Math.cos(angle2));
var my4 = d.target.y - (bodySize * Math.sin(angle2));
var midY2 = (my1 + my3) / 2;
var midX2 = (mx1 + mx3) / 2;
var midY1 = (my2 + my4) / 2;
var midX1 = (mx2 + mx4) / 2;
var midDiffY1 = my1 - my3;
var midDiffX1 = mx1 - mx3;
var midDiffY2 = my2 - my4;
var midDiffX2 = mx2 - mx4;
var pythag = Math.sqrt((midDiffX1 * midDiffX1) + (midDiffY1 * midDiffY1));
var adjX1 = mx1 - ((midDiffX1 * headSize) / pythag);
var adjY1 = my1 - ((midDiffY1 * headSize) / pythag);
var adjX2 = mx1 - ((midDiffX2 * headSize) / pythag);
var adjY2 = my1 - ((midDiffY2 * headSize) / pythag);
return "M" + mx1 + "," + my1 + "L" + adjX1 + "," + adjY1 + " L " + adjX2 + "," + adjY2 + " L " + mx2 + "," + my2 + "z";
}
set3 = ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"];
d3.json("network.json", makeViz)
function makeViz(data) {
force = d3.layout.force().links(data.links).nodes(data.nodes)
.charge(function (d) {return d.weight * -200})
.size([1000,1000])
.on("tick", tick)
d3.select("svg").selectAll("path.source").data(data.links)
.enter()
.append("path")
.attr("class", "source")
.style("fill", "lightgreen")
.style("stroke", "black")
.style("stroke-width", 1)
d3.select("svg").selectAll("path.target").data(data.links)
.enter()
.append("path")
.attr("class", "target")
.style("fill", "gold")
.style("stroke", "black")
.style("stroke-width", 1)
d3.select("svg").selectAll("circle").data(data.nodes)
.enter()
.append("circle")
.attr("r", 20)
.style("fill", function (d) {return set3[d.module]})
.style("fill-opacity", 0.2)
.style("stroke", "darkgray")
.style("stroke-opacity", 0.3)
.call(force.drag)
force.start();
function tick(e) {
d3.selectAll("circle")
.attr("cx", function (d) {return d.x})
.attr("cy", function (d) {return d.y});
d3.selectAll("path.source")
.attr("d", function (d) {return arrowhead(d, 20, 1)})
d3.selectAll("path.target")
.attr("d", function (d) {return arrowhead({source: d.target, target: d.source}, 20, 1)})
}
}
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js