We can model relationships between entities using a Force Chart. Use SVG to draw the nodes and edges. The D3 Force layout provides a means of animating and interacting with the chart.
This example contains two data sets. 'People', which could be players in a game, and 'Killed' which captures the details of which players kill other players.
//Width and height
var w = 500;
var h = 500;
//Original data
var dataset = {
people: [
{ name: "Adam", r: 10 },
{ name: "Bob", r: 10 },
{ name: "Carrie", r: 10 },
{ name: "Donovan", r: 10 },
{ name: "Edward", r: 40 },
{ name: "Felicity", r: 25 },
{ name: "George", r: 15 },
{ name: "Hannah", r: 5 },
{ name: "Iris", r: 30 },
{ name: "Jerry", r: 20 }
],
killed: [
{ source: 0, target: 1 },
{ source: 0, target: 2 },
{ source: 0, target: 3 },
{ source: 0, target: 4 },
{ source: 1, target: 5 },
{ source: 2, target: 5 },
{ source: 2, target: 5 },
{ source: 3, target: 4 },
{ source: 5, target: 8 },
{ source: 5, target: 9 },
{ source: 6, target: 7 },
{ source: 7, target: 8 },
{ source: 8, target: 9 }
]
};
// Initialize a default force layout,
// using the nodes and edges in dataset
var force = d3.layout.force()
.nodes(dataset.people)
.links(dataset.killed)
.size([w, h])
.linkDistance([200])
.charge([-10])
.start();
var colors = d3.scale.category10();
//Create SVG element
var svg = d3.select("#draw_here")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create edges as lines
var lines = svg.selectAll("line")
.data(dataset.killed)
.enter()
.append("line")
.style("stroke", "#ccc")
.style("stroke-width", 1);
//Create nodes as circles
var circles = svg.selectAll("circle")
.data(dataset.people)
.enter()
.append("circle")
.attr("r", function(d){
return d.r;
})
.style("fill", function(d, i) {
return colors(i);
})
.attr("opacity", "0.5")
.call(force.drag);
var text = svg.selectAll("text")
.data(dataset.people)
.enter()
.append("text")
.text(function (d) {
return d.name;
})
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "11px");
//Every time the simulation "ticks", this will be called
force.on("tick", function() {
lines.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; });
circles.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
text.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
});