source: node_modules/d3-chord/src/chord.js@ e4c61dd

Last change on this file since e4c61dd was e4c61dd, checked in by istevanoska <ilinastevanoska@…>, 6 months ago

Prototype 1.1

  • Property mode set to 100644
File size: 4.3 KB
Line 
1import {max, tau} from "./math.js";
2
3function range(i, j) {
4 return Array.from({length: j - i}, (_, k) => i + k);
5}
6
7function compareValue(compare) {
8 return function(a, b) {
9 return compare(
10 a.source.value + a.target.value,
11 b.source.value + b.target.value
12 );
13 };
14}
15
16export default function() {
17 return chord(false, false);
18}
19
20export function chordTranspose() {
21 return chord(false, true);
22}
23
24export function chordDirected() {
25 return chord(true, false);
26}
27
28function chord(directed, transpose) {
29 var padAngle = 0,
30 sortGroups = null,
31 sortSubgroups = null,
32 sortChords = null;
33
34 function chord(matrix) {
35 var n = matrix.length,
36 groupSums = new Array(n),
37 groupIndex = range(0, n),
38 chords = new Array(n * n),
39 groups = new Array(n),
40 k = 0, dx;
41
42 matrix = Float64Array.from({length: n * n}, transpose
43 ? (_, i) => matrix[i % n][i / n | 0]
44 : (_, i) => matrix[i / n | 0][i % n]);
45
46 // Compute the scaling factor from value to angle in [0, 2pi].
47 for (let i = 0; i < n; ++i) {
48 let x = 0;
49 for (let j = 0; j < n; ++j) x += matrix[i * n + j] + directed * matrix[j * n + i];
50 k += groupSums[i] = x;
51 }
52 k = max(0, tau - padAngle * n) / k;
53 dx = k ? padAngle : tau / n;
54
55 // Compute the angles for each group and constituent chord.
56 {
57 let x = 0;
58 if (sortGroups) groupIndex.sort((a, b) => sortGroups(groupSums[a], groupSums[b]));
59 for (const i of groupIndex) {
60 const x0 = x;
61 if (directed) {
62 const subgroupIndex = range(~n + 1, n).filter(j => j < 0 ? matrix[~j * n + i] : matrix[i * n + j]);
63 if (sortSubgroups) subgroupIndex.sort((a, b) => sortSubgroups(a < 0 ? -matrix[~a * n + i] : matrix[i * n + a], b < 0 ? -matrix[~b * n + i] : matrix[i * n + b]));
64 for (const j of subgroupIndex) {
65 if (j < 0) {
66 const chord = chords[~j * n + i] || (chords[~j * n + i] = {source: null, target: null});
67 chord.target = {index: i, startAngle: x, endAngle: x += matrix[~j * n + i] * k, value: matrix[~j * n + i]};
68 } else {
69 const chord = chords[i * n + j] || (chords[i * n + j] = {source: null, target: null});
70 chord.source = {index: i, startAngle: x, endAngle: x += matrix[i * n + j] * k, value: matrix[i * n + j]};
71 }
72 }
73 groups[i] = {index: i, startAngle: x0, endAngle: x, value: groupSums[i]};
74 } else {
75 const subgroupIndex = range(0, n).filter(j => matrix[i * n + j] || matrix[j * n + i]);
76 if (sortSubgroups) subgroupIndex.sort((a, b) => sortSubgroups(matrix[i * n + a], matrix[i * n + b]));
77 for (const j of subgroupIndex) {
78 let chord;
79 if (i < j) {
80 chord = chords[i * n + j] || (chords[i * n + j] = {source: null, target: null});
81 chord.source = {index: i, startAngle: x, endAngle: x += matrix[i * n + j] * k, value: matrix[i * n + j]};
82 } else {
83 chord = chords[j * n + i] || (chords[j * n + i] = {source: null, target: null});
84 chord.target = {index: i, startAngle: x, endAngle: x += matrix[i * n + j] * k, value: matrix[i * n + j]};
85 if (i === j) chord.source = chord.target;
86 }
87 if (chord.source && chord.target && chord.source.value < chord.target.value) {
88 const source = chord.source;
89 chord.source = chord.target;
90 chord.target = source;
91 }
92 }
93 groups[i] = {index: i, startAngle: x0, endAngle: x, value: groupSums[i]};
94 }
95 x += dx;
96 }
97 }
98
99 // Remove empty chords.
100 chords = Object.values(chords);
101 chords.groups = groups;
102 return sortChords ? chords.sort(sortChords) : chords;
103 }
104
105 chord.padAngle = function(_) {
106 return arguments.length ? (padAngle = max(0, _), chord) : padAngle;
107 };
108
109 chord.sortGroups = function(_) {
110 return arguments.length ? (sortGroups = _, chord) : sortGroups;
111 };
112
113 chord.sortSubgroups = function(_) {
114 return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
115 };
116
117 chord.sortChords = function(_) {
118 return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
119 };
120
121 return chord;
122}
Note: See TracBrowser for help on using the repository browser.