d3_rails 2.10.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.DS_Store +0 -0
  2. data/README.md +11 -39
  3. data/lib/.DS_Store +0 -0
  4. data/lib/d3_rails/.DS_Store +0 -0
  5. data/lib/d3_rails/version.rb +1 -1
  6. data/vendor/.DS_Store +0 -0
  7. data/vendor/assets/.DS_Store +0 -0
  8. data/vendor/assets/javascripts/.DS_Store +0 -0
  9. data/vendor/assets/javascripts/d3.js +1 -4765
  10. data/vendor/assets/javascripts/d3.min.js +1 -0
  11. data/vendor/assets/javascripts/{d3.v2.js → d3.v3.js} +5585 -4802
  12. data/vendor/assets/javascripts/d3.v3.min.js +4 -0
  13. data/vendor/assets/stylesheets/.DS_Store +0 -0
  14. metadata +11 -42
  15. data/vendor/assets/javascripts/LICENSE.txt +0 -26
  16. data/vendor/assets/javascripts/colorbrewer.js +0 -32
  17. data/vendor/assets/javascripts/d3.chart.js +0 -984
  18. data/vendor/assets/javascripts/d3.geo.js +0 -938
  19. data/vendor/assets/javascripts/d3.geom.js +0 -835
  20. data/vendor/assets/javascripts/d3.layout.js +0 -1882
  21. data/vendor/assets/javascripts/d3.time.js +0 -726
  22. data/vendor/assets/javascripts/d3.v2.min.js +0 -4
  23. data/vendor/assets/javascripts/d3_csv.js +0 -92
  24. data/vendor/assets/javascripts/d3_rails.js +0 -1
  25. data/vendor/assets/javascripts/science.js +0 -225
  26. data/vendor/assets/javascripts/science.lin.js +0 -27
  27. data/vendor/assets/javascripts/science.stats.js +0 -720
  28. data/vendor/assets/stylesheets/LICENSE.txt +0 -38
  29. data/vendor/assets/stylesheets/azimuthal.css +0 -21
  30. data/vendor/assets/stylesheets/box.css +0 -4
  31. data/vendor/assets/stylesheets/bubble.css +0 -8
  32. data/vendor/assets/stylesheets/bullet.css +0 -10
  33. data/vendor/assets/stylesheets/bundle-radial.css +0 -9
  34. data/vendor/assets/stylesheets/bundle-treemap.css +0 -14
  35. data/vendor/assets/stylesheets/button.css +0 -35
  36. data/vendor/assets/stylesheets/calendar.css +0 -16
  37. data/vendor/assets/stylesheets/cartogram.css +0 -20
  38. data/vendor/assets/stylesheets/chord.css +0 -9
  39. data/vendor/assets/stylesheets/choropleth.css +0 -16
  40. data/vendor/assets/stylesheets/clock.css +0 -23
  41. data/vendor/assets/stylesheets/cluster.css +0 -15
  42. data/vendor/assets/stylesheets/colorbrewer.css +0 -1327
  43. data/vendor/assets/stylesheets/d3_rails.css +0 -6
  44. data/vendor/assets/stylesheets/force.css +0 -9
  45. data/vendor/assets/stylesheets/horizon.css +0 -9
  46. data/vendor/assets/stylesheets/kde.css +0 -9
  47. data/vendor/assets/stylesheets/line.css +0 -22
@@ -1,1882 +0,0 @@
1
- (function(){d3.layout = {};
2
- // Implements hierarchical edge bundling using Holten's algorithm. For each
3
- // input link, a path is computed that travels through the tree, up the parent
4
- // hierarchy to the least common ancestor, and then back down to the destination
5
- // node. Each path is simply an array of nodes.
6
- d3.layout.bundle = function() {
7
- return function(links) {
8
- var paths = [],
9
- i = -1,
10
- n = links.length;
11
- while (++i < n) paths.push(d3_layout_bundlePath(links[i]));
12
- return paths;
13
- };
14
- };
15
-
16
- function d3_layout_bundlePath(link) {
17
- var start = link.source,
18
- end = link.target,
19
- lca = d3_layout_bundleLeastCommonAncestor(start, end),
20
- points = [start];
21
- while (start !== lca) {
22
- start = start.parent;
23
- points.push(start);
24
- }
25
- var k = points.length;
26
- while (end !== lca) {
27
- points.splice(k, 0, end);
28
- end = end.parent;
29
- }
30
- return points;
31
- }
32
-
33
- function d3_layout_bundleAncestors(node) {
34
- var ancestors = [],
35
- parent = node.parent;
36
- while (parent != null) {
37
- ancestors.push(node);
38
- node = parent;
39
- parent = parent.parent;
40
- }
41
- ancestors.push(node);
42
- return ancestors;
43
- }
44
-
45
- function d3_layout_bundleLeastCommonAncestor(a, b) {
46
- if (a === b) return a;
47
- var aNodes = d3_layout_bundleAncestors(a),
48
- bNodes = d3_layout_bundleAncestors(b),
49
- aNode = aNodes.pop(),
50
- bNode = bNodes.pop(),
51
- sharedNode = null;
52
- while (aNode === bNode) {
53
- sharedNode = aNode;
54
- aNode = aNodes.pop();
55
- bNode = bNodes.pop();
56
- }
57
- return sharedNode;
58
- }
59
- d3.layout.chord = function() {
60
- var chord = {},
61
- chords,
62
- groups,
63
- matrix,
64
- n,
65
- padding = 0,
66
- sortGroups,
67
- sortSubgroups,
68
- sortChords;
69
-
70
- function relayout() {
71
- var subgroups = {},
72
- groupSums = [],
73
- groupIndex = d3.range(n),
74
- subgroupIndex = [],
75
- k,
76
- x,
77
- x0,
78
- i,
79
- j;
80
-
81
- chords = [];
82
- groups = [];
83
-
84
- // Compute the sum.
85
- k = 0, i = -1; while (++i < n) {
86
- x = 0, j = -1; while (++j < n) {
87
- x += matrix[i][j];
88
- }
89
- groupSums.push(x);
90
- subgroupIndex.push(d3.range(n));
91
- k += x;
92
- }
93
-
94
- // Sort groups…
95
- if (sortGroups) {
96
- groupIndex.sort(function(a, b) {
97
- return sortGroups(groupSums[a], groupSums[b]);
98
- });
99
- }
100
-
101
- // Sort subgroups…
102
- if (sortSubgroups) {
103
- subgroupIndex.forEach(function(d, i) {
104
- d.sort(function(a, b) {
105
- return sortSubgroups(matrix[i][a], matrix[i][b]);
106
- });
107
- });
108
- }
109
-
110
- // Convert the sum to scaling factor for [0, 2pi].
111
- // TODO Allow start and end angle to be specified.
112
- // TODO Allow padding to be specified as percentage?
113
- k = (2 * Math.PI - padding * n) / k;
114
-
115
- // Compute the start and end angle for each group and subgroup.
116
- // Note: Opera has a bug reordering object literal properties!
117
- x = 0, i = -1; while (++i < n) {
118
- x0 = x, j = -1; while (++j < n) {
119
- var di = groupIndex[i],
120
- dj = subgroupIndex[di][j],
121
- v = matrix[di][dj],
122
- a0 = x,
123
- a1 = x += v * k;
124
- subgroups[di + "-" + dj] = {
125
- index: di,
126
- subindex: dj,
127
- startAngle: a0,
128
- endAngle: a1,
129
- value: v
130
- };
131
- }
132
- groups.push({
133
- index: di,
134
- startAngle: x0,
135
- endAngle: x,
136
- value: (x - x0) / k
137
- });
138
- x += padding;
139
- }
140
-
141
- // Generate chords for each (non-empty) subgroup-subgroup link.
142
- i = -1; while (++i < n) {
143
- j = i - 1; while (++j < n) {
144
- var source = subgroups[i + "-" + j],
145
- target = subgroups[j + "-" + i];
146
- if (source.value || target.value) {
147
- chords.push(source.value < target.value
148
- ? {source: target, target: source}
149
- : {source: source, target: target});
150
- }
151
- }
152
- }
153
-
154
- if (sortChords) resort();
155
- }
156
-
157
- function resort() {
158
- chords.sort(function(a, b) {
159
- return sortChords(
160
- (a.source.value + a.target.value) / 2,
161
- (b.source.value + b.target.value) / 2);
162
- });
163
- }
164
-
165
- chord.matrix = function(x) {
166
- if (!arguments.length) return matrix;
167
- n = (matrix = x) && matrix.length;
168
- chords = groups = null;
169
- return chord;
170
- };
171
-
172
- chord.padding = function(x) {
173
- if (!arguments.length) return padding;
174
- padding = x;
175
- chords = groups = null;
176
- return chord;
177
- };
178
-
179
- chord.sortGroups = function(x) {
180
- if (!arguments.length) return sortGroups;
181
- sortGroups = x;
182
- chords = groups = null;
183
- return chord;
184
- };
185
-
186
- chord.sortSubgroups = function(x) {
187
- if (!arguments.length) return sortSubgroups;
188
- sortSubgroups = x;
189
- chords = null;
190
- return chord;
191
- };
192
-
193
- chord.sortChords = function(x) {
194
- if (!arguments.length) return sortChords;
195
- sortChords = x;
196
- if (chords) resort();
197
- return chord;
198
- };
199
-
200
- chord.chords = function() {
201
- if (!chords) relayout();
202
- return chords;
203
- };
204
-
205
- chord.groups = function() {
206
- if (!groups) relayout();
207
- return groups;
208
- };
209
-
210
- return chord;
211
- };
212
- // A rudimentary force layout using Gauss-Seidel.
213
- d3.layout.force = function() {
214
- var force = {},
215
- event = d3.dispatch("tick"),
216
- size = [1, 1],
217
- drag,
218
- alpha,
219
- friction = .9,
220
- linkDistance = d3_layout_forceLinkDistance,
221
- linkStrength = d3_layout_forceLinkStrength,
222
- charge = -30,
223
- gravity = .1,
224
- theta = .8,
225
- interval,
226
- nodes = [],
227
- links = [],
228
- distances,
229
- strengths,
230
- charges;
231
-
232
- function repulse(node) {
233
- return function(quad, x1, y1, x2, y2) {
234
- if (quad.point !== node) {
235
- var dx = quad.cx - node.x,
236
- dy = quad.cy - node.y,
237
- dn = 1 / Math.sqrt(dx * dx + dy * dy);
238
-
239
- /* Barnes-Hut criterion. */
240
- if ((x2 - x1) * dn < theta) {
241
- var k = quad.charge * dn * dn;
242
- node.px -= dx * k;
243
- node.py -= dy * k;
244
- return true;
245
- }
246
-
247
- if (quad.point && isFinite(dn)) {
248
- var k = quad.pointCharge * dn * dn;
249
- node.px -= dx * k;
250
- node.py -= dy * k;
251
- }
252
- }
253
- return !quad.charge;
254
- };
255
- }
256
-
257
- function tick() {
258
- // simulated annealing, basically
259
- if ((alpha *= .99) < .005) return true;
260
-
261
- var n = nodes.length,
262
- m = links.length,
263
- q,
264
- i, // current index
265
- o, // current object
266
- s, // current source
267
- t, // current target
268
- l, // current distance
269
- k, // current force
270
- x, // x-distance
271
- y; // y-distance
272
-
273
- // gauss-seidel relaxation for links
274
- for (i = 0; i < m; ++i) {
275
- o = links[i];
276
- s = o.source;
277
- t = o.target;
278
- x = t.x - s.x;
279
- y = t.y - s.y;
280
- if (l = (x * x + y * y)) {
281
- l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l;
282
- x *= l;
283
- y *= l;
284
- t.x -= x * (k = s.weight / (t.weight + s.weight));
285
- t.y -= y * k;
286
- s.x += x * (k = 1 - k);
287
- s.y += y * k;
288
- }
289
- }
290
-
291
- // apply gravity forces
292
- if (k = alpha * gravity) {
293
- x = size[0] / 2;
294
- y = size[1] / 2;
295
- i = -1; if (k) while (++i < n) {
296
- o = nodes[i];
297
- o.x += (x - o.x) * k;
298
- o.y += (y - o.y) * k;
299
- }
300
- }
301
-
302
- // compute quadtree center of mass and apply charge forces
303
- if (charge) {
304
- d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges);
305
- i = -1; while (++i < n) {
306
- if (!(o = nodes[i]).fixed) {
307
- q.visit(repulse(o));
308
- }
309
- }
310
- }
311
-
312
- // position verlet integration
313
- i = -1; while (++i < n) {
314
- o = nodes[i];
315
- if (o.fixed) {
316
- o.x = o.px;
317
- o.y = o.py;
318
- } else {
319
- o.x -= (o.px - (o.px = o.x)) * friction;
320
- o.y -= (o.py - (o.py = o.y)) * friction;
321
- }
322
- }
323
-
324
- event.tick({type: "tick", alpha: alpha});
325
- }
326
-
327
- force.nodes = function(x) {
328
- if (!arguments.length) return nodes;
329
- nodes = x;
330
- return force;
331
- };
332
-
333
- force.links = function(x) {
334
- if (!arguments.length) return links;
335
- links = x;
336
- return force;
337
- };
338
-
339
- force.size = function(x) {
340
- if (!arguments.length) return size;
341
- size = x;
342
- return force;
343
- };
344
-
345
- force.linkDistance = function(x) {
346
- if (!arguments.length) return linkDistance;
347
- linkDistance = d3.functor(x);
348
- return force;
349
- };
350
-
351
- // For backwards-compatibility.
352
- force.distance = force.linkDistance;
353
-
354
- force.linkStrength = function(x) {
355
- if (!arguments.length) return linkStrength;
356
- linkStrength = d3.functor(x);
357
- return force;
358
- };
359
-
360
- force.friction = function(x) {
361
- if (!arguments.length) return friction;
362
- friction = x;
363
- return force;
364
- };
365
-
366
- force.charge = function(x) {
367
- if (!arguments.length) return charge;
368
- charge = typeof x === "function" ? x : +x;
369
- return force;
370
- };
371
-
372
- force.gravity = function(x) {
373
- if (!arguments.length) return gravity;
374
- gravity = x;
375
- return force;
376
- };
377
-
378
- force.theta = function(x) {
379
- if (!arguments.length) return theta;
380
- theta = x;
381
- return force;
382
- };
383
-
384
- force.start = function() {
385
- var i,
386
- j,
387
- n = nodes.length,
388
- m = links.length,
389
- w = size[0],
390
- h = size[1],
391
- neighbors,
392
- o;
393
-
394
- for (i = 0; i < n; ++i) {
395
- (o = nodes[i]).index = i;
396
- o.weight = 0;
397
- }
398
-
399
- distances = [];
400
- strengths = [];
401
- for (i = 0; i < m; ++i) {
402
- o = links[i];
403
- if (typeof o.source == "number") o.source = nodes[o.source];
404
- if (typeof o.target == "number") o.target = nodes[o.target];
405
- distances[i] = linkDistance.call(this, o, i);
406
- strengths[i] = linkStrength.call(this, o, i);
407
- ++o.source.weight;
408
- ++o.target.weight;
409
- }
410
-
411
- for (i = 0; i < n; ++i) {
412
- o = nodes[i];
413
- if (isNaN(o.x)) o.x = position("x", w);
414
- if (isNaN(o.y)) o.y = position("y", h);
415
- if (isNaN(o.px)) o.px = o.x;
416
- if (isNaN(o.py)) o.py = o.y;
417
- }
418
-
419
- charges = [];
420
- if (typeof charge === "function") {
421
- for (i = 0; i < n; ++i) {
422
- charges[i] = +charge.call(this, nodes[i], i);
423
- }
424
- } else {
425
- for (i = 0; i < n; ++i) {
426
- charges[i] = charge;
427
- }
428
- }
429
-
430
- // initialize node position based on first neighbor
431
- function position(dimension, size) {
432
- var neighbors = neighbor(i),
433
- j = -1,
434
- m = neighbors.length,
435
- x;
436
- while (++j < m) if (!isNaN(x = neighbors[j][dimension])) return x;
437
- return Math.random() * size;
438
- }
439
-
440
- // initialize neighbors lazily
441
- function neighbor() {
442
- if (!neighbors) {
443
- neighbors = [];
444
- for (j = 0; j < n; ++j) {
445
- neighbors[j] = [];
446
- }
447
- for (j = 0; j < m; ++j) {
448
- var o = links[j];
449
- neighbors[o.source.index].push(o.target);
450
- neighbors[o.target.index].push(o.source);
451
- }
452
- }
453
- return neighbors[i];
454
- }
455
-
456
- return force.resume();
457
- };
458
-
459
- force.resume = function() {
460
- alpha = .1;
461
- d3.timer(tick);
462
- return force;
463
- };
464
-
465
- force.stop = function() {
466
- alpha = 0;
467
- return force;
468
- };
469
-
470
- // use `node.call(force.drag)` to make nodes draggable
471
- force.drag = function() {
472
- if (!drag) drag = d3.behavior.drag()
473
- .origin(Object)
474
- .on("dragstart", dragstart)
475
- .on("drag", d3_layout_forceDrag)
476
- .on("dragend", d3_layout_forceDragEnd);
477
-
478
- this.on("mouseover.force", d3_layout_forceDragOver)
479
- .on("mouseout.force", d3_layout_forceDragOut)
480
- .call(drag);
481
- };
482
-
483
- function dragstart(d) {
484
- d3_layout_forceDragOver(d3_layout_forceDragNode = d);
485
- d3_layout_forceDragForce = force;
486
- }
487
-
488
- return d3.rebind(force, event, "on");
489
- };
490
-
491
- var d3_layout_forceDragForce,
492
- d3_layout_forceDragNode;
493
-
494
- function d3_layout_forceDragOver(d) {
495
- d.fixed |= 2;
496
- }
497
-
498
- function d3_layout_forceDragOut(d) {
499
- if (d !== d3_layout_forceDragNode) d.fixed &= 1;
500
- }
501
-
502
- function d3_layout_forceDragEnd() {
503
- d3_layout_forceDrag();
504
- d3_layout_forceDragNode.fixed &= 1;
505
- d3_layout_forceDragForce = d3_layout_forceDragNode = null;
506
- }
507
-
508
- function d3_layout_forceDrag() {
509
- d3_layout_forceDragNode.px = d3.event.x;
510
- d3_layout_forceDragNode.py = d3.event.y;
511
- d3_layout_forceDragForce.resume(); // restart annealing
512
- }
513
-
514
- function d3_layout_forceAccumulate(quad, alpha, charges) {
515
- var cx = 0,
516
- cy = 0;
517
- quad.charge = 0;
518
- if (!quad.leaf) {
519
- var nodes = quad.nodes,
520
- n = nodes.length,
521
- i = -1,
522
- c;
523
- while (++i < n) {
524
- c = nodes[i];
525
- if (c == null) continue;
526
- d3_layout_forceAccumulate(c, alpha, charges);
527
- quad.charge += c.charge;
528
- cx += c.charge * c.cx;
529
- cy += c.charge * c.cy;
530
- }
531
- }
532
- if (quad.point) {
533
- // jitter internal nodes that are coincident
534
- if (!quad.leaf) {
535
- quad.point.x += Math.random() - .5;
536
- quad.point.y += Math.random() - .5;
537
- }
538
- var k = alpha * charges[quad.point.index];
539
- quad.charge += quad.pointCharge = k;
540
- cx += k * quad.point.x;
541
- cy += k * quad.point.y;
542
- }
543
- quad.cx = cx / quad.charge;
544
- quad.cy = cy / quad.charge;
545
- }
546
-
547
- function d3_layout_forceLinkDistance(link) {
548
- return 20;
549
- }
550
-
551
- function d3_layout_forceLinkStrength(link) {
552
- return 1;
553
- }
554
- d3.layout.partition = function() {
555
- var hierarchy = d3.layout.hierarchy(),
556
- size = [1, 1]; // width, height
557
-
558
- function position(node, x, dx, dy) {
559
- var children = node.children;
560
- node.x = x;
561
- node.y = node.depth * dy;
562
- node.dx = dx;
563
- node.dy = dy;
564
- if (children && (n = children.length)) {
565
- var i = -1,
566
- n,
567
- c,
568
- d;
569
- dx = node.value ? dx / node.value : 0;
570
- while (++i < n) {
571
- position(c = children[i], x, d = c.value * dx, dy);
572
- x += d;
573
- }
574
- }
575
- }
576
-
577
- function depth(node) {
578
- var children = node.children,
579
- d = 0;
580
- if (children && (n = children.length)) {
581
- var i = -1,
582
- n;
583
- while (++i < n) d = Math.max(d, depth(children[i]));
584
- }
585
- return 1 + d;
586
- }
587
-
588
- function partition(d, i) {
589
- var nodes = hierarchy.call(this, d, i);
590
- position(nodes[0], 0, size[0], size[1] / depth(nodes[0]));
591
- return nodes;
592
- }
593
-
594
- partition.size = function(x) {
595
- if (!arguments.length) return size;
596
- size = x;
597
- return partition;
598
- };
599
-
600
- return d3_layout_hierarchyRebind(partition, hierarchy);
601
- };
602
- d3.layout.pie = function() {
603
- var value = Number,
604
- sort = d3_layout_pieSortByValue,
605
- startAngle = 0,
606
- endAngle = 2 * Math.PI;
607
-
608
- function pie(data, i) {
609
-
610
- // Compute the numeric values for each data element.
611
- var values = data.map(function(d, i) { return +value.call(pie, d, i); });
612
-
613
- // Compute the start angle.
614
- var a = +(typeof startAngle === "function"
615
- ? startAngle.apply(this, arguments)
616
- : startAngle);
617
-
618
- // Compute the angular scale factor: from value to radians.
619
- var k = ((typeof endAngle === "function"
620
- ? endAngle.apply(this, arguments)
621
- : endAngle) - startAngle)
622
- / d3.sum(values);
623
-
624
- // Optionally sort the data.
625
- var index = d3.range(data.length);
626
- if (sort != null) index.sort(sort === d3_layout_pieSortByValue
627
- ? function(i, j) { return values[j] - values[i]; }
628
- : function(i, j) { return sort(data[i], data[j]); });
629
-
630
- // Compute the arcs!
631
- // They are stored in the original data's order.
632
- var arcs = [];
633
- index.forEach(function(i) {
634
- arcs[i] = {
635
- data: data[i],
636
- value: d = values[i],
637
- startAngle: a,
638
- endAngle: a += d * k
639
- };
640
- });
641
- return arcs;
642
- }
643
-
644
- /**
645
- * Specifies the value function *x*, which returns a nonnegative numeric value
646
- * for each datum. The default value function is `Number`. The value function
647
- * is passed two arguments: the current datum and the current index.
648
- */
649
- pie.value = function(x) {
650
- if (!arguments.length) return value;
651
- value = x;
652
- return pie;
653
- };
654
-
655
- /**
656
- * Specifies a sort comparison operator *x*. The comparator is passed two data
657
- * elements from the data array, a and b; it returns a negative value if a is
658
- * less than b, a positive value if a is greater than b, and zero if a equals
659
- * b.
660
- */
661
- pie.sort = function(x) {
662
- if (!arguments.length) return sort;
663
- sort = x;
664
- return pie;
665
- };
666
-
667
- /**
668
- * Specifies the overall start angle of the pie chart. Defaults to 0. The
669
- * start angle can be specified either as a constant or as a function; in the
670
- * case of a function, it is evaluated once per array (as opposed to per
671
- * element).
672
- */
673
- pie.startAngle = function(x) {
674
- if (!arguments.length) return startAngle;
675
- startAngle = x;
676
- return pie;
677
- };
678
-
679
- /**
680
- * Specifies the overall end angle of the pie chart. Defaults to 2π. The
681
- * end angle can be specified either as a constant or as a function; in the
682
- * case of a function, it is evaluated once per array (as opposed to per
683
- * element).
684
- */
685
- pie.endAngle = function(x) {
686
- if (!arguments.length) return endAngle;
687
- endAngle = x;
688
- return pie;
689
- };
690
-
691
- return pie;
692
- };
693
-
694
- var d3_layout_pieSortByValue = {};
695
- // data is two-dimensional array of x,y; we populate y0
696
- d3.layout.stack = function() {
697
- var values = Object,
698
- order = d3_layout_stackOrders["default"],
699
- offset = d3_layout_stackOffsets["zero"],
700
- out = d3_layout_stackOut,
701
- x = d3_layout_stackX,
702
- y = d3_layout_stackY;
703
-
704
- function stack(data, index) {
705
-
706
- // Convert series to canonical two-dimensional representation.
707
- var series = data.map(function(d, i) {
708
- return values.call(stack, d, i);
709
- });
710
-
711
- // Convert each series to canonical [[x,y]] representation.
712
- var points = series.map(function(d, i) {
713
- return d.map(function(v, i) {
714
- return [x.call(stack, v, i), y.call(stack, v, i)];
715
- });
716
- });
717
-
718
- // Compute the order of series, and permute them.
719
- var orders = order.call(stack, points, index);
720
- series = d3.permute(series, orders);
721
- points = d3.permute(points, orders);
722
-
723
- // Compute the baseline…
724
- var offsets = offset.call(stack, points, index);
725
-
726
- // And propagate it to other series.
727
- var n = series.length,
728
- m = series[0].length,
729
- i,
730
- j,
731
- o;
732
- for (j = 0; j < m; ++j) {
733
- out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
734
- for (i = 1; i < n; ++i) {
735
- out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
736
- }
737
- }
738
-
739
- return data;
740
- }
741
-
742
- stack.values = function(x) {
743
- if (!arguments.length) return values;
744
- values = x;
745
- return stack;
746
- };
747
-
748
- stack.order = function(x) {
749
- if (!arguments.length) return order;
750
- order = typeof x === "function" ? x : d3_layout_stackOrders[x];
751
- return stack;
752
- };
753
-
754
- stack.offset = function(x) {
755
- if (!arguments.length) return offset;
756
- offset = typeof x === "function" ? x : d3_layout_stackOffsets[x];
757
- return stack;
758
- };
759
-
760
- stack.x = function(z) {
761
- if (!arguments.length) return x;
762
- x = z;
763
- return stack;
764
- };
765
-
766
- stack.y = function(z) {
767
- if (!arguments.length) return y;
768
- y = z;
769
- return stack;
770
- };
771
-
772
- stack.out = function(z) {
773
- if (!arguments.length) return out;
774
- out = z;
775
- return stack;
776
- };
777
-
778
- return stack;
779
- }
780
-
781
- function d3_layout_stackX(d) {
782
- return d.x;
783
- }
784
-
785
- function d3_layout_stackY(d) {
786
- return d.y;
787
- }
788
-
789
- function d3_layout_stackOut(d, y0, y) {
790
- d.y0 = y0;
791
- d.y = y;
792
- }
793
-
794
- var d3_layout_stackOrders = {
795
-
796
- "inside-out": function(data) {
797
- var n = data.length,
798
- i,
799
- j,
800
- max = data.map(d3_layout_stackMaxIndex),
801
- sums = data.map(d3_layout_stackReduceSum),
802
- index = d3.range(n).sort(function(a, b) { return max[a] - max[b]; }),
803
- top = 0,
804
- bottom = 0,
805
- tops = [],
806
- bottoms = [];
807
- for (i = 0; i < n; ++i) {
808
- j = index[i];
809
- if (top < bottom) {
810
- top += sums[j];
811
- tops.push(j);
812
- } else {
813
- bottom += sums[j];
814
- bottoms.push(j);
815
- }
816
- }
817
- return bottoms.reverse().concat(tops);
818
- },
819
-
820
- "reverse": function(data) {
821
- return d3.range(data.length).reverse();
822
- },
823
-
824
- "default": function(data) {
825
- return d3.range(data.length);
826
- }
827
-
828
- };
829
-
830
- var d3_layout_stackOffsets = {
831
-
832
- "silhouette": function(data) {
833
- var n = data.length,
834
- m = data[0].length,
835
- sums = [],
836
- max = 0,
837
- i,
838
- j,
839
- o,
840
- y0 = [];
841
- for (j = 0; j < m; ++j) {
842
- for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
843
- if (o > max) max = o;
844
- sums.push(o);
845
- }
846
- for (j = 0; j < m; ++j) {
847
- y0[j] = (max - sums[j]) / 2;
848
- }
849
- return y0;
850
- },
851
-
852
- "wiggle": function(data) {
853
- var n = data.length,
854
- x = data[0],
855
- m = x.length,
856
- max = 0,
857
- i,
858
- j,
859
- k,
860
- s1,
861
- s2,
862
- s3,
863
- dx,
864
- o,
865
- o0,
866
- y0 = [];
867
- y0[0] = o = o0 = 0;
868
- for (j = 1; j < m; ++j) {
869
- for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
870
- for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
871
- for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
872
- s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
873
- }
874
- s2 += s3 * data[i][j][1];
875
- }
876
- y0[j] = o -= s1 ? s2 / s1 * dx : 0;
877
- if (o < o0) o0 = o;
878
- }
879
- for (j = 0; j < m; ++j) y0[j] -= o0;
880
- return y0;
881
- },
882
-
883
- "expand": function(data) {
884
- var n = data.length,
885
- m = data[0].length,
886
- k = 1 / n,
887
- i,
888
- j,
889
- o,
890
- y0 = [];
891
- for (j = 0; j < m; ++j) {
892
- for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
893
- if (o) for (i = 0; i < n; i++) data[i][j][1] /= o;
894
- else for (i = 0; i < n; i++) data[i][j][1] = k;
895
- }
896
- for (j = 0; j < m; ++j) y0[j] = 0;
897
- return y0;
898
- },
899
-
900
- "zero": function(data) {
901
- var j = -1,
902
- m = data[0].length,
903
- y0 = [];
904
- while (++j < m) y0[j] = 0;
905
- return y0;
906
- }
907
-
908
- };
909
-
910
- function d3_layout_stackMaxIndex(array) {
911
- var i = 1,
912
- j = 0,
913
- v = array[0][1],
914
- k,
915
- n = array.length;
916
- for (; i < n; ++i) {
917
- if ((k = array[i][1]) > v) {
918
- j = i;
919
- v = k;
920
- }
921
- }
922
- return j;
923
- }
924
-
925
- function d3_layout_stackReduceSum(d) {
926
- return d.reduce(d3_layout_stackSum, 0);
927
- }
928
-
929
- function d3_layout_stackSum(p, d) {
930
- return p + d[1];
931
- }
932
- d3.layout.histogram = function() {
933
- var frequency = true,
934
- valuer = Number,
935
- ranger = d3_layout_histogramRange,
936
- binner = d3_layout_histogramBinSturges;
937
-
938
- function histogram(data, i) {
939
- var bins = [],
940
- values = data.map(valuer, this),
941
- range = ranger.call(this, values, i),
942
- thresholds = binner.call(this, range, values, i),
943
- bin,
944
- i = -1,
945
- n = values.length,
946
- m = thresholds.length - 1,
947
- k = frequency ? 1 : 1 / n,
948
- x;
949
-
950
- // Initialize the bins.
951
- while (++i < m) {
952
- bin = bins[i] = [];
953
- bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
954
- bin.y = 0;
955
- }
956
-
957
- // Fill the bins, ignoring values outside the range.
958
- i = -1; while(++i < n) {
959
- x = values[i];
960
- if ((x >= range[0]) && (x <= range[1])) {
961
- bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
962
- bin.y += k;
963
- bin.push(data[i]);
964
- }
965
- }
966
-
967
- return bins;
968
- }
969
-
970
- // Specifies how to extract a value from the associated data. The default
971
- // value function is `Number`, which is equivalent to the identity function.
972
- histogram.value = function(x) {
973
- if (!arguments.length) return valuer;
974
- valuer = x;
975
- return histogram;
976
- };
977
-
978
- // Specifies the range of the histogram. Values outside the specified range
979
- // will be ignored. The argument `x` may be specified either as a two-element
980
- // array representing the minimum and maximum value of the range, or as a
981
- // function that returns the range given the array of values and the current
982
- // index `i`. The default range is the extent (minimum and maximum) of the
983
- // values.
984
- histogram.range = function(x) {
985
- if (!arguments.length) return ranger;
986
- ranger = d3.functor(x);
987
- return histogram;
988
- };
989
-
990
- // Specifies how to bin values in the histogram. The argument `x` may be
991
- // specified as a number, in which case the range of values will be split
992
- // uniformly into the given number of bins. Or, `x` may be an array of
993
- // threshold values, defining the bins; the specified array must contain the
994
- // rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x`
995
- // may be a function which is evaluated, being passed the range, the array of
996
- // values, and the current index `i`, returning an array of thresholds. The
997
- // default bin function will divide the values into uniform bins using
998
- // Sturges' formula.
999
- histogram.bins = function(x) {
1000
- if (!arguments.length) return binner;
1001
- binner = typeof x === "number"
1002
- ? function(range) { return d3_layout_histogramBinFixed(range, x); }
1003
- : d3.functor(x);
1004
- return histogram;
1005
- };
1006
-
1007
- // Specifies whether the histogram's `y` value is a count (frequency) or a
1008
- // probability (density). The default value is true.
1009
- histogram.frequency = function(x) {
1010
- if (!arguments.length) return frequency;
1011
- frequency = !!x;
1012
- return histogram;
1013
- };
1014
-
1015
- return histogram;
1016
- };
1017
-
1018
- function d3_layout_histogramBinSturges(range, values) {
1019
- return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
1020
- }
1021
-
1022
- function d3_layout_histogramBinFixed(range, n) {
1023
- var x = -1,
1024
- b = +range[0],
1025
- m = (range[1] - b) / n,
1026
- f = [];
1027
- while (++x <= n) f[x] = m * x + b;
1028
- return f;
1029
- }
1030
-
1031
- function d3_layout_histogramRange(values) {
1032
- return [d3.min(values), d3.max(values)];
1033
- }
1034
- d3.layout.hierarchy = function() {
1035
- var sort = d3_layout_hierarchySort,
1036
- children = d3_layout_hierarchyChildren,
1037
- value = d3_layout_hierarchyValue;
1038
-
1039
- // Recursively compute the node depth and value.
1040
- // Also converts the data representation into a standard hierarchy structure.
1041
- function recurse(data, depth, nodes) {
1042
- var childs = children.call(hierarchy, data, depth),
1043
- node = d3_layout_hierarchyInline ? data : {data: data};
1044
- node.depth = depth;
1045
- nodes.push(node);
1046
- if (childs && (n = childs.length)) {
1047
- var i = -1,
1048
- n,
1049
- c = node.children = [],
1050
- v = 0,
1051
- j = depth + 1;
1052
- while (++i < n) {
1053
- d = recurse(childs[i], j, nodes);
1054
- d.parent = node;
1055
- c.push(d);
1056
- v += d.value;
1057
- }
1058
- if (sort) c.sort(sort);
1059
- if (value) node.value = v;
1060
- } else if (value) {
1061
- node.value = +value.call(hierarchy, data, depth) || 0;
1062
- }
1063
- return node;
1064
- }
1065
-
1066
- // Recursively re-evaluates the node value.
1067
- function revalue(node, depth) {
1068
- var children = node.children,
1069
- v = 0;
1070
- if (children && (n = children.length)) {
1071
- var i = -1,
1072
- n,
1073
- j = depth + 1;
1074
- while (++i < n) v += revalue(children[i], j);
1075
- } else if (value) {
1076
- v = +value.call(hierarchy, d3_layout_hierarchyInline ? node : node.data, depth) || 0;
1077
- }
1078
- if (value) node.value = v;
1079
- return v;
1080
- }
1081
-
1082
- function hierarchy(d) {
1083
- var nodes = [];
1084
- recurse(d, 0, nodes);
1085
- return nodes;
1086
- }
1087
-
1088
- hierarchy.sort = function(x) {
1089
- if (!arguments.length) return sort;
1090
- sort = x;
1091
- return hierarchy;
1092
- };
1093
-
1094
- hierarchy.children = function(x) {
1095
- if (!arguments.length) return children;
1096
- children = x;
1097
- return hierarchy;
1098
- };
1099
-
1100
- hierarchy.value = function(x) {
1101
- if (!arguments.length) return value;
1102
- value = x;
1103
- return hierarchy;
1104
- };
1105
-
1106
- // Re-evaluates the `value` property for the specified hierarchy.
1107
- hierarchy.revalue = function(root) {
1108
- revalue(root, 0);
1109
- return root;
1110
- };
1111
-
1112
- return hierarchy;
1113
- };
1114
-
1115
- // A method assignment helper for hierarchy subclasses.
1116
- function d3_layout_hierarchyRebind(object, hierarchy) {
1117
- d3.rebind(object, hierarchy, "sort", "children", "value");
1118
-
1119
- // Add an alias for links, for convenience.
1120
- object.links = d3_layout_hierarchyLinks;
1121
-
1122
- // If the new API is used, enabling inlining.
1123
- object.nodes = function(d) {
1124
- d3_layout_hierarchyInline = true;
1125
- return (object.nodes = object)(d);
1126
- };
1127
-
1128
- return object;
1129
- }
1130
-
1131
- function d3_layout_hierarchyChildren(d) {
1132
- return d.children;
1133
- }
1134
-
1135
- function d3_layout_hierarchyValue(d) {
1136
- return d.value;
1137
- }
1138
-
1139
- function d3_layout_hierarchySort(a, b) {
1140
- return b.value - a.value;
1141
- }
1142
-
1143
- // Returns an array source+target objects for the specified nodes.
1144
- function d3_layout_hierarchyLinks(nodes) {
1145
- return d3.merge(nodes.map(function(parent) {
1146
- return (parent.children || []).map(function(child) {
1147
- return {source: parent, target: child};
1148
- });
1149
- }));
1150
- }
1151
-
1152
- // For backwards-compatibility, don't enable inlining by default.
1153
- var d3_layout_hierarchyInline = false;
1154
- d3.layout.pack = function() {
1155
- var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
1156
- size = [1, 1];
1157
-
1158
- function pack(d, i) {
1159
- var nodes = hierarchy.call(this, d, i),
1160
- root = nodes[0];
1161
-
1162
- // Recursively compute the layout.
1163
- root.x = 0;
1164
- root.y = 0;
1165
- d3_layout_packTree(root);
1166
-
1167
- // Scale the layout to fit the requested size.
1168
- var w = size[0],
1169
- h = size[1],
1170
- k = 1 / Math.max(2 * root.r / w, 2 * root.r / h);
1171
- d3_layout_packTransform(root, w / 2, h / 2, k);
1172
-
1173
- return nodes;
1174
- }
1175
-
1176
- pack.size = function(x) {
1177
- if (!arguments.length) return size;
1178
- size = x;
1179
- return pack;
1180
- };
1181
-
1182
- return d3_layout_hierarchyRebind(pack, hierarchy);
1183
- };
1184
-
1185
- function d3_layout_packSort(a, b) {
1186
- return a.value - b.value;
1187
- }
1188
-
1189
- function d3_layout_packInsert(a, b) {
1190
- var c = a._pack_next;
1191
- a._pack_next = b;
1192
- b._pack_prev = a;
1193
- b._pack_next = c;
1194
- c._pack_prev = b;
1195
- }
1196
-
1197
- function d3_layout_packSplice(a, b) {
1198
- a._pack_next = b;
1199
- b._pack_prev = a;
1200
- }
1201
-
1202
- function d3_layout_packIntersects(a, b) {
1203
- var dx = b.x - a.x,
1204
- dy = b.y - a.y,
1205
- dr = a.r + b.r;
1206
- return dr * dr - dx * dx - dy * dy > .001; // within epsilon
1207
- }
1208
-
1209
- function d3_layout_packCircle(nodes) {
1210
- var xMin = Infinity,
1211
- xMax = -Infinity,
1212
- yMin = Infinity,
1213
- yMax = -Infinity,
1214
- n = nodes.length,
1215
- a, b, c, j, k;
1216
-
1217
- function bound(node) {
1218
- xMin = Math.min(node.x - node.r, xMin);
1219
- xMax = Math.max(node.x + node.r, xMax);
1220
- yMin = Math.min(node.y - node.r, yMin);
1221
- yMax = Math.max(node.y + node.r, yMax);
1222
- }
1223
-
1224
- // Create node links.
1225
- nodes.forEach(d3_layout_packLink);
1226
-
1227
- // Create first node.
1228
- a = nodes[0];
1229
- a.x = -a.r;
1230
- a.y = 0;
1231
- bound(a);
1232
-
1233
- // Create second node.
1234
- if (n > 1) {
1235
- b = nodes[1];
1236
- b.x = b.r;
1237
- b.y = 0;
1238
- bound(b);
1239
-
1240
- // Create third node and build chain.
1241
- if (n > 2) {
1242
- c = nodes[2];
1243
- d3_layout_packPlace(a, b, c);
1244
- bound(c);
1245
- d3_layout_packInsert(a, c);
1246
- a._pack_prev = c;
1247
- d3_layout_packInsert(c, b);
1248
- b = a._pack_next;
1249
-
1250
- // Now iterate through the rest.
1251
- for (var i = 3; i < n; i++) {
1252
- d3_layout_packPlace(a, b, c = nodes[i]);
1253
-
1254
- // Search for the closest intersection.
1255
- var isect = 0, s1 = 1, s2 = 1;
1256
- for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
1257
- if (d3_layout_packIntersects(j, c)) {
1258
- isect = 1;
1259
- break;
1260
- }
1261
- }
1262
- if (isect == 1) {
1263
- for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
1264
- if (d3_layout_packIntersects(k, c)) {
1265
- break;
1266
- }
1267
- }
1268
- }
1269
-
1270
- // Update node chain.
1271
- if (isect) {
1272
- if (s1 < s2 || (s1 == s2 && b.r < a.r)) d3_layout_packSplice(a, b = j);
1273
- else d3_layout_packSplice(a = k, b);
1274
- i--;
1275
- } else {
1276
- d3_layout_packInsert(a, c);
1277
- b = c;
1278
- bound(c);
1279
- }
1280
- }
1281
- }
1282
- }
1283
-
1284
- // Re-center the circles and return the encompassing radius.
1285
- var cx = (xMin + xMax) / 2,
1286
- cy = (yMin + yMax) / 2,
1287
- cr = 0;
1288
- for (var i = 0; i < n; i++) {
1289
- var node = nodes[i];
1290
- node.x -= cx;
1291
- node.y -= cy;
1292
- cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y));
1293
- }
1294
-
1295
- // Remove node links.
1296
- nodes.forEach(d3_layout_packUnlink);
1297
-
1298
- return cr;
1299
- }
1300
-
1301
- function d3_layout_packLink(node) {
1302
- node._pack_next = node._pack_prev = node;
1303
- }
1304
-
1305
- function d3_layout_packUnlink(node) {
1306
- delete node._pack_next;
1307
- delete node._pack_prev;
1308
- }
1309
-
1310
- function d3_layout_packTree(node) {
1311
- var children = node.children;
1312
- if (children && children.length) {
1313
- children.forEach(d3_layout_packTree);
1314
- node.r = d3_layout_packCircle(children);
1315
- } else {
1316
- node.r = Math.sqrt(node.value);
1317
- }
1318
- }
1319
-
1320
- function d3_layout_packTransform(node, x, y, k) {
1321
- var children = node.children;
1322
- node.x = (x += k * node.x);
1323
- node.y = (y += k * node.y);
1324
- node.r *= k;
1325
- if (children) {
1326
- var i = -1, n = children.length;
1327
- while (++i < n) d3_layout_packTransform(children[i], x, y, k);
1328
- }
1329
- }
1330
-
1331
- function d3_layout_packPlace(a, b, c) {
1332
- var db = a.r + c.r,
1333
- dx = b.x - a.x,
1334
- dy = b.y - a.y;
1335
- if (db && (dx || dy)) {
1336
- var da = b.r + c.r,
1337
- dc = Math.sqrt(dx * dx + dy * dy),
1338
- cos = Math.max(-1, Math.min(1, (db * db + dc * dc - da * da) / (2 * db * dc))),
1339
- theta = Math.acos(cos),
1340
- x = cos * (db /= dc),
1341
- y = Math.sin(theta) * db;
1342
- c.x = a.x + x * dx + y * dy;
1343
- c.y = a.y + x * dy - y * dx;
1344
- } else {
1345
- c.x = a.x + db;
1346
- c.y = a.y;
1347
- }
1348
- }
1349
- // Implements a hierarchical layout using the cluster (or dendrogram)
1350
- // algorithm.
1351
- d3.layout.cluster = function() {
1352
- var hierarchy = d3.layout.hierarchy().sort(null).value(null),
1353
- separation = d3_layout_treeSeparation,
1354
- size = [1, 1]; // width, height
1355
-
1356
- function cluster(d, i) {
1357
- var nodes = hierarchy.call(this, d, i),
1358
- root = nodes[0],
1359
- previousNode,
1360
- x = 0,
1361
- kx,
1362
- ky;
1363
-
1364
- // First walk, computing the initial x & y values.
1365
- d3_layout_treeVisitAfter(root, function(node) {
1366
- var children = node.children;
1367
- if (children && children.length) {
1368
- node.x = d3_layout_clusterX(children);
1369
- node.y = d3_layout_clusterY(children);
1370
- } else {
1371
- node.x = previousNode ? x += separation(node, previousNode) : 0;
1372
- node.y = 0;
1373
- previousNode = node;
1374
- }
1375
- });
1376
-
1377
- // Compute the left-most, right-most, and depth-most nodes for extents.
1378
- var left = d3_layout_clusterLeft(root),
1379
- right = d3_layout_clusterRight(root),
1380
- x0 = left.x - separation(left, right) / 2,
1381
- x1 = right.x + separation(right, left) / 2;
1382
-
1383
- // Second walk, normalizing x & y to the desired size.
1384
- d3_layout_treeVisitAfter(root, function(node) {
1385
- node.x = (node.x - x0) / (x1 - x0) * size[0];
1386
- node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1];
1387
- });
1388
-
1389
- return nodes;
1390
- }
1391
-
1392
- cluster.separation = function(x) {
1393
- if (!arguments.length) return separation;
1394
- separation = x;
1395
- return cluster;
1396
- };
1397
-
1398
- cluster.size = function(x) {
1399
- if (!arguments.length) return size;
1400
- size = x;
1401
- return cluster;
1402
- };
1403
-
1404
- return d3_layout_hierarchyRebind(cluster, hierarchy);
1405
- };
1406
-
1407
- function d3_layout_clusterY(children) {
1408
- return 1 + d3.max(children, function(child) {
1409
- return child.y;
1410
- });
1411
- }
1412
-
1413
- function d3_layout_clusterX(children) {
1414
- return children.reduce(function(x, child) {
1415
- return x + child.x;
1416
- }, 0) / children.length;
1417
- }
1418
-
1419
- function d3_layout_clusterLeft(node) {
1420
- var children = node.children;
1421
- return children && children.length ? d3_layout_clusterLeft(children[0]) : node;
1422
- }
1423
-
1424
- function d3_layout_clusterRight(node) {
1425
- var children = node.children, n;
1426
- return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node;
1427
- }
1428
- // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
1429
- d3.layout.tree = function() {
1430
- var hierarchy = d3.layout.hierarchy().sort(null).value(null),
1431
- separation = d3_layout_treeSeparation,
1432
- size = [1, 1]; // width, height
1433
-
1434
- function tree(d, i) {
1435
- var nodes = hierarchy.call(this, d, i),
1436
- root = nodes[0];
1437
-
1438
- function firstWalk(node, previousSibling) {
1439
- var children = node.children,
1440
- layout = node._tree;
1441
- if (children && (n = children.length)) {
1442
- var n,
1443
- firstChild = children[0],
1444
- previousChild,
1445
- ancestor = firstChild,
1446
- child,
1447
- i = -1;
1448
- while (++i < n) {
1449
- child = children[i];
1450
- firstWalk(child, previousChild);
1451
- ancestor = apportion(child, previousChild, ancestor);
1452
- previousChild = child;
1453
- }
1454
- d3_layout_treeShift(node);
1455
- var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim);
1456
- if (previousSibling) {
1457
- layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
1458
- layout.mod = layout.prelim - midpoint;
1459
- } else {
1460
- layout.prelim = midpoint;
1461
- }
1462
- } else {
1463
- if (previousSibling) {
1464
- layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
1465
- }
1466
- }
1467
- }
1468
-
1469
- function secondWalk(node, x) {
1470
- node.x = node._tree.prelim + x;
1471
- var children = node.children;
1472
- if (children && (n = children.length)) {
1473
- var i = -1,
1474
- n;
1475
- x += node._tree.mod;
1476
- while (++i < n) {
1477
- secondWalk(children[i], x);
1478
- }
1479
- }
1480
- }
1481
-
1482
- function apportion(node, previousSibling, ancestor) {
1483
- if (previousSibling) {
1484
- var vip = node,
1485
- vop = node,
1486
- vim = previousSibling,
1487
- vom = node.parent.children[0],
1488
- sip = vip._tree.mod,
1489
- sop = vop._tree.mod,
1490
- sim = vim._tree.mod,
1491
- som = vom._tree.mod,
1492
- shift;
1493
- while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
1494
- vom = d3_layout_treeLeft(vom);
1495
- vop = d3_layout_treeRight(vop);
1496
- vop._tree.ancestor = node;
1497
- shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip);
1498
- if (shift > 0) {
1499
- d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift);
1500
- sip += shift;
1501
- sop += shift;
1502
- }
1503
- sim += vim._tree.mod;
1504
- sip += vip._tree.mod;
1505
- som += vom._tree.mod;
1506
- sop += vop._tree.mod;
1507
- }
1508
- if (vim && !d3_layout_treeRight(vop)) {
1509
- vop._tree.thread = vim;
1510
- vop._tree.mod += sim - sop;
1511
- }
1512
- if (vip && !d3_layout_treeLeft(vom)) {
1513
- vom._tree.thread = vip;
1514
- vom._tree.mod += sip - som;
1515
- ancestor = node;
1516
- }
1517
- }
1518
- return ancestor;
1519
- }
1520
-
1521
- // Initialize temporary layout variables.
1522
- d3_layout_treeVisitAfter(root, function(node, previousSibling) {
1523
- node._tree = {
1524
- ancestor: node,
1525
- prelim: 0,
1526
- mod: 0,
1527
- change: 0,
1528
- shift: 0,
1529
- number: previousSibling ? previousSibling._tree.number + 1 : 0
1530
- };
1531
- });
1532
-
1533
- // Compute the layout using Buchheim et al.'s algorithm.
1534
- firstWalk(root);
1535
- secondWalk(root, -root._tree.prelim);
1536
-
1537
- // Compute the left-most, right-most, and depth-most nodes for extents.
1538
- var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost),
1539
- right = d3_layout_treeSearch(root, d3_layout_treeRightmost),
1540
- deep = d3_layout_treeSearch(root, d3_layout_treeDeepest),
1541
- x0 = left.x - separation(left, right) / 2,
1542
- x1 = right.x + separation(right, left) / 2,
1543
- y1 = deep.depth || 1;
1544
-
1545
- // Clear temporary layout variables; transform x and y.
1546
- d3_layout_treeVisitAfter(root, function(node) {
1547
- node.x = (node.x - x0) / (x1 - x0) * size[0];
1548
- node.y = node.depth / y1 * size[1];
1549
- delete node._tree;
1550
- });
1551
-
1552
- return nodes;
1553
- }
1554
-
1555
- tree.separation = function(x) {
1556
- if (!arguments.length) return separation;
1557
- separation = x;
1558
- return tree;
1559
- };
1560
-
1561
- tree.size = function(x) {
1562
- if (!arguments.length) return size;
1563
- size = x;
1564
- return tree;
1565
- };
1566
-
1567
- return d3_layout_hierarchyRebind(tree, hierarchy);
1568
- };
1569
-
1570
- function d3_layout_treeSeparation(a, b) {
1571
- return a.parent == b.parent ? 1 : 2;
1572
- }
1573
-
1574
- // function d3_layout_treeSeparationRadial(a, b) {
1575
- // return (a.parent == b.parent ? 1 : 2) / a.depth;
1576
- // }
1577
-
1578
- function d3_layout_treeLeft(node) {
1579
- var children = node.children;
1580
- return children && children.length ? children[0] : node._tree.thread;
1581
- }
1582
-
1583
- function d3_layout_treeRight(node) {
1584
- var children = node.children,
1585
- n;
1586
- return children && (n = children.length) ? children[n - 1] : node._tree.thread;
1587
- }
1588
-
1589
- function d3_layout_treeSearch(node, compare) {
1590
- var children = node.children;
1591
- if (children && (n = children.length)) {
1592
- var child,
1593
- n,
1594
- i = -1;
1595
- while (++i < n) {
1596
- if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
1597
- node = child;
1598
- }
1599
- }
1600
- }
1601
- return node;
1602
- }
1603
-
1604
- function d3_layout_treeRightmost(a, b) {
1605
- return a.x - b.x;
1606
- }
1607
-
1608
- function d3_layout_treeLeftmost(a, b) {
1609
- return b.x - a.x;
1610
- }
1611
-
1612
- function d3_layout_treeDeepest(a, b) {
1613
- return a.depth - b.depth;
1614
- }
1615
-
1616
- function d3_layout_treeVisitAfter(node, callback) {
1617
- function visit(node, previousSibling) {
1618
- var children = node.children;
1619
- if (children && (n = children.length)) {
1620
- var child,
1621
- previousChild = null,
1622
- i = -1,
1623
- n;
1624
- while (++i < n) {
1625
- child = children[i];
1626
- visit(child, previousChild);
1627
- previousChild = child;
1628
- }
1629
- }
1630
- callback(node, previousSibling);
1631
- }
1632
- visit(node, null);
1633
- }
1634
-
1635
- function d3_layout_treeShift(node) {
1636
- var shift = 0,
1637
- change = 0,
1638
- children = node.children,
1639
- i = children.length,
1640
- child;
1641
- while (--i >= 0) {
1642
- child = children[i]._tree;
1643
- child.prelim += shift;
1644
- child.mod += shift;
1645
- shift += child.shift + (change += child.change);
1646
- }
1647
- }
1648
-
1649
- function d3_layout_treeMove(ancestor, node, shift) {
1650
- ancestor = ancestor._tree;
1651
- node = node._tree;
1652
- var change = shift / (node.number - ancestor.number);
1653
- ancestor.change += change;
1654
- node.change -= change;
1655
- node.shift += shift;
1656
- node.prelim += shift;
1657
- node.mod += shift;
1658
- }
1659
-
1660
- function d3_layout_treeAncestor(vim, node, ancestor) {
1661
- return vim._tree.ancestor.parent == node.parent
1662
- ? vim._tree.ancestor
1663
- : ancestor;
1664
- }
1665
- // Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
1666
- // Modified to support a target aspect ratio by Jeff Heer
1667
- d3.layout.treemap = function() {
1668
- var hierarchy = d3.layout.hierarchy(),
1669
- round = Math.round,
1670
- size = [1, 1], // width, height
1671
- padding = null,
1672
- pad = d3_layout_treemapPadNull,
1673
- sticky = false,
1674
- stickies,
1675
- ratio = 0.5 * (1 + Math.sqrt(5)); // golden ratio
1676
-
1677
- // Compute the area for each child based on value & scale.
1678
- function scale(children, k) {
1679
- var i = -1,
1680
- n = children.length,
1681
- child,
1682
- area;
1683
- while (++i < n) {
1684
- area = (child = children[i]).value * (k < 0 ? 0 : k);
1685
- child.area = isNaN(area) || area <= 0 ? 0 : area;
1686
- }
1687
- }
1688
-
1689
- // Recursively arranges the specified node's children into squarified rows.
1690
- function squarify(node) {
1691
- var children = node.children;
1692
- if (children && children.length) {
1693
- var rect = pad(node),
1694
- row = [],
1695
- remaining = children.slice(), // copy-on-write
1696
- child,
1697
- best = Infinity, // the best row score so far
1698
- score, // the current row score
1699
- u = Math.min(rect.dx, rect.dy), // initial orientation
1700
- n;
1701
- scale(remaining, rect.dx * rect.dy / node.value);
1702
- row.area = 0;
1703
- while ((n = remaining.length) > 0) {
1704
- row.push(child = remaining[n - 1]);
1705
- row.area += child.area;
1706
- if ((score = worst(row, u)) <= best) { // continue with this orientation
1707
- remaining.pop();
1708
- best = score;
1709
- } else { // abort, and try a different orientation
1710
- row.area -= row.pop().area;
1711
- position(row, u, rect, false);
1712
- u = Math.min(rect.dx, rect.dy);
1713
- row.length = row.area = 0;
1714
- best = Infinity;
1715
- }
1716
- }
1717
- if (row.length) {
1718
- position(row, u, rect, true);
1719
- row.length = row.area = 0;
1720
- }
1721
- children.forEach(squarify);
1722
- }
1723
- }
1724
-
1725
- // Recursively resizes the specified node's children into existing rows.
1726
- // Preserves the existing layout!
1727
- function stickify(node) {
1728
- var children = node.children;
1729
- if (children && children.length) {
1730
- var rect = pad(node),
1731
- remaining = children.slice(), // copy-on-write
1732
- child,
1733
- row = [];
1734
- scale(remaining, rect.dx * rect.dy / node.value);
1735
- row.area = 0;
1736
- while (child = remaining.pop()) {
1737
- row.push(child);
1738
- row.area += child.area;
1739
- if (child.z != null) {
1740
- position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
1741
- row.length = row.area = 0;
1742
- }
1743
- }
1744
- children.forEach(stickify);
1745
- }
1746
- }
1747
-
1748
- // Computes the score for the specified row, as the worst aspect ratio.
1749
- function worst(row, u) {
1750
- var s = row.area,
1751
- r,
1752
- rmax = 0,
1753
- rmin = Infinity,
1754
- i = -1,
1755
- n = row.length;
1756
- while (++i < n) {
1757
- if (!(r = row[i].area)) continue;
1758
- if (r < rmin) rmin = r;
1759
- if (r > rmax) rmax = r;
1760
- }
1761
- s *= s;
1762
- u *= u;
1763
- return s
1764
- ? Math.max((u * rmax * ratio) / s, s / (u * rmin * ratio))
1765
- : Infinity;
1766
- }
1767
-
1768
- // Positions the specified row of nodes. Modifies `rect`.
1769
- function position(row, u, rect, flush) {
1770
- var i = -1,
1771
- n = row.length,
1772
- x = rect.x,
1773
- y = rect.y,
1774
- v = u ? round(row.area / u) : 0,
1775
- o;
1776
- if (u == rect.dx) { // horizontal subdivision
1777
- if (flush || v > rect.dy) v = rect.dy; // over+underflow
1778
- while (++i < n) {
1779
- o = row[i];
1780
- o.x = x;
1781
- o.y = y;
1782
- o.dy = v;
1783
- x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0);
1784
- }
1785
- o.z = true;
1786
- o.dx += rect.x + rect.dx - x; // rounding error
1787
- rect.y += v;
1788
- rect.dy -= v;
1789
- } else { // vertical subdivision
1790
- if (flush || v > rect.dx) v = rect.dx; // over+underflow
1791
- while (++i < n) {
1792
- o = row[i];
1793
- o.x = x;
1794
- o.y = y;
1795
- o.dx = v;
1796
- y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0);
1797
- }
1798
- o.z = false;
1799
- o.dy += rect.y + rect.dy - y; // rounding error
1800
- rect.x += v;
1801
- rect.dx -= v;
1802
- }
1803
- }
1804
-
1805
- function treemap(d) {
1806
- var nodes = stickies || hierarchy(d),
1807
- root = nodes[0];
1808
- root.x = 0;
1809
- root.y = 0;
1810
- root.dx = size[0];
1811
- root.dy = size[1];
1812
- if (stickies) hierarchy.revalue(root);
1813
- scale([root], root.dx * root.dy / root.value);
1814
- (stickies ? stickify : squarify)(root);
1815
- if (sticky) stickies = nodes;
1816
- return nodes;
1817
- }
1818
-
1819
- treemap.size = function(x) {
1820
- if (!arguments.length) return size;
1821
- size = x;
1822
- return treemap;
1823
- };
1824
-
1825
- treemap.padding = function(x) {
1826
- if (!arguments.length) return padding;
1827
-
1828
- function padFunction(node) {
1829
- var p = x.call(treemap, node, node.depth);
1830
- return p == null
1831
- ? d3_layout_treemapPadNull(node)
1832
- : d3_layout_treemapPad(node, typeof p === "number" ? [p, p, p, p] : p);
1833
- }
1834
-
1835
- function padConstant(node) {
1836
- return d3_layout_treemapPad(node, x);
1837
- }
1838
-
1839
- var type;
1840
- pad = (padding = x) == null ? d3_layout_treemapPadNull
1841
- : (type = typeof x) === "function" ? padFunction
1842
- : type === "number" ? (x = [x, x, x, x], padConstant)
1843
- : padConstant;
1844
- return treemap;
1845
- };
1846
-
1847
- treemap.round = function(x) {
1848
- if (!arguments.length) return round != Number;
1849
- round = x ? Math.round : Number;
1850
- return treemap;
1851
- };
1852
-
1853
- treemap.sticky = function(x) {
1854
- if (!arguments.length) return sticky;
1855
- sticky = x;
1856
- stickies = null;
1857
- return treemap;
1858
- };
1859
-
1860
- treemap.ratio = function(x) {
1861
- if (!arguments.length) return ratio;
1862
- ratio = x;
1863
- return treemap;
1864
- };
1865
-
1866
- return d3_layout_hierarchyRebind(treemap, hierarchy);
1867
- };
1868
-
1869
- function d3_layout_treemapPadNull(node) {
1870
- return {x: node.x, y: node.y, dx: node.dx, dy: node.dy};
1871
- }
1872
-
1873
- function d3_layout_treemapPad(node, padding) {
1874
- var x = node.x + padding[3],
1875
- y = node.y + padding[0],
1876
- dx = node.dx - padding[1] - padding[3],
1877
- dy = node.dy - padding[0] - padding[2];
1878
- if (dx < 0) { x += dx / 2; dx = 0; }
1879
- if (dy < 0) { y += dy / 2; dy = 0; }
1880
- return {x: x, y: y, dx: dx, dy: dy};
1881
- }
1882
- })();