源码:
var τ = 2 * Math.PI;
d3.layout.chord = function() { var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; function relayout() { var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; chords = []; groups = []; k = 0, i = -1; while (++i < n) { x = 0, j = -1; while (++j < n) { x += matrix[i][j]; } groupSums.push(x); subgroupIndex.push(d3.range(n)); k += x; } if (sortGroups) { groupIndex.sort(function(a, b) { return sortGroups(groupSums[a], groupSums[b]); }); } if (sortSubgroups) { subgroupIndex.forEach(function(d, i) { d.sort(function(a, b) { return sortSubgroups(matrix[i][a], matrix[i][b]); }); }); } //k运算之前为matrix的所有取值的和,运算之后为单位1数字所表示的角度值 k = (τ - padding * n) / k; x = 0, i = -1; while (++i < n) { x0 = x, j = -1; while (++j < n) { var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; subgroups[di + "-" + dj] = { index: di, subindex: dj, startAngle: a0, endAngle: a1, value: v }; } groups[di] = { index: di, startAngle: x0, endAngle: x, value: (x - x0) / k }; x += padding; } i = -1; while (++i < n) { j = i - 1; while (++j < n) { var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; if (source.value || target.value) { chords.push(source.value < target.value ? { source: target, target: source } : { source: source, target: target }); } } } if (sortChords) resort(); } function resort() { chords.sort(function(a, b) { return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); }); } chord.matrix = function(x) { if (!arguments.length) return matrix; n = (matrix = x) && matrix.length; chords = groups = null; return chord; }; chord.padding = function(x) { if (!arguments.length) return padding; padding = x; chords = groups = null; return chord; }; chord.sortGroups = function(x) { if (!arguments.length) return sortGroups; sortGroups = x; chords = groups = null; return chord; }; chord.sortSubgroups = function(x) { if (!arguments.length) return sortSubgroups; sortSubgroups = x; chords = null; return chord; }; chord.sortChords = function(x) { if (!arguments.length) return sortChords; sortChords = x; if (chords) resort(); return chord; }; chord.chords = function() { if (!chords) relayout(); return chords; }; chord.groups = function() { if (!groups) relayout(); return groups; }; return chord; };
d3.layout.chord()
构建新的弦布局。在默认情况下,输入数据并未分类,并且各群组之间没有填充。和其他布局不同,该弦布局并不是应用于数据的函数;相反,数据通过设置关联矩阵来指定,通过chords和groups访问器检索。
chord.matrix([matrix])
指定矩阵之后,设定该布局用到的输入数据矩阵。如果没有指定矩阵,返回当前数据矩阵,默认为未定义。输入矩阵的数字必须为“方形矩阵” :[[11975,5871,8916,2868], [1951,10048,2060,6171], [8010,16145,8090,8045], [1013,990,940,6907]]
矩阵的每一行对应一个特定分组,如上文所述某个发色。矩阵中每一列i同第i行相对应;每个单元格ij对应表示第i组到第j组之间的关系。
chord.padding([padding])
If padding is specified, sets the angular padding between groups to the specified value inradians. If padding is not specified, returns the current padding, which defaults to zero. You may wish to compute the padding as a function of the number of groups (the number of rows or columns in the associated matrix). 指定填充之后,在不同组之间设定角度填充,为指定的值(弧度为单位)。如果没有指定填充,返回当前填充,默认值为0。你可能希望计算填充是分组数量(关联矩阵中行和列的数量)的函数。
chord.sortGroups([comparator])
如果已经指定comparator,使用指定comparator函数为布局设定分组(行)的排列顺序。为每两行调用comparator函数,传递的入参是行i和行j的总和。通常,需要将comparator按照d3.ascending或d3.descending进行指定。如果没有指定comparator,则返回当前分组排列顺序,该顺序默认值为空。
chord.sortSubgroups([comparator])
如果已经指定comparator,使用指定comparator函数为布局设定分组(行内各列)的排列顺序。为每对单元格调用comparator函数,值为各单元格的值。通常,需要将comparator以升序或降序进行指定。如果没有指定comparator,则回当前子分组排列顺序,该顺序默认值为空。
chord.sortChords([comparator])
如果已经指定comparator,运用指定comparator函数为弦布局设定弦(Z顺序)的排列顺序。为每两条弦调用comparator函数,入参为源单元格和目标单元格的最小值。通常,要将comparator以升序或降序进行指定。如果没有指定comparator,返回当前chord排列顺序,默认值为空。
chord.chords()
给定布局的当前配置和关联矩阵,返回计算过的弦对象。如果弦对象已计算完毕,本方法返回缓存值。如果布局属性有任何改变,则清空之前计算的弦。此时,如果下次调用该方法,需要对布局进行重新计算。返回对象具有下列属性: ? source -描述源对象。 ? target -描述目标对象。 这两个对象描述下列实体: ? index -行索引,i。 ? subindex索引-列索引,j。 ? startAngle-弧的起始角,在radians内。 ? endAngle-弧的终止角,在radians内。 ? value -关联单元格ij的数值。 需要注意的是,这些对象同弦很方便为弦生成器匹配默认的访问器;但仍可以对访问器进行重写或者修改返回对象,实现布局微调。
chord.groups()
给定布局的当前配置和关联矩阵,返回计算过的分组对象。如果分组对象已计算完毕,本方法返回缓存值。如果布局属性有任何改变,则清空之前计算的分组。此时,如果下次调用该方法,需要对布局进行重新计算。返回对象具有下列属性: ? index -行索引,i。 ? startAngle -弧的起始角,在radians内。 ? endAngle -弧的终止角,在radians内。 ? value -相关行 i的值的总和。 需要注意的是,这些对象同弧度生成器的默认访问器具有较好的吻合度;但仍可以对访问器进行重写或者修改返回对象,实现布局微调。