d3_rails 2.10.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/.DS_Store +0 -0
  2. data/README.md +11 -39
  3. data/lib/.DS_Store +0 -0
  4. data/lib/d3_rails/.DS_Store +0 -0
  5. data/lib/d3_rails/version.rb +1 -1
  6. data/vendor/.DS_Store +0 -0
  7. data/vendor/assets/.DS_Store +0 -0
  8. data/vendor/assets/javascripts/.DS_Store +0 -0
  9. data/vendor/assets/javascripts/d3.js +1 -4765
  10. data/vendor/assets/javascripts/d3.min.js +1 -0
  11. data/vendor/assets/javascripts/{d3.v2.js → d3.v3.js} +5585 -4802
  12. data/vendor/assets/javascripts/d3.v3.min.js +4 -0
  13. data/vendor/assets/stylesheets/.DS_Store +0 -0
  14. metadata +11 -42
  15. data/vendor/assets/javascripts/LICENSE.txt +0 -26
  16. data/vendor/assets/javascripts/colorbrewer.js +0 -32
  17. data/vendor/assets/javascripts/d3.chart.js +0 -984
  18. data/vendor/assets/javascripts/d3.geo.js +0 -938
  19. data/vendor/assets/javascripts/d3.geom.js +0 -835
  20. data/vendor/assets/javascripts/d3.layout.js +0 -1882
  21. data/vendor/assets/javascripts/d3.time.js +0 -726
  22. data/vendor/assets/javascripts/d3.v2.min.js +0 -4
  23. data/vendor/assets/javascripts/d3_csv.js +0 -92
  24. data/vendor/assets/javascripts/d3_rails.js +0 -1
  25. data/vendor/assets/javascripts/science.js +0 -225
  26. data/vendor/assets/javascripts/science.lin.js +0 -27
  27. data/vendor/assets/javascripts/science.stats.js +0 -720
  28. data/vendor/assets/stylesheets/LICENSE.txt +0 -38
  29. data/vendor/assets/stylesheets/azimuthal.css +0 -21
  30. data/vendor/assets/stylesheets/box.css +0 -4
  31. data/vendor/assets/stylesheets/bubble.css +0 -8
  32. data/vendor/assets/stylesheets/bullet.css +0 -10
  33. data/vendor/assets/stylesheets/bundle-radial.css +0 -9
  34. data/vendor/assets/stylesheets/bundle-treemap.css +0 -14
  35. data/vendor/assets/stylesheets/button.css +0 -35
  36. data/vendor/assets/stylesheets/calendar.css +0 -16
  37. data/vendor/assets/stylesheets/cartogram.css +0 -20
  38. data/vendor/assets/stylesheets/chord.css +0 -9
  39. data/vendor/assets/stylesheets/choropleth.css +0 -16
  40. data/vendor/assets/stylesheets/clock.css +0 -23
  41. data/vendor/assets/stylesheets/cluster.css +0 -15
  42. data/vendor/assets/stylesheets/colorbrewer.css +0 -1327
  43. data/vendor/assets/stylesheets/d3_rails.css +0 -6
  44. data/vendor/assets/stylesheets/force.css +0 -9
  45. data/vendor/assets/stylesheets/horizon.css +0 -9
  46. data/vendor/assets/stylesheets/kde.css +0 -9
  47. data/vendor/assets/stylesheets/line.css +0 -22
@@ -1,835 +0,0 @@
1
- (function(){d3.geom = {};
2
- /**
3
- * Computes a contour for a given input grid function using the <a
4
- * href="http://en.wikipedia.org/wiki/Marching_squares">marching
5
- * squares</a> algorithm. Returns the contour polygon as an array of points.
6
- *
7
- * @param grid a two-input function(x, y) that returns true for values
8
- * inside the contour and false for values outside the contour.
9
- * @param start an optional starting point [x, y] on the grid.
10
- * @returns polygon [[x1, y1], [x2, y2], …]
11
- */
12
- d3.geom.contour = function(grid, start) {
13
- var s = start || d3_geom_contourStart(grid), // starting point
14
- c = [], // contour polygon
15
- x = s[0], // current x position
16
- y = s[1], // current y position
17
- dx = 0, // next x direction
18
- dy = 0, // next y direction
19
- pdx = NaN, // previous x direction
20
- pdy = NaN, // previous y direction
21
- i = 0;
22
-
23
- do {
24
- // determine marching squares index
25
- i = 0;
26
- if (grid(x-1, y-1)) i += 1;
27
- if (grid(x, y-1)) i += 2;
28
- if (grid(x-1, y )) i += 4;
29
- if (grid(x, y )) i += 8;
30
-
31
- // determine next direction
32
- if (i === 6) {
33
- dx = pdy === -1 ? -1 : 1;
34
- dy = 0;
35
- } else if (i === 9) {
36
- dx = 0;
37
- dy = pdx === 1 ? -1 : 1;
38
- } else {
39
- dx = d3_geom_contourDx[i];
40
- dy = d3_geom_contourDy[i];
41
- }
42
-
43
- // update contour polygon
44
- if (dx != pdx && dy != pdy) {
45
- c.push([x, y]);
46
- pdx = dx;
47
- pdy = dy;
48
- }
49
-
50
- x += dx;
51
- y += dy;
52
- } while (s[0] != x || s[1] != y);
53
-
54
- return c;
55
- };
56
-
57
- // lookup tables for marching directions
58
- var d3_geom_contourDx = [1, 0, 1, 1,-1, 0,-1, 1,0, 0,0,0,-1, 0,-1,NaN],
59
- d3_geom_contourDy = [0,-1, 0, 0, 0,-1, 0, 0,1,-1,1,1, 0,-1, 0,NaN];
60
-
61
- function d3_geom_contourStart(grid) {
62
- var x = 0,
63
- y = 0;
64
-
65
- // search for a starting point; begin at origin
66
- // and proceed along outward-expanding diagonals
67
- while (true) {
68
- if (grid(x,y)) {
69
- return [x,y];
70
- }
71
- if (x === 0) {
72
- x = y + 1;
73
- y = 0;
74
- } else {
75
- x = x - 1;
76
- y = y + 1;
77
- }
78
- }
79
- }
80
- /**
81
- * Computes the 2D convex hull of a set of points using Graham's scanning
82
- * algorithm. The algorithm has been implemented as described in Cormen,
83
- * Leiserson, and Rivest's Introduction to Algorithms. The running time of
84
- * this algorithm is O(n log n), where n is the number of input points.
85
- *
86
- * @param vertices [[x1, y1], [x2, y2], …]
87
- * @returns polygon [[x1, y1], [x2, y2], …]
88
- */
89
- d3.geom.hull = function(vertices) {
90
- if (vertices.length < 3) return [];
91
-
92
- var len = vertices.length,
93
- plen = len - 1,
94
- points = [],
95
- stack = [],
96
- i, j, h = 0, x1, y1, x2, y2, u, v, a, sp;
97
-
98
- // find the starting ref point: leftmost point with the minimum y coord
99
- for (i=1; i<len; ++i) {
100
- if (vertices[i][1] < vertices[h][1]) {
101
- h = i;
102
- } else if (vertices[i][1] == vertices[h][1]) {
103
- h = (vertices[i][0] < vertices[h][0] ? i : h);
104
- }
105
- }
106
-
107
- // calculate polar angles from ref point and sort
108
- for (i=0; i<len; ++i) {
109
- if (i === h) continue;
110
- y1 = vertices[i][1] - vertices[h][1];
111
- x1 = vertices[i][0] - vertices[h][0];
112
- points.push({angle: Math.atan2(y1, x1), index: i});
113
- }
114
- points.sort(function(a, b) { return a.angle - b.angle; });
115
-
116
- // toss out duplicate angles
117
- a = points[0].angle;
118
- v = points[0].index;
119
- u = 0;
120
- for (i=1; i<plen; ++i) {
121
- j = points[i].index;
122
- if (a == points[i].angle) {
123
- // keep angle for point most distant from the reference
124
- x1 = vertices[v][0] - vertices[h][0];
125
- y1 = vertices[v][1] - vertices[h][1];
126
- x2 = vertices[j][0] - vertices[h][0];
127
- y2 = vertices[j][1] - vertices[h][1];
128
- if ((x1*x1 + y1*y1) >= (x2*x2 + y2*y2)) {
129
- points[i].index = -1;
130
- } else {
131
- points[u].index = -1;
132
- a = points[i].angle;
133
- u = i;
134
- v = j;
135
- }
136
- } else {
137
- a = points[i].angle;
138
- u = i;
139
- v = j;
140
- }
141
- }
142
-
143
- // initialize the stack
144
- stack.push(h);
145
- for (i=0, j=0; i<2; ++j) {
146
- if (points[j].index !== -1) {
147
- stack.push(points[j].index);
148
- i++;
149
- }
150
- }
151
- sp = stack.length;
152
-
153
- // do graham's scan
154
- for (; j<plen; ++j) {
155
- if (points[j].index === -1) continue; // skip tossed out points
156
- while (!d3_geom_hullCCW(stack[sp-2], stack[sp-1], points[j].index, vertices)) {
157
- --sp;
158
- }
159
- stack[sp++] = points[j].index;
160
- }
161
-
162
- // construct the hull
163
- var poly = [];
164
- for (i=0; i<sp; ++i) {
165
- poly.push(vertices[stack[i]]);
166
- }
167
- return poly;
168
- }
169
-
170
- // are three points in counter-clockwise order?
171
- function d3_geom_hullCCW(i1, i2, i3, v) {
172
- var t, a, b, c, d, e, f;
173
- t = v[i1]; a = t[0]; b = t[1];
174
- t = v[i2]; c = t[0]; d = t[1];
175
- t = v[i3]; e = t[0]; f = t[1];
176
- return ((f-b)*(c-a) - (d-b)*(e-a)) > 0;
177
- }
178
- // Note: requires coordinates to be counterclockwise and convex!
179
- d3.geom.polygon = function(coordinates) {
180
-
181
- coordinates.area = function() {
182
- var i = 0,
183
- n = coordinates.length,
184
- a = coordinates[n - 1][0] * coordinates[0][1],
185
- b = coordinates[n - 1][1] * coordinates[0][0];
186
- while (++i < n) {
187
- a += coordinates[i - 1][0] * coordinates[i][1];
188
- b += coordinates[i - 1][1] * coordinates[i][0];
189
- }
190
- return (b - a) * .5;
191
- };
192
-
193
- coordinates.centroid = function(k) {
194
- var i = -1,
195
- n = coordinates.length,
196
- x = 0,
197
- y = 0,
198
- a,
199
- b = coordinates[n - 1],
200
- c;
201
- if (!arguments.length) k = -1 / (6 * coordinates.area());
202
- while (++i < n) {
203
- a = b;
204
- b = coordinates[i];
205
- c = a[0] * b[1] - b[0] * a[1];
206
- x += (a[0] + b[0]) * c;
207
- y += (a[1] + b[1]) * c;
208
- }
209
- return [x * k, y * k];
210
- };
211
-
212
- // The Sutherland-Hodgman clipping algorithm.
213
- coordinates.clip = function(subject) {
214
- var input,
215
- i = -1,
216
- n = coordinates.length,
217
- j,
218
- m,
219
- a = coordinates[n - 1],
220
- b,
221
- c,
222
- d;
223
- while (++i < n) {
224
- input = subject.slice();
225
- subject.length = 0;
226
- b = coordinates[i];
227
- c = input[(m = input.length) - 1];
228
- j = -1;
229
- while (++j < m) {
230
- d = input[j];
231
- if (d3_geom_polygonInside(d, a, b)) {
232
- if (!d3_geom_polygonInside(c, a, b)) {
233
- subject.push(d3_geom_polygonIntersect(c, d, a, b));
234
- }
235
- subject.push(d);
236
- } else if (d3_geom_polygonInside(c, a, b)) {
237
- subject.push(d3_geom_polygonIntersect(c, d, a, b));
238
- }
239
- c = d;
240
- }
241
- a = b;
242
- }
243
- return subject;
244
- };
245
-
246
- return coordinates;
247
- };
248
-
249
- function d3_geom_polygonInside(p, a, b) {
250
- return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
251
- }
252
-
253
- // Intersect two infinite lines cd and ab.
254
- function d3_geom_polygonIntersect(c, d, a, b) {
255
- var x1 = c[0], x2 = d[0], x3 = a[0], x4 = b[0],
256
- y1 = c[1], y2 = d[1], y3 = a[1], y4 = b[1],
257
- x13 = x1 - x3,
258
- x21 = x2 - x1,
259
- x43 = x4 - x3,
260
- y13 = y1 - y3,
261
- y21 = y2 - y1,
262
- y43 = y4 - y3,
263
- ua = (x43 * y13 - y43 * x13) / (y43 * x21 - x43 * y21);
264
- return [x1 + ua * x21, y1 + ua * y21];
265
- }
266
- // Adapted from Nicolas Garcia Belmonte's JIT implementation:
267
- // http://blog.thejit.org/2010/02/12/voronoi-tessellation/
268
- // http://blog.thejit.org/assets/voronoijs/voronoi.js
269
- // See lib/jit/LICENSE for details.
270
-
271
- // Notes:
272
- //
273
- // This implementation does not clip the returned polygons, so if you want to
274
- // clip them to a particular shape you will need to do that either in SVG or by
275
- // post-processing with d3.geom.polygon's clip method.
276
- //
277
- // If any vertices are coincident or have NaN positions, the behavior of this
278
- // method is undefined. Most likely invalid polygons will be returned. You
279
- // should filter invalid points, and consolidate coincident points, before
280
- // computing the tessellation.
281
-
282
- /**
283
- * @param vertices [[x1, y1], [x2, y2], …]
284
- * @returns polygons [[[x1, y1], [x2, y2], …], …]
285
- */
286
- d3.geom.voronoi = function(vertices) {
287
- var polygons = vertices.map(function() { return []; });
288
-
289
- d3_voronoi_tessellate(vertices, function(e) {
290
- var s1,
291
- s2,
292
- x1,
293
- x2,
294
- y1,
295
- y2;
296
- if (e.a === 1 && e.b >= 0) {
297
- s1 = e.ep.r;
298
- s2 = e.ep.l;
299
- } else {
300
- s1 = e.ep.l;
301
- s2 = e.ep.r;
302
- }
303
- if (e.a === 1) {
304
- y1 = s1 ? s1.y : -1e6;
305
- x1 = e.c - e.b * y1;
306
- y2 = s2 ? s2.y : 1e6;
307
- x2 = e.c - e.b * y2;
308
- } else {
309
- x1 = s1 ? s1.x : -1e6;
310
- y1 = e.c - e.a * x1;
311
- x2 = s2 ? s2.x : 1e6;
312
- y2 = e.c - e.a * x2;
313
- }
314
- var v1 = [x1, y1],
315
- v2 = [x2, y2];
316
- polygons[e.region.l.index].push(v1, v2);
317
- polygons[e.region.r.index].push(v1, v2);
318
- });
319
-
320
- // Reconnect the polygon segments into counterclockwise loops.
321
- return polygons.map(function(polygon, i) {
322
- var cx = vertices[i][0],
323
- cy = vertices[i][1];
324
- polygon.forEach(function(v) {
325
- v.angle = Math.atan2(v[0] - cx, v[1] - cy);
326
- });
327
- return polygon.sort(function(a, b) {
328
- return a.angle - b.angle;
329
- }).filter(function(d, i) {
330
- return !i || (d.angle - polygon[i - 1].angle > 1e-10);
331
- });
332
- });
333
- };
334
-
335
- var d3_voronoi_opposite = {"l": "r", "r": "l"};
336
-
337
- function d3_voronoi_tessellate(vertices, callback) {
338
-
339
- var Sites = {
340
- list: vertices
341
- .map(function(v, i) {
342
- return {
343
- index: i,
344
- x: v[0],
345
- y: v[1]
346
- };
347
- })
348
- .sort(function(a, b) {
349
- return a.y < b.y ? -1
350
- : a.y > b.y ? 1
351
- : a.x < b.x ? -1
352
- : a.x > b.x ? 1
353
- : 0;
354
- }),
355
- bottomSite: null
356
- };
357
-
358
- var EdgeList = {
359
- list: [],
360
- leftEnd: null,
361
- rightEnd: null,
362
-
363
- init: function() {
364
- EdgeList.leftEnd = EdgeList.createHalfEdge(null, "l");
365
- EdgeList.rightEnd = EdgeList.createHalfEdge(null, "l");
366
- EdgeList.leftEnd.r = EdgeList.rightEnd;
367
- EdgeList.rightEnd.l = EdgeList.leftEnd;
368
- EdgeList.list.unshift(EdgeList.leftEnd, EdgeList.rightEnd);
369
- },
370
-
371
- createHalfEdge: function(edge, side) {
372
- return {
373
- edge: edge,
374
- side: side,
375
- vertex: null,
376
- "l": null,
377
- "r": null
378
- };
379
- },
380
-
381
- insert: function(lb, he) {
382
- he.l = lb;
383
- he.r = lb.r;
384
- lb.r.l = he;
385
- lb.r = he;
386
- },
387
-
388
- leftBound: function(p) {
389
- var he = EdgeList.leftEnd;
390
- do {
391
- he = he.r;
392
- } while (he != EdgeList.rightEnd && Geom.rightOf(he, p));
393
- he = he.l;
394
- return he;
395
- },
396
-
397
- del: function(he) {
398
- he.l.r = he.r;
399
- he.r.l = he.l;
400
- he.edge = null;
401
- },
402
-
403
- right: function(he) {
404
- return he.r;
405
- },
406
-
407
- left: function(he) {
408
- return he.l;
409
- },
410
-
411
- leftRegion: function(he) {
412
- return he.edge == null
413
- ? Sites.bottomSite
414
- : he.edge.region[he.side];
415
- },
416
-
417
- rightRegion: function(he) {
418
- return he.edge == null
419
- ? Sites.bottomSite
420
- : he.edge.region[d3_voronoi_opposite[he.side]];
421
- }
422
- };
423
-
424
- var Geom = {
425
-
426
- bisect: function(s1, s2) {
427
- var newEdge = {
428
- region: {"l": s1, "r": s2},
429
- ep: {"l": null, "r": null}
430
- };
431
-
432
- var dx = s2.x - s1.x,
433
- dy = s2.y - s1.y,
434
- adx = dx > 0 ? dx : -dx,
435
- ady = dy > 0 ? dy : -dy;
436
-
437
- newEdge.c = s1.x * dx + s1.y * dy
438
- + (dx * dx + dy * dy) * .5;
439
-
440
- if (adx > ady) {
441
- newEdge.a = 1;
442
- newEdge.b = dy / dx;
443
- newEdge.c /= dx;
444
- } else {
445
- newEdge.b = 1;
446
- newEdge.a = dx / dy;
447
- newEdge.c /= dy;
448
- }
449
-
450
- return newEdge;
451
- },
452
-
453
- intersect: function(el1, el2) {
454
- var e1 = el1.edge,
455
- e2 = el2.edge;
456
- if (!e1 || !e2 || (e1.region.r == e2.region.r)) {
457
- return null;
458
- }
459
- var d = (e1.a * e2.b) - (e1.b * e2.a);
460
- if (Math.abs(d) < 1e-10) {
461
- return null;
462
- }
463
- var xint = (e1.c * e2.b - e2.c * e1.b) / d,
464
- yint = (e2.c * e1.a - e1.c * e2.a) / d,
465
- e1r = e1.region.r,
466
- e2r = e2.region.r,
467
- el,
468
- e;
469
- if ((e1r.y < e2r.y) ||
470
- (e1r.y == e2r.y && e1r.x < e2r.x)) {
471
- el = el1;
472
- e = e1;
473
- } else {
474
- el = el2;
475
- e = e2;
476
- }
477
- var rightOfSite = (xint >= e.region.r.x);
478
- if ((rightOfSite && (el.side === "l")) ||
479
- (!rightOfSite && (el.side === "r"))) {
480
- return null;
481
- }
482
- return {
483
- x: xint,
484
- y: yint
485
- };
486
- },
487
-
488
- rightOf: function(he, p) {
489
- var e = he.edge,
490
- topsite = e.region.r,
491
- rightOfSite = (p.x > topsite.x);
492
-
493
- if (rightOfSite && (he.side === "l")) {
494
- return 1;
495
- }
496
- if (!rightOfSite && (he.side === "r")) {
497
- return 0;
498
- }
499
- if (e.a === 1) {
500
- var dyp = p.y - topsite.y,
501
- dxp = p.x - topsite.x,
502
- fast = 0,
503
- above = 0;
504
-
505
- if ((!rightOfSite && (e.b < 0)) ||
506
- (rightOfSite && (e.b >= 0))) {
507
- above = fast = (dyp >= e.b * dxp);
508
- } else {
509
- above = ((p.x + p.y * e.b) > e.c);
510
- if (e.b < 0) {
511
- above = !above;
512
- }
513
- if (!above) {
514
- fast = 1;
515
- }
516
- }
517
- if (!fast) {
518
- var dxs = topsite.x - e.region.l.x;
519
- above = (e.b * (dxp * dxp - dyp * dyp)) <
520
- (dxs * dyp * (1 + 2 * dxp / dxs + e.b * e.b));
521
-
522
- if (e.b < 0) {
523
- above = !above;
524
- }
525
- }
526
- } else /* e.b == 1 */ {
527
- var yl = e.c - e.a * p.x,
528
- t1 = p.y - yl,
529
- t2 = p.x - topsite.x,
530
- t3 = yl - topsite.y;
531
-
532
- above = (t1 * t1) > (t2 * t2 + t3 * t3);
533
- }
534
- return he.side === "l" ? above : !above;
535
- },
536
-
537
- endPoint: function(edge, side, site) {
538
- edge.ep[side] = site;
539
- if (!edge.ep[d3_voronoi_opposite[side]]) return;
540
- callback(edge);
541
- },
542
-
543
- distance: function(s, t) {
544
- var dx = s.x - t.x,
545
- dy = s.y - t.y;
546
- return Math.sqrt(dx * dx + dy * dy);
547
- }
548
- };
549
-
550
- var EventQueue = {
551
- list: [],
552
-
553
- insert: function(he, site, offset) {
554
- he.vertex = site;
555
- he.ystar = site.y + offset;
556
- for (var i=0, list=EventQueue.list, l=list.length; i<l; i++) {
557
- var next = list[i];
558
- if (he.ystar > next.ystar ||
559
- (he.ystar == next.ystar &&
560
- site.x > next.vertex.x)) {
561
- continue;
562
- } else {
563
- break;
564
- }
565
- }
566
- list.splice(i, 0, he);
567
- },
568
-
569
- del: function(he) {
570
- for (var i=0, ls=EventQueue.list, l=ls.length; i<l && (ls[i] != he); ++i) {}
571
- ls.splice(i, 1);
572
- },
573
-
574
- empty: function() { return EventQueue.list.length === 0; },
575
-
576
- nextEvent: function(he) {
577
- for (var i=0, ls=EventQueue.list, l=ls.length; i<l; ++i) {
578
- if (ls[i] == he) return ls[i+1];
579
- }
580
- return null;
581
- },
582
-
583
- min: function() {
584
- var elem = EventQueue.list[0];
585
- return {
586
- x: elem.vertex.x,
587
- y: elem.ystar
588
- };
589
- },
590
-
591
- extractMin: function() {
592
- return EventQueue.list.shift();
593
- }
594
- };
595
-
596
- EdgeList.init();
597
- Sites.bottomSite = Sites.list.shift();
598
-
599
- var newSite = Sites.list.shift(), newIntStar;
600
- var lbnd, rbnd, llbnd, rrbnd, bisector;
601
- var bot, top, temp, p, v;
602
- var e, pm;
603
-
604
- while (true) {
605
- if (!EventQueue.empty()) {
606
- newIntStar = EventQueue.min();
607
- }
608
- if (newSite && (EventQueue.empty()
609
- || newSite.y < newIntStar.y
610
- || (newSite.y == newIntStar.y
611
- && newSite.x < newIntStar.x))) { //new site is smallest
612
- lbnd = EdgeList.leftBound(newSite);
613
- rbnd = EdgeList.right(lbnd);
614
- bot = EdgeList.rightRegion(lbnd);
615
- e = Geom.bisect(bot, newSite);
616
- bisector = EdgeList.createHalfEdge(e, "l");
617
- EdgeList.insert(lbnd, bisector);
618
- p = Geom.intersect(lbnd, bisector);
619
- if (p) {
620
- EventQueue.del(lbnd);
621
- EventQueue.insert(lbnd, p, Geom.distance(p, newSite));
622
- }
623
- lbnd = bisector;
624
- bisector = EdgeList.createHalfEdge(e, "r");
625
- EdgeList.insert(lbnd, bisector);
626
- p = Geom.intersect(bisector, rbnd);
627
- if (p) {
628
- EventQueue.insert(bisector, p, Geom.distance(p, newSite));
629
- }
630
- newSite = Sites.list.shift();
631
- } else if (!EventQueue.empty()) { //intersection is smallest
632
- lbnd = EventQueue.extractMin();
633
- llbnd = EdgeList.left(lbnd);
634
- rbnd = EdgeList.right(lbnd);
635
- rrbnd = EdgeList.right(rbnd);
636
- bot = EdgeList.leftRegion(lbnd);
637
- top = EdgeList.rightRegion(rbnd);
638
- v = lbnd.vertex;
639
- Geom.endPoint(lbnd.edge, lbnd.side, v);
640
- Geom.endPoint(rbnd.edge, rbnd.side, v);
641
- EdgeList.del(lbnd);
642
- EventQueue.del(rbnd);
643
- EdgeList.del(rbnd);
644
- pm = "l";
645
- if (bot.y > top.y) {
646
- temp = bot;
647
- bot = top;
648
- top = temp;
649
- pm = "r";
650
- }
651
- e = Geom.bisect(bot, top);
652
- bisector = EdgeList.createHalfEdge(e, pm);
653
- EdgeList.insert(llbnd, bisector);
654
- Geom.endPoint(e, d3_voronoi_opposite[pm], v);
655
- p = Geom.intersect(llbnd, bisector);
656
- if (p) {
657
- EventQueue.del(llbnd);
658
- EventQueue.insert(llbnd, p, Geom.distance(p, bot));
659
- }
660
- p = Geom.intersect(bisector, rrbnd);
661
- if (p) {
662
- EventQueue.insert(bisector, p, Geom.distance(p, bot));
663
- }
664
- } else {
665
- break;
666
- }
667
- }//end while
668
-
669
- for (lbnd = EdgeList.right(EdgeList.leftEnd);
670
- lbnd != EdgeList.rightEnd;
671
- lbnd = EdgeList.right(lbnd)) {
672
- callback(lbnd.edge);
673
- }
674
- }
675
- /**
676
- * @param vertices [[x1, y1], [x2, y2], …]
677
- * @returns triangles [[[x1, y1], [x2, y2], [x3, y3]], …]
678
- */
679
- d3.geom.delaunay = function(vertices) {
680
- var edges = vertices.map(function() { return []; }),
681
- triangles = [];
682
-
683
- // Use the Voronoi tessellation to determine Delaunay edges.
684
- d3_voronoi_tessellate(vertices, function(e) {
685
- edges[e.region.l.index].push(vertices[e.region.r.index]);
686
- });
687
-
688
- // Reconnect the edges into counterclockwise triangles.
689
- edges.forEach(function(edge, i) {
690
- var v = vertices[i],
691
- cx = v[0],
692
- cy = v[1];
693
- edge.forEach(function(v) {
694
- v.angle = Math.atan2(v[0] - cx, v[1] - cy);
695
- });
696
- edge.sort(function(a, b) {
697
- return a.angle - b.angle;
698
- });
699
- for (var j = 0, m = edge.length - 1; j < m; j++) {
700
- triangles.push([v, edge[j], edge[j + 1]]);
701
- }
702
- });
703
-
704
- return triangles;
705
- };
706
- // Constructs a new quadtree for the specified array of points. A quadtree is a
707
- // two-dimensional recursive spatial subdivision. This implementation uses
708
- // square partitions, dividing each square into four equally-sized squares. Each
709
- // point exists in a unique node; if multiple points are in the same position,
710
- // some points may be stored on internal nodes rather than leaf nodes. Quadtrees
711
- // can be used to accelerate various spatial operations, such as the Barnes-Hut
712
- // approximation for computing n-body forces, or collision detection.
713
- d3.geom.quadtree = function(points, x1, y1, x2, y2) {
714
- var p,
715
- i = -1,
716
- n = points.length;
717
-
718
- // Type conversion for deprecated API.
719
- if (n && isNaN(points[0].x)) points = points.map(d3_geom_quadtreePoint);
720
-
721
- // Allow bounds to be specified explicitly.
722
- if (arguments.length < 5) {
723
- if (arguments.length === 3) {
724
- y2 = x2 = y1;
725
- y1 = x1;
726
- } else {
727
- x1 = y1 = Infinity;
728
- x2 = y2 = -Infinity;
729
-
730
- // Compute bounds.
731
- while (++i < n) {
732
- p = points[i];
733
- if (p.x < x1) x1 = p.x;
734
- if (p.y < y1) y1 = p.y;
735
- if (p.x > x2) x2 = p.x;
736
- if (p.y > y2) y2 = p.y;
737
- }
738
-
739
- // Squarify the bounds.
740
- var dx = x2 - x1,
741
- dy = y2 - y1;
742
- if (dx > dy) y2 = y1 + dx;
743
- else x2 = x1 + dy;
744
- }
745
- }
746
-
747
- // Recursively inserts the specified point p at the node n or one of its
748
- // descendants. The bounds are defined by [x1, x2] and [y1, y2].
749
- function insert(n, p, x1, y1, x2, y2) {
750
- if (isNaN(p.x) || isNaN(p.y)) return; // ignore invalid points
751
- if (n.leaf) {
752
- var v = n.point;
753
- if (v) {
754
- // If the point at this leaf node is at the same position as the new
755
- // point we are adding, we leave the point associated with the
756
- // internal node while adding the new point to a child node. This
757
- // avoids infinite recursion.
758
- if ((Math.abs(v.x - p.x) + Math.abs(v.y - p.y)) < .01) {
759
- insertChild(n, p, x1, y1, x2, y2);
760
- } else {
761
- n.point = null;
762
- insertChild(n, v, x1, y1, x2, y2);
763
- insertChild(n, p, x1, y1, x2, y2);
764
- }
765
- } else {
766
- n.point = p;
767
- }
768
- } else {
769
- insertChild(n, p, x1, y1, x2, y2);
770
- }
771
- }
772
-
773
- // Recursively inserts the specified point p into a descendant of node n. The
774
- // bounds are defined by [x1, x2] and [y1, y2].
775
- function insertChild(n, p, x1, y1, x2, y2) {
776
- // Compute the split point, and the quadrant in which to insert p.
777
- var sx = (x1 + x2) * .5,
778
- sy = (y1 + y2) * .5,
779
- right = p.x >= sx,
780
- bottom = p.y >= sy,
781
- i = (bottom << 1) + right;
782
-
783
- // Recursively insert into the child node.
784
- n.leaf = false;
785
- n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode());
786
-
787
- // Update the bounds as we recurse.
788
- if (right) x1 = sx; else x2 = sx;
789
- if (bottom) y1 = sy; else y2 = sy;
790
- insert(n, p, x1, y1, x2, y2);
791
- }
792
-
793
- // Create the root node.
794
- var root = d3_geom_quadtreeNode();
795
-
796
- root.add = function(p) {
797
- insert(root, p, x1, y1, x2, y2);
798
- };
799
-
800
- root.visit = function(f) {
801
- d3_geom_quadtreeVisit(f, root, x1, y1, x2, y2);
802
- };
803
-
804
- // Insert all points.
805
- points.forEach(root.add);
806
- return root;
807
- };
808
-
809
- function d3_geom_quadtreeNode() {
810
- return {
811
- leaf: true,
812
- nodes: [],
813
- point: null
814
- };
815
- }
816
-
817
- function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
818
- if (!f(node, x1, y1, x2, y2)) {
819
- var sx = (x1 + x2) * .5,
820
- sy = (y1 + y2) * .5,
821
- children = node.nodes;
822
- if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy);
823
- if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy);
824
- if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2);
825
- if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2);
826
- }
827
- }
828
-
829
- function d3_geom_quadtreePoint(p) {
830
- return {
831
- x: p[0],
832
- y: p[1]
833
- };
834
- }
835
- })();