wiki 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +10 -2
  4. data/bin/wiki +4 -0
  5. data/default-data/pages/how-to-wiki +1069 -0
  6. data/default-data/pages/welcome-visitors +336 -0
  7. data/default-data/status/favicon.png +0 -0
  8. data/default-data/status/local-identity +7 -0
  9. data/lib/wiki/favicon.rb +0 -1
  10. data/lib/wiki/page.rb +3 -6
  11. data/lib/wiki/server.rb +7 -3
  12. data/lib/wiki/version.rb +1 -1
  13. data/package.json +70 -0
  14. data/wiki.gemspec +20 -13
  15. metadata +205 -58
  16. data/lib/wiki/views/client/Gruntfile.js +0 -50
  17. data/lib/wiki/views/client/ReadMe.md +0 -67
  18. data/lib/wiki/views/client/build-test.bat +0 -10
  19. data/lib/wiki/views/client/build.bat +0 -8
  20. data/lib/wiki/views/client/builder.pl +0 -41
  21. data/lib/wiki/views/client/client.coffee +0 -3
  22. data/lib/wiki/views/client/client.js +0 -3607
  23. data/lib/wiki/views/client/crosses.png +0 -0
  24. data/lib/wiki/views/client/images/external-link-ltr-icon.png +0 -0
  25. data/lib/wiki/views/client/images/noise.png +0 -0
  26. data/lib/wiki/views/client/images/oops.jpg +0 -0
  27. data/lib/wiki/views/client/js/d3/d3.behavior.js +0 -198
  28. data/lib/wiki/views/client/js/d3/d3.chart.js +0 -984
  29. data/lib/wiki/views/client/js/d3/d3.csv.js +0 -92
  30. data/lib/wiki/views/client/js/d3/d3.geo.js +0 -566
  31. data/lib/wiki/views/client/js/d3/d3.geom.js +0 -825
  32. data/lib/wiki/views/client/js/d3/d3.js +0 -3597
  33. data/lib/wiki/views/client/js/d3/d3.layout.js +0 -1923
  34. data/lib/wiki/views/client/js/d3/d3.time.js +0 -660
  35. data/lib/wiki/views/client/js/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  36. data/lib/wiki/views/client/js/images/ui-icons_222222_256x240.png +0 -0
  37. data/lib/wiki/views/client/js/jquery-1.6.2.min.js +0 -18
  38. data/lib/wiki/views/client/js/jquery-1.7.1.min.js +0 -4
  39. data/lib/wiki/views/client/js/jquery-1.9.1.min.js +0 -5
  40. data/lib/wiki/views/client/js/jquery-migrate-1.1.1.min.js +0 -3
  41. data/lib/wiki/views/client/js/jquery-ui-1.10.1.custom.min.css +0 -5
  42. data/lib/wiki/views/client/js/jquery-ui-1.10.1.custom.min.js +0 -6
  43. data/lib/wiki/views/client/js/jquery-ui-1.8.16.custom.css +0 -339
  44. data/lib/wiki/views/client/js/jquery-ui-1.8.16.custom.min.js +0 -315
  45. data/lib/wiki/views/client/js/jquery.ie.cors.js +0 -310
  46. data/lib/wiki/views/client/js/jquery.ui.touch-punch.min.js +0 -11
  47. data/lib/wiki/views/client/js/modernizr.custom.63710.js +0 -824
  48. data/lib/wiki/views/client/js/sockjs-0.3.min.js +0 -27
  49. data/lib/wiki/views/client/js/underscore-min.js +0 -30
  50. data/lib/wiki/views/client/mkplugin.sh +0 -97
  51. data/lib/wiki/views/client/package.json +0 -36
  52. data/lib/wiki/views/client/runtests.html +0 -26
  53. data/lib/wiki/views/client/style.css +0 -339
  54. data/lib/wiki/views/client/test/mocha.css +0 -231
  55. data/lib/wiki/views/client/test/mocha.js +0 -5340
  56. data/lib/wiki/views/client/test/testclient.js +0 -17133
  57. data/lib/wiki/views/client/testclient.coffee +0 -18
  58. data/lib/wiki/views/client/theme/granite.css +0 -59
  59. data/lib/wiki/views/client/theme/stoneSeamless.jpg +0 -0
  60. data/lib/wiki/views/client/twitter-maintainance.jpg +0 -0
@@ -1,1923 +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
- 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
- })();