| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- // https://d3js.org/d3-chord/ v1.0.6 Copyright 2018 Mike Bostock
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-path')) :
- typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'd3-path'], factory) :
- (factory((global.d3 = global.d3 || {}),global.d3,global.d3));
- }(this, (function (exports,d3Array,d3Path) { 'use strict';
- var cos = Math.cos;
- var sin = Math.sin;
- var pi = Math.PI;
- var halfPi = pi / 2;
- var tau = pi * 2;
- var max = Math.max;
- function compareValue(compare) {
- return function(a, b) {
- return compare(
- a.source.value + a.target.value,
- b.source.value + b.target.value
- );
- };
- }
- function chord() {
- var padAngle = 0,
- sortGroups = null,
- sortSubgroups = null,
- sortChords = null;
- function chord(matrix) {
- var n = matrix.length,
- groupSums = [],
- groupIndex = d3Array.range(n),
- subgroupIndex = [],
- chords = [],
- groups = chords.groups = new Array(n),
- subgroups = new Array(n * n),
- k,
- x,
- x0,
- dx,
- i,
- j;
- // Compute the sum.
- k = 0, i = -1; while (++i < n) {
- x = 0, j = -1; while (++j < n) {
- x += matrix[i][j];
- }
- groupSums.push(x);
- subgroupIndex.push(d3Array.range(n));
- k += x;
- }
- // Sort groups…
- if (sortGroups) groupIndex.sort(function(a, b) {
- return sortGroups(groupSums[a], groupSums[b]);
- });
- // Sort subgroups…
- if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
- d.sort(function(a, b) {
- return sortSubgroups(matrix[i][a], matrix[i][b]);
- });
- });
- // Convert the sum to scaling factor for [0, 2pi].
- // TODO Allow start and end angle to be specified?
- // TODO Allow padding to be specified as percentage?
- k = max(0, tau - padAngle * n) / k;
- dx = k ? padAngle : tau / n;
- // Compute the start and end angle for each group and subgroup.
- // Note: Opera has a bug reordering object literal properties!
- 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[dj * n + di] = {
- index: di,
- subindex: dj,
- startAngle: a0,
- endAngle: a1,
- value: v
- };
- }
- groups[di] = {
- index: di,
- startAngle: x0,
- endAngle: x,
- value: groupSums[di]
- };
- x += dx;
- }
- // Generate chords for each (non-empty) subgroup-subgroup link.
- i = -1; while (++i < n) {
- j = i - 1; while (++j < n) {
- var source = subgroups[j * n + i],
- target = subgroups[i * n + j];
- if (source.value || target.value) {
- chords.push(source.value < target.value
- ? {source: target, target: source}
- : {source: source, target: target});
- }
- }
- }
- return sortChords ? chords.sort(sortChords) : chords;
- }
- chord.padAngle = function(_) {
- return arguments.length ? (padAngle = max(0, _), chord) : padAngle;
- };
- chord.sortGroups = function(_) {
- return arguments.length ? (sortGroups = _, chord) : sortGroups;
- };
- chord.sortSubgroups = function(_) {
- return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
- };
- chord.sortChords = function(_) {
- return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
- };
- return chord;
- }
- var slice = Array.prototype.slice;
- function constant(x) {
- return function() {
- return x;
- };
- }
- function defaultSource(d) {
- return d.source;
- }
- function defaultTarget(d) {
- return d.target;
- }
- function defaultRadius(d) {
- return d.radius;
- }
- function defaultStartAngle(d) {
- return d.startAngle;
- }
- function defaultEndAngle(d) {
- return d.endAngle;
- }
- function ribbon() {
- var source = defaultSource,
- target = defaultTarget,
- radius = defaultRadius,
- startAngle = defaultStartAngle,
- endAngle = defaultEndAngle,
- context = null;
- function ribbon() {
- var buffer,
- argv = slice.call(arguments),
- s = source.apply(this, argv),
- t = target.apply(this, argv),
- sr = +radius.apply(this, (argv[0] = s, argv)),
- sa0 = startAngle.apply(this, argv) - halfPi,
- sa1 = endAngle.apply(this, argv) - halfPi,
- sx0 = sr * cos(sa0),
- sy0 = sr * sin(sa0),
- tr = +radius.apply(this, (argv[0] = t, argv)),
- ta0 = startAngle.apply(this, argv) - halfPi,
- ta1 = endAngle.apply(this, argv) - halfPi;
- if (!context) context = buffer = d3Path.path();
- context.moveTo(sx0, sy0);
- context.arc(0, 0, sr, sa0, sa1);
- if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
- context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
- context.arc(0, 0, tr, ta0, ta1);
- }
- context.quadraticCurveTo(0, 0, sx0, sy0);
- context.closePath();
- if (buffer) return context = null, buffer + "" || null;
- }
- ribbon.radius = function(_) {
- return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), ribbon) : radius;
- };
- ribbon.startAngle = function(_) {
- return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), ribbon) : startAngle;
- };
- ribbon.endAngle = function(_) {
- return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), ribbon) : endAngle;
- };
- ribbon.source = function(_) {
- return arguments.length ? (source = _, ribbon) : source;
- };
- ribbon.target = function(_) {
- return arguments.length ? (target = _, ribbon) : target;
- };
- ribbon.context = function(_) {
- return arguments.length ? ((context = _ == null ? null : _), ribbon) : context;
- };
- return ribbon;
- }
- exports.chord = chord;
- exports.ribbon = ribbon;
- Object.defineProperty(exports, '__esModule', { value: true });
- })));
|