【D3.js 学习总结】11、D3布局-弦图

d3.layout.chord()

弦图是一种用于描述节点之间联系的图表。

弦图(Chord)的API说明

  • chord.chords - 取回计算的弦角度。
  • chord.groups - 取回计算的分组角度。
  • chord.matrix - 取得或设置布局需要的矩阵数据。
  • chord.padding - 取得或设置弦片段间的角填充。
  • chord.sortChords - 取得或设置用于弦的比较器(Z轴顺序)。
  • chord.sortGroups - 取得或设置用于分组的比较器。
  • chord.sortSubgroups - 取得或设置用于子分组的比较器。

我们通过一个制作一个弦图来讲解弦布局。

【D3.js 学习总结】11、D3布局-弦图

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。前者是节点,后者是连线,也就是弦。

通过弦布局转换数据后,数据被转换成如下形式:

节点
【D3.js 学习总结】11、D3布局-弦图

连线
【D3.js 学习总结】11、D3布局-弦图

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));
    });

查看在线演示

上一篇:【D3.js 学习总结】10、D3布局-力学图


下一篇:【D3.js 学习总结】16、D3布局-矩阵图