弦图是一种用于描述节点之间联系的图表。
我们通过一个制作一个弦图来讲解弦布局。
var city_name = ["北京", "上海", "广州", "深圳", "香港"];
var population = [
[1000, 3045, 4567, 1234, 3714],
[3214, 2000, 2060, 124, 3234],
[8761, 6545, 3000, 8045, 647],
[3211, 1067, 3214, 4000, 1006],
[2146, 1034, 6745, 4764, 5000]
];
数据是一些城市名和一些数字,这些数字表示城市人口的来源,用表格表示如下:
北京 | 上海 | 广州 | 深圳 | 香港 | |
---|---|---|---|---|---|
北京 | 1000 | 3045 | 4567 | 1234 | 3714 |
上海 | 3214 | 2000 | 2060 | 124 | 3234 |
广州 | 8761 | 6545 | 3000 | 8045 | 647 |
深圳 | 3211 | 1067 | 3214 | 4000 | 1006 |
香港 | 2146 | 1034 | 6745 | 4764 | 5000 |
左边第一列是被统计人口的城市,上边第一行是被统计的来源城市
var chord_layout = d3.layout.chord()
.padding(0.03) //节点之间的间隔
.matrix(population); //输入矩阵
var groups = chord_layout.groups();
var chords = chord_layout.chords();
population 经过转换后,实际上分成了两部分:groups 和 chords。前者是节点,后者是连线,也就是弦。
通过弦布局转换数据后,数据被转换成如下形式:
var width = 600;
var height = 600;
var innerRadius = width / 2 * 0.7;
var outerRadius = innerRadius * 1.1;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color20 = d3.scale.category20();
var outer_arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var g_outer = svg.append("g");
g_outer.selectAll("path")
.data(groups)
.enter()
.append("path")
.style("fill", function(d) {
return color20(d.index);
})
.style("stroke", function(d) {
return color20(d.index);
})
.attr("d", outer_arc);
g_outer.selectAll("text")
.data(groups)
.enter()
.append("text")
.each(function(d, i) {
d.angle = (d.startAngle + d.endAngle) / 2;
d.name = city_name[i];
})
.attr("dy", ".35em")
.attr("transform", function(d) {
return "rotate(" + (d.angle * 180 / Math.PI) + ")" +
"translate(0," + -1.0 * (outerRadius + 10) + ")" +
((d.angle > Math.PI * 3 / 4 && d.angle < Math.PI * 5 / 4) ? "rotate(180)" : "");
})
.text(function(d) {
return d.name;
});
var inner_chord = d3.svg.chord()
.radius(innerRadius);
svg.append("g")
.attr("class", "chord")
.selectAll("path")
.data(chords)
.enter()
.append("path")
.attr("d", inner_chord)
.style("fill", function(d) {
return color20(d.source.index);
})
.style("opacity", 1)
.on("mouseover", function(d, i) {
d3.select(this)
.style("fill", "yellow");
})
.on("mouseout", function(d, i) {
d3.select(this)
.transition()
.duration(1000)
.style("fill", color20(d.source.index));
});
查看在线演示