### Description

Arc Diagram 是二维 Network Diagram 的一种特殊表现形式，所有的结点都在一条直线上。结点之间使用弧线来表示他们之间有关联，而关联的紧密程度可以通过弧线的粗细来表示。
Arc Diagram 可以用于发现数据之间的共现关系。

### Generate by D3

CSS:

.node {
stroke: #ffffff;
stroke-weight: 1px;
fill: #99cc99;
}

fill: none;
stroke: #6699cc;
stroke-weight: 1px;
stroke-opacity: 0.5;
}

.axis {
stroke: #9c9;
stroke-width: 2px;
}


Javascript:

/* GLOBALS */
var width  = 960;           // width of svg image
var height = 250;           // height of svg image
var margin = 20;            // amount of margin around plot area
var yfixed = pad + radius;  // y position for all nodes

/* MAIN DRAW METHOD */
// Draws an arc diagram for the provided undirected graph
function arcDiagram(graph) {
// create svg image
var svg  = d3.select("body")
.append("svg")
.attr("id", "arc")
.attr("width", width)
.attr("height", height);

// create plot area within svg image
var plot = svg.append("g")
.attr("id", "plot")

d.source = isNaN(d.source) ? d.source : graph.nodes[d.source];
d.target = isNaN(d.target) ? d.target : graph.nodes[d.target];
});

// must be done AFTER links are fixed
linearLayout(graph.nodes);

// draw links first, so nodes appear on top

// draw nodes last
drawNodes(graph.nodes);
}

// Layout nodes linearly, sorted by group
function linearLayout(nodes) {
// used to scale node index to x position
var xscale = d3.scaleLinear()
.domain([0, nodes.length - 1])
.range([0, width / 2]);

// calculate pixel location for each node
nodes.forEach(function(d, i) {
d.x = xscale(i);
d.y = yfixed;
});
}

// Draws nodes on plot
function drawNodes(nodes) {
d3.select("#plot")
.append("line")
.attr("class", "axis")
.attr("x1", 0)
.attr("y1", height - yfixed)
.attr("x2", width / 2)
.attr("y2", height - yfixed);

d3.select("#plot").selectAll(".node")
.data(nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("id", function(d, i) { return d.name; })
.attr("cx", function(d, i) { return d.x; })
.attr("cy", function(d, i) { return height - d.y; })
.attr("r", function(d, i) { return radius; });
}

// Draws nice arcs for each link on plot
// scale to generate radians (just for lower-half of circle)
.range([-Math.PI / 2, Math.PI / 2]);

// path generator for arcs (uses polar coordinates)
.curve(d3.curveBasis)

.enter()
.append("path")
.attr("stroke-width", function(d, i) {
return d.value
})
.attr("transform", function(d, i) {
// arc will always be drawn around (0, 0)
// shift so (0, 0) will be between source and target
var xshift = d.source.x + (d.target.x - d.source.x) / 2;
var yshift = height - yfixed;
return "translate(" + xshift + ", " + yshift + ")";
})
.attr("d", function(d, i) {
// get x distance between source and target
var xdist = Math.abs(d.source.x - d.target.x);
// set arc radius based on x distance
// want to generate 1/3 as many points per pixel in x direction
var points = d3.range(0, Math.ceil(xdist / 3));
// return path for arc
return arc(points);
});
}

d3.json("arc.json", arcDiagram);


Data:

{
"nodes":[
{"name":"Node A"},
{"name":"Node B"},
{"name":"Node C"}
],