An arc diagram is another way of visualizing networks that doesn’t use force-directed principles. Instead, it draws the edge from one node to another as arcs above or below the nodes. Weight is indicated by edge thickness and directionality is indicated by the arc being above or below the nodes.
<html xmlns="//www.w3.org/1999/xhtml">
<head>
<title>D3 in Action Arc Diagram</title>
<meta charset="utf-8" />
</head>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/queue.v1.min.js" type="text/javascript"></script>
<style>
.tick line {
shape-rendering: crispEdges;
stroke: #000;
}
line.minor {
stroke: #777;
stroke-dasharray: 2,2;
}
path.domain {
fill: none;
stroke: black;
}
</style>
<body onload="arcDiagram()">
<div id="vizcontainer">
<svg style="width:500px;height:500px;border:1px lightgray solid;" />
</div>
<footer>
<script>
function arcDiagram() {
queue()
.defer(d3.csv, "nodelist.csv")
.defer(d3.csv, "edgelist.csv")
.await(function(error, file1, file2) { createArcDiagram(file1, file2); });
function createArcDiagram(nodes,edges) {
expEdges = edges;
expNodes = nodes;
var nodeHash = {};
for (x in nodes) {
nodeHash[nodes[x].id] = nodes[x];
nodes[x].x = parseInt(x) * 50;
}
for (x in edges) {
edges[x].source = nodeHash[edges[x].source];
edges[x].target = nodeHash[edges[x].target];
}
var arcG = d3.select("svg").append("g").attr("id", "arcG").attr("transform", "translate(50,250)");
arcG.selectAll("path")
.data(edges)
.enter()
.append("path")
.style("stroke", "black")
.style("stroke-width", function(d) {return d.weight * 2})
.style("opacity", .25)
.style("fill", "none")
.attr("d", arc)
.on("mouseover", edgeOver)
arcG.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", 10)
.style("fill", "lightgray")
.style("stroke", "black")
.style("stroke-width", "1px")
.attr("cx", function (d) {return d.x})
.on("mouseover", nodeOver)
function arc(d,i) {
var draw = d3.svg.line().interpolate("basis");
var midX = (d.source.x + d.target.x) / 2;
var midY = d.source.x - d.target.x;
return draw([[d.source.x,0],[midX,midY],[d.target.x,0]])
}
function nodeOver(d,i) {
d3.selectAll("circle").style("fill", function (p) {return p == d ? "red" : "lightgray"})
d3.selectAll("path").style("stroke", function (p) {return p.source == d || p.target == d ? "red" : "black"})
}
function edgeOver(d) {
d3.selectAll("path").style("stroke", function(p) {return p == d ? "red" : "black"})
d3.selectAll("circle").style("fill", function(p) {return p == d.source ? "blue" : p == d.target ? "green" : "lightgray"})}
}
}
</script>
</footer>
</body>
</html>
source,target,weight
sam,tully,3
sam,pat,8
sam,kim,2
sam,pris,1
roy,pris,5
roy,sam,1
tully,sam,1
tully,pris,5
tully,kim,3
tully,pat,1
tully,mo,3
kim,pat,2
kim,mo,1
mo,tully,7
mo,pat,1
mo,sam,4
mo,pris,1
pat,sam,3
pat,tully,1
pat,kim,2
pat,mo,5
id,followers,following
sam,17,500
roy,83,80
pris,904,15
tully,7,5
kim,11,50
mo,80,85
pat,150,300