source: Dev/trunk/d3/src/layout/chord.js @ 76

Last change on this file since 76 was 76, checked in by fpvanagthoven, 14 years ago

d3

File size: 3.3 KB
Line 
1d3.layout.chord = function() {
2  var chord = {},
3      chords,
4      groups,
5      matrix,
6      n,
7      padding = 0,
8      sortGroups,
9      sortSubgroups,
10      sortChords;
11
12  function relayout() {
13    var subgroups = {},
14        groupSums = [],
15        groupIndex = d3.range(n),
16        subgroupIndex = [],
17        k,
18        x,
19        x0,
20        i,
21        j;
22
23    chords = [];
24    groups = [];
25
26    // Compute the sum.
27    k = 0, i = -1; while (++i < n) {
28      x = 0, j = -1; while (++j < n) {
29        x += matrix[i][j];
30      }
31      groupSums.push(x);
32      subgroupIndex.push(d3.range(n));
33      k += x;
34    }
35
36    // Sort groups

37    if (sortGroups) {
38      groupIndex.sort(function(a, b) {
39        return sortGroups(groupSums[a], groupSums[b]);
40      });
41    }
42
43    // Sort subgroups

44    if (sortSubgroups) {
45      subgroupIndex.forEach(function(d, i) {
46        d.sort(function(a, b) {
47          return sortSubgroups(matrix[i][a], matrix[i][b]);
48        });
49      });
50    }
51
52    // Convert the sum to scaling factor for [0, 2pi].
53    // TODO Allow start and end angle to be specified.
54    // TODO Allow padding to be specified as percentage?
55    k = (2 * Math.PI - padding * n) / k;
56
57    // Compute the start and end angle for each group and subgroup.
58    x = 0, i = -1; while (++i < n) {
59      x0 = x, j = -1; while (++j < n) {
60        var di = groupIndex[i],
61            dj = subgroupIndex[i][j],
62            v = matrix[di][dj];
63        subgroups[di + "-" + dj] = {
64          index: di,
65          subindex: dj,
66          startAngle: x,
67          endAngle: x += v * k,
68          value: v
69        };
70      }
71      groups.push({
72        index: di,
73        startAngle: x0,
74        endAngle: x,
75        value: (x - x0) / k
76      });
77      x += padding;
78    }
79
80    // Generate chords for each (non-empty) subgroup-subgroup link.
81    i = -1; while (++i < n) {
82      j = i - 1; while (++j < n) {
83        var source = subgroups[i + "-" + j],
84            target = subgroups[j + "-" + i];
85        if (source.value || target.value) {
86          chords.push(source.value < target.value
87              ? {source: target, target: source}
88              : {source: source, target: target})
89        }
90      }
91    }
92
93    if (sortChords) resort();
94  }
95
96  function resort() {
97    chords.sort(function(a, b) {
98      return sortChords(a.target.value, b.target.value);
99    });
100  }
101
102  chord.matrix = function(x) {
103    if (!arguments.length) return matrix;
104    n = (matrix = x) && matrix.length;
105    chords = groups = null;
106    return chord;
107  };
108
109  chord.padding = function(x) {
110    if (!arguments.length) return padding;
111    padding = x;
112    chords = groups = null;
113    return chord;
114  };
115
116  chord.sortGroups = function(x) {
117    if (!arguments.length) return sortGroups;
118    sortGroups = x;
119    chords = groups = null;
120    return chord;
121  };
122
123  chord.sortSubgroups = function(x) {
124    if (!arguments.length) return sortSubgroups;
125    sortSubgroups = x;
126    chords = null;
127    return chord;
128  };
129
130  chord.sortChords = function(x) {
131    if (!arguments.length) return sortChords;
132    sortChords = x;
133    if (chords) resort();
134    return chord;
135  };
136
137  chord.chords = function() {
138    if (!chords) relayout();
139    return chords;
140  };
141
142  chord.groups = function() {
143    if (!groups) relayout();
144    return groups;
145  };
146
147  return chord;
148};
Note: See TracBrowser for help on using the repository browser.