wiki 0.0.1

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