source: Dev/branches/jQueryUI/client/d3/src/layout/stack.js @ 249

Last change on this file since 249 was 249, checked in by hendrikvanantwerpen, 13 years ago

This one's for Subversion, because it's so close...

First widget (stripped down sequencer).
Seperated client and server code in two direcotry trees.

File size: 5.1 KB
Line 
1// data is two-dimensional array of x,y; we populate y0
2d3.layout.stack = function() {
3  var values = Object,
4      order = d3_layout_stackOrders["default"],
5      offset = d3_layout_stackOffsets["zero"],
6      out = d3_layout_stackOut,
7      x = d3_layout_stackX,
8      y = d3_layout_stackY;
9
10  function stack(data, index) {
11
12    // Convert series to canonical two-dimensional representation.
13    var series = data.map(function(d, i) {
14      return values.call(stack, d, i);
15    });
16
17    // Convert each series to canonical [[x,y]] representation.
18    var points = series.map(function(d, i) {
19      return d.map(function(v, i) {
20        return [x.call(stack, v, i), y.call(stack, v, i)];
21      });
22    });
23
24    // Compute the order of series, and permute them.
25    var orders = order.call(stack, points, index);
26    series = d3.permute(series, orders);
27    points = d3.permute(points, orders);
28
29    // Compute the baseline

30    var offsets = offset.call(stack, points, index);
31
32    // And propagate it to other series.
33    var n = series.length,
34        m = series[0].length,
35        i,
36        j,
37        o;
38    for (j = 0; j < m; ++j) {
39      out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
40      for (i = 1; i < n; ++i) {
41        out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
42      }
43    }
44
45    return data;
46  }
47
48  stack.values = function(x) {
49    if (!arguments.length) return values;
50    values = x;
51    return stack;
52  };
53
54  stack.order = function(x) {
55    if (!arguments.length) return order;
56    order = typeof x === "function" ? x : d3_layout_stackOrders[x];
57    return stack;
58  };
59
60  stack.offset = function(x) {
61    if (!arguments.length) return offset;
62    offset = typeof x === "function" ? x : d3_layout_stackOffsets[x];
63    return stack;
64  };
65
66  stack.x = function(z) {
67    if (!arguments.length) return x;
68    x = z;
69    return stack;
70  };
71
72  stack.y = function(z) {
73    if (!arguments.length) return y;
74    y = z;
75    return stack;
76  };
77
78  stack.out = function(z) {
79    if (!arguments.length) return out;
80    out = z;
81    return stack;
82  };
83
84  return stack;
85}
86
87function d3_layout_stackX(d) {
88  return d.x;
89}
90
91function d3_layout_stackY(d) {
92  return d.y;
93}
94
95function d3_layout_stackOut(d, y0, y) {
96  d.y0 = y0;
97  d.y = y;
98}
99
100var d3_layout_stackOrders = {
101
102  "inside-out": function(data) {
103    var n = data.length,
104        i,
105        j,
106        max = data.map(d3_layout_stackMaxIndex),
107        sums = data.map(d3_layout_stackReduceSum),
108        index = d3.range(n).sort(function(a, b) { return max[a] - max[b]; }),
109        top = 0,
110        bottom = 0,
111        tops = [],
112        bottoms = [];
113    for (i = 0; i < n; ++i) {
114      j = index[i];
115      if (top < bottom) {
116        top += sums[j];
117        tops.push(j);
118      } else {
119        bottom += sums[j];
120        bottoms.push(j);
121      }
122    }
123    return bottoms.reverse().concat(tops);
124  },
125
126  "reverse": function(data) {
127    return d3.range(data.length).reverse();
128  },
129
130  "default": function(data) {
131    return d3.range(data.length);
132  }
133
134};
135
136var d3_layout_stackOffsets = {
137
138  "silhouette": function(data) {
139    var n = data.length,
140        m = data[0].length,
141        sums = [],
142        max = 0,
143        i,
144        j,
145        o,
146        y0 = [];
147    for (j = 0; j < m; ++j) {
148      for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
149      if (o > max) max = o;
150      sums.push(o);
151    }
152    for (j = 0; j < m; ++j) {
153      y0[j] = (max - sums[j]) / 2;
154    }
155    return y0;
156  },
157
158  "wiggle": function(data) {
159    var n = data.length,
160        x = data[0],
161        m = x.length,
162        max = 0,
163        i,
164        j,
165        k,
166        s1,
167        s2,
168        s3,
169        dx,
170        o,
171        o0,
172        y0 = [];
173    y0[0] = o = o0 = 0;
174    for (j = 1; j < m; ++j) {
175      for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
176      for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
177        for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
178          s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
179        }
180        s2 += s3 * data[i][j][1];
181      }
182      y0[j] = o -= s1 ? s2 / s1 * dx : 0;
183      if (o < o0) o0 = o;
184    }
185    for (j = 0; j < m; ++j) y0[j] -= o0;
186    return y0;
187  },
188
189  "expand": function(data) {
190    var n = data.length,
191        m = data[0].length,
192        k = 1 / n,
193        i,
194        j,
195        o,
196        y0 = [];
197    for (j = 0; j < m; ++j) {
198      for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
199      if (o) for (i = 0; i < n; i++) data[i][j][1] /= o;
200      else for (i = 0; i < n; i++) data[i][j][1] = k;
201    }
202    for (j = 0; j < m; ++j) y0[j] = 0;
203    return y0;
204  },
205
206  "zero": function(data) {
207    var j = -1,
208        m = data[0].length,
209        y0 = [];
210    while (++j < m) y0[j] = 0;
211    return y0;
212  }
213
214};
215
216function d3_layout_stackMaxIndex(array) {
217  var i = 1,
218      j = 0,
219      v = array[0][1],
220      k,
221      n = array.length;
222  for (; i < n; ++i) {
223    if ((k = array[i][1]) > v) {
224      j = i;
225      v = k;
226    }
227  }
228  return j;
229}
230
231function d3_layout_stackReduceSum(d) {
232  return d.reduce(d3_layout_stackSum, 0);
233}
234
235function d3_layout_stackSum(p, d) {
236  return p + d[1];
237}
Note: See TracBrowser for help on using the repository browser.