d3.layout.chord()
弦图是一种用于描述节点之间联系的图表。
弦图(Chord)的API说明
- chord.chords - 取回计算的弦角度。
- chord.groups - 取回计算的分组角度。
- chord.matrix - 取得或设置布局需要的矩阵数据。
- chord.padding - 取得或设置弦片段间的角填充。
- chord.sortChords - 取得或设置用于弦的比较器(Z轴顺序)。
- chord.sortGroups - 取得或设置用于分组的比较器。
- chord.sortSubgroups - 取得或设置用于子分组的比较器。
我们通过一个制作一个弦图来讲解弦布局。
1. 数据
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 |
左边第一列是被统计人口的城市,上边第一行是被统计的来源城市
2. 数据转换
var chord_layout = d3.layout.chord()
.padding(0.03) //节点之间的间隔
.matrix(population); //输入矩阵
var groups = chord_layout.groups();
var chords = chord_layout.chords();
population 经过转换后,实际上分成了两部分:groups 和 chords。前者是节点,后者是连线,也就是弦。
通过弦布局转换数据后,数据被转换成如下形式:
节点
连线
3. 绘制图形
绘制容器
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();
创建圆弧SVG生成器
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;
});
创建弦图SVG生成器
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));
});