JSFiddle - React, Tailwind, and code Playground
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/2.10.0/d3.v2.min.js"></script>
<html>
<head><title>Hello</title>
<style>
.link line {
stroke: #696969;
}
.link line.separator {
stroke: #fff;
stroke-width: 2px;
}
.node circle {
stroke: #000;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
pointer-events: none;
}
</style>
</head>
<body>
</body>
</html>
JavaScript
(function(){
var width, height, rules, map, tasks, links, nodes, svg, tick, radius, force, link, node;
width = 960;
height = 500;
rules = [['P1', 'T1'], ['T1', 'P2'], ['T1', 'P3'], ['P2', 'T2'], ['P3', 'T2'], ['T2', 'P4']];
map = d3.map();
rules.forEach(function(rule){
map.set(rule[0], {
fixed: false
});
return map.set(rule[1], false);
});
map.set('P1', {
fixed: true,
x: 100,
y: height / 2
});
map.set('P4', {
fixed: true,
x: width / 2 - 100,
y: height / 2
});
tasks = map.keys();
links = rules.map(function(rule){
return {
source: tasks.indexOf(rule[0]),
target: tasks.indexOf(rule[1])
};
});
nodes = tasks.map(function(k){
var entry;
entry = {
name: k
};
if (map.get(k).fixed) {
entry.fixed = true;
entry.x = map.get(k).x;
entry.y = map.get(k).y;
}
return entry;
});
svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
svg.append("svg:defs").append("svg:marker").attr("id", "arrow").attr("viewBox", "0 0 10 10").attr("refX", 0).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto").append("svg:path").attr("d", "M 0 0 L 10 5 L 0 10 z");
svg.append("line").attr("x1", 5).attr("x2", 50).attr("y1", 5).attr("y2", 50).style("stroke", "black").attr("stroke-width", 2).attr("marker-end", "url(#arrow)");
tick = function(){
var arrowheadLength = 8, // from markerWidth
nodeRadius = 10;
link.each(function(d) {
var x1 = d.source.x,
y1 = d.source.y,
x2 = d.target.x,
y2 = d.target.y,
angle = Math.atan2(y2 - y1, x2 - x1);
d.targetX = x2 - Math.cos(angle) * (nodeRadius + arrowheadLength);
d.targetY = y2 - Math.sin(angle) * (nodeRadius + arrowheadLength);
});
link.selectAll("line").attr("x1", function(d){
return d.source.x;
}).attr("y1", function(d){
...