<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ID-based force layout</title>
<link type="text/css" href="style.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
<script src="script.js"></script>
</head>
<body>
<svg id="chart"></svg>
</body>
</html>
// Code goes here
(function() {
var data = {
'nodes': [{
'id': 'A',
'x': 469,
'y': 410
}, {
'id': 'B',
'x': 493,
'y': 364
}, {
'id': 'C',
'x': 442,
'y': 365
}, {
'id': 'D',
'x': 467,
'y': 314
}, {
'id': 'E',
'x': 477,
'y': 248
}, {
'id': 'F',
'x': 425,
'y': 207
}, {
'id': 'G',
'x': 402,
'y': 155
}, {
'id': 'H',
'x': 369,
'y': 196
}, {
'id': 'I',
'x': 350,
'y': 148
}, {
'id': 'J',
'x': 539,
'y': 222
}, {
'id': 'K',
'x': 594,
'y': 235
}, {
'id': 'L',
'x': 582,
'y': 185
}, {
'id': 'M',
'x': 633,
'y': 200
}],
'links': [{
'source': 'A',
'target': 'B'
}, {
'source': 'B',
'target': 'C'
}, {
'source': 'C',
'target': 'A'
}, {
'source': 'B',
'target': 'D'
}, {
'source': 'D',
'target': 'C'
}, {
'source': 'D',
'target': 'E'
}, {
'source': 'E',
'target': 'F'
}, {
'source': 'F',
'target': 'G'
}, {
'source': 'F',
'target': 'H'
}, {
'source': 'G',
'target': 'H'
}, {
'source': 'G',
'target': 'I'
}, {
'source': 'H',
'target': 'I'
}, {
'source': 'J',
'target': 'E'
}, {
'source': 'J',
'target': 'L'
}, {
'source': 'J',
'target': 'K'
}, {
'source': 'K',
'target': 'L'
}, {
'source': 'L',
'target': 'M'
}, {
'source': 'M',
'target': 'K'
}]
}
var d3color = d3.scale.category20()
var width = 960,
height = 500
var force = d3.layout.force()
.size([width, height])
.linkDistance(20)
.charge(-30)
.gravity(0.1)
.linkStrength(1)
.friction(0.9)
.theta(0.8)
.alpha(0.1)
.on("tick", tick);
var svg = d3.select('#chart')
.attr("width", width)
.attr("height", height);
var drag = force.drag()
.on("dragstart", dragstart);
var link, node
var nodes = data.nodes
var edges = [];
data.links.forEach(function(e) {
var sourceNode = data.nodes.filter(function(n) {
return n.id === e.source;
})[0],
targetNode = data.nodes.filter(function(n) {
return n.id === e.target;
})[0];
edges.push({
source: data.nodes.indexOf(sourceNode),
target: data.nodes.indexOf(targetNode),
value: e.value
});
});
links = edges
force
.nodes(nodes)
.links(links)
.start();
link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.on("dblclick", dblclick)
.append('circle')
.attr('r', 10)
.style("fill", function(d) {
return d3color(d.group)
})
.call(force.drag);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) {
return d.id
});
node.append("title").text(function(d) {
return d.name ? d.name : (d.id ? d.id : '')
});
function tick() {
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("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
}
function dblclick(d) {
d3.select(this).classed("fixed", d.fixed = false);
}
function dragstart(d) {
d3.select(this).classed("fixed", d.fixed = true);
}
})();
/* Styles go here */
.node > circle {
stroke-width: 2px;
stroke: gray;
fill: #dddddd;
}
.node > text {
pointer-events: none;
font-family: sans-serif;
text-anchor: middle;
}
.link {
stroke-width: 2px;
stroke: lightgrey;
}