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,938 +0,0 @@
1
- (function(){d3.geo = {};
2
-
3
- var d3_geo_radians = Math.PI / 180;
4
- // TODO clip input coordinates on opposite hemisphere
5
- d3.geo.azimuthal = function() {
6
- var mode = "orthographic", // or stereographic, gnomonic, equidistant or equalarea
7
- origin,
8
- scale = 200,
9
- translate = [480, 250],
10
- x0,
11
- y0,
12
- cy0,
13
- sy0;
14
-
15
- function azimuthal(coordinates) {
16
- var x1 = coordinates[0] * d3_geo_radians - x0,
17
- y1 = coordinates[1] * d3_geo_radians,
18
- cx1 = Math.cos(x1),
19
- sx1 = Math.sin(x1),
20
- cy1 = Math.cos(y1),
21
- sy1 = Math.sin(y1),
22
- cc = mode !== "orthographic" ? sy0 * sy1 + cy0 * cy1 * cx1 : null,
23
- c,
24
- k = mode === "stereographic" ? 1 / (1 + cc)
25
- : mode === "gnomonic" ? 1 / cc
26
- : mode === "equidistant" ? (c = Math.acos(cc), c ? c / Math.sin(c) : 0)
27
- : mode === "equalarea" ? Math.sqrt(2 / (1 + cc))
28
- : 1,
29
- x = k * cy1 * sx1,
30
- y = k * (sy0 * cy1 * cx1 - cy0 * sy1);
31
- return [
32
- scale * x + translate[0],
33
- scale * y + translate[1]
34
- ];
35
- }
36
-
37
- azimuthal.invert = function(coordinates) {
38
- var x = (coordinates[0] - translate[0]) / scale,
39
- y = (coordinates[1] - translate[1]) / scale,
40
- p = Math.sqrt(x * x + y * y),
41
- c = mode === "stereographic" ? 2 * Math.atan(p)
42
- : mode === "gnomonic" ? Math.atan(p)
43
- : mode === "equidistant" ? p
44
- : mode === "equalarea" ? 2 * Math.asin(.5 * p)
45
- : Math.asin(p),
46
- sc = Math.sin(c),
47
- cc = Math.cos(c);
48
- return [
49
- (x0 + Math.atan2(x * sc, p * cy0 * cc + y * sy0 * sc)) / d3_geo_radians,
50
- Math.asin(cc * sy0 - (p ? (y * sc * cy0) / p : 0)) / d3_geo_radians
51
- ];
52
- };
53
-
54
- azimuthal.mode = function(x) {
55
- if (!arguments.length) return mode;
56
- mode = x + "";
57
- return azimuthal;
58
- };
59
-
60
- azimuthal.origin = function(x) {
61
- if (!arguments.length) return origin;
62
- origin = x;
63
- x0 = origin[0] * d3_geo_radians;
64
- y0 = origin[1] * d3_geo_radians;
65
- cy0 = Math.cos(y0);
66
- sy0 = Math.sin(y0);
67
- return azimuthal;
68
- };
69
-
70
- azimuthal.scale = function(x) {
71
- if (!arguments.length) return scale;
72
- scale = +x;
73
- return azimuthal;
74
- };
75
-
76
- azimuthal.translate = function(x) {
77
- if (!arguments.length) return translate;
78
- translate = [+x[0], +x[1]];
79
- return azimuthal;
80
- };
81
-
82
- return azimuthal.origin([0, 0]);
83
- };
84
- // Derived from Tom Carden's Albers implementation for Protovis.
85
- // http://gist.github.com/476238
86
- // http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html
87
-
88
- d3.geo.albers = function() {
89
- var origin = [-98, 38],
90
- parallels = [29.5, 45.5],
91
- scale = 1000,
92
- translate = [480, 250],
93
- lng0, // d3_geo_radians * origin[0]
94
- n,
95
- C,
96
- p0;
97
-
98
- function albers(coordinates) {
99
- var t = n * (d3_geo_radians * coordinates[0] - lng0),
100
- p = Math.sqrt(C - 2 * n * Math.sin(d3_geo_radians * coordinates[1])) / n;
101
- return [
102
- scale * p * Math.sin(t) + translate[0],
103
- scale * (p * Math.cos(t) - p0) + translate[1]
104
- ];
105
- }
106
-
107
- albers.invert = function(coordinates) {
108
- var x = (coordinates[0] - translate[0]) / scale,
109
- y = (coordinates[1] - translate[1]) / scale,
110
- p0y = p0 + y,
111
- t = Math.atan2(x, p0y),
112
- p = Math.sqrt(x * x + p0y * p0y);
113
- return [
114
- (lng0 + t / n) / d3_geo_radians,
115
- Math.asin((C - p * p * n * n) / (2 * n)) / d3_geo_radians
116
- ];
117
- };
118
-
119
- function reload() {
120
- var phi1 = d3_geo_radians * parallels[0],
121
- phi2 = d3_geo_radians * parallels[1],
122
- lat0 = d3_geo_radians * origin[1],
123
- s = Math.sin(phi1),
124
- c = Math.cos(phi1);
125
- lng0 = d3_geo_radians * origin[0];
126
- n = .5 * (s + Math.sin(phi2));
127
- C = c * c + 2 * n * s;
128
- p0 = Math.sqrt(C - 2 * n * Math.sin(lat0)) / n;
129
- return albers;
130
- }
131
-
132
- albers.origin = function(x) {
133
- if (!arguments.length) return origin;
134
- origin = [+x[0], +x[1]];
135
- return reload();
136
- };
137
-
138
- albers.parallels = function(x) {
139
- if (!arguments.length) return parallels;
140
- parallels = [+x[0], +x[1]];
141
- return reload();
142
- };
143
-
144
- albers.scale = function(x) {
145
- if (!arguments.length) return scale;
146
- scale = +x;
147
- return albers;
148
- };
149
-
150
- albers.translate = function(x) {
151
- if (!arguments.length) return translate;
152
- translate = [+x[0], +x[1]];
153
- return albers;
154
- };
155
-
156
- return reload();
157
- };
158
-
159
- // A composite projection for the United States, 960x500. The set of standard
160
- // parallels for each region comes from USGS, which is published here:
161
- // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
162
- // TODO allow the composite projection to be rescaled?
163
- d3.geo.albersUsa = function() {
164
- var lower48 = d3.geo.albers();
165
-
166
- var alaska = d3.geo.albers()
167
- .origin([-160, 60])
168
- .parallels([55, 65]);
169
-
170
- var hawaii = d3.geo.albers()
171
- .origin([-160, 20])
172
- .parallels([8, 18]);
173
-
174
- var puertoRico = d3.geo.albers()
175
- .origin([-60, 10])
176
- .parallels([8, 18]);
177
-
178
- function albersUsa(coordinates) {
179
- var lon = coordinates[0],
180
- lat = coordinates[1];
181
- return (lat > 50 ? alaska
182
- : lon < -140 ? hawaii
183
- : lat < 21 ? puertoRico
184
- : lower48)(coordinates);
185
- }
186
-
187
- albersUsa.scale = function(x) {
188
- if (!arguments.length) return lower48.scale();
189
- lower48.scale(x);
190
- alaska.scale(x * .6);
191
- hawaii.scale(x);
192
- puertoRico.scale(x * 1.5);
193
- return albersUsa.translate(lower48.translate());
194
- };
195
-
196
- albersUsa.translate = function(x) {
197
- if (!arguments.length) return lower48.translate();
198
- var dz = lower48.scale() / 1000,
199
- dx = x[0],
200
- dy = x[1];
201
- lower48.translate(x);
202
- alaska.translate([dx - 400 * dz, dy + 170 * dz]);
203
- hawaii.translate([dx - 190 * dz, dy + 200 * dz]);
204
- puertoRico.translate([dx + 580 * dz, dy + 430 * dz]);
205
- return albersUsa;
206
- };
207
-
208
- return albersUsa.scale(lower48.scale());
209
- };
210
- d3.geo.bonne = function() {
211
- var scale = 200,
212
- translate = [480, 250],
213
- x0, // origin longitude in radians
214
- y0, // origin latitude in radians
215
- y1, // parallel latitude in radians
216
- c1; // cot(y1)
217
-
218
- function bonne(coordinates) {
219
- var x = coordinates[0] * d3_geo_radians - x0,
220
- y = coordinates[1] * d3_geo_radians - y0;
221
- if (y1) {
222
- var p = c1 + y1 - y, E = x * Math.cos(y) / p;
223
- x = p * Math.sin(E);
224
- y = p * Math.cos(E) - c1;
225
- } else {
226
- x *= Math.cos(y);
227
- y *= -1;
228
- }
229
- return [
230
- scale * x + translate[0],
231
- scale * y + translate[1]
232
- ];
233
- }
234
-
235
- bonne.invert = function(coordinates) {
236
- var x = (coordinates[0] - translate[0]) / scale,
237
- y = (coordinates[1] - translate[1]) / scale;
238
- if (y1) {
239
- var c = c1 + y, p = Math.sqrt(x * x + c * c);
240
- y = c1 + y1 - p;
241
- x = x0 + p * Math.atan2(x, c) / Math.cos(y);
242
- } else {
243
- y *= -1;
244
- x /= Math.cos(y);
245
- }
246
- return [
247
- x / d3_geo_radians,
248
- y / d3_geo_radians
249
- ];
250
- };
251
-
252
- // 90° for Werner, 0° for Sinusoidal
253
- bonne.parallel = function(x) {
254
- if (!arguments.length) return y1 / d3_geo_radians;
255
- c1 = 1 / Math.tan(y1 = x * d3_geo_radians);
256
- return bonne;
257
- };
258
-
259
- bonne.origin = function(x) {
260
- if (!arguments.length) return [x0 / d3_geo_radians, y0 / d3_geo_radians];
261
- x0 = x[0] * d3_geo_radians;
262
- y0 = x[1] * d3_geo_radians;
263
- return bonne;
264
- };
265
-
266
- bonne.scale = function(x) {
267
- if (!arguments.length) return scale;
268
- scale = +x;
269
- return bonne;
270
- };
271
-
272
- bonne.translate = function(x) {
273
- if (!arguments.length) return translate;
274
- translate = [+x[0], +x[1]];
275
- return bonne;
276
- };
277
-
278
- return bonne.origin([0, 0]).parallel(45);
279
- };
280
- d3.geo.equirectangular = function() {
281
- var scale = 500,
282
- translate = [480, 250];
283
-
284
- function equirectangular(coordinates) {
285
- var x = coordinates[0] / 360,
286
- y = -coordinates[1] / 360;
287
- return [
288
- scale * x + translate[0],
289
- scale * y + translate[1]
290
- ];
291
- }
292
-
293
- equirectangular.invert = function(coordinates) {
294
- var x = (coordinates[0] - translate[0]) / scale,
295
- y = (coordinates[1] - translate[1]) / scale;
296
- return [
297
- 360 * x,
298
- -360 * y
299
- ];
300
- };
301
-
302
- equirectangular.scale = function(x) {
303
- if (!arguments.length) return scale;
304
- scale = +x;
305
- return equirectangular;
306
- };
307
-
308
- equirectangular.translate = function(x) {
309
- if (!arguments.length) return translate;
310
- translate = [+x[0], +x[1]];
311
- return equirectangular;
312
- };
313
-
314
- return equirectangular;
315
- };
316
- d3.geo.mercator = function() {
317
- var scale = 500,
318
- translate = [480, 250];
319
-
320
- function mercator(coordinates) {
321
- var x = coordinates[0] / 360,
322
- y = -(Math.log(Math.tan(Math.PI / 4 + coordinates[1] * d3_geo_radians / 2)) / d3_geo_radians) / 360;
323
- return [
324
- scale * x + translate[0],
325
- scale * Math.max(-.5, Math.min(.5, y)) + translate[1]
326
- ];
327
- }
328
-
329
- mercator.invert = function(coordinates) {
330
- var x = (coordinates[0] - translate[0]) / scale,
331
- y = (coordinates[1] - translate[1]) / scale;
332
- return [
333
- 360 * x,
334
- 2 * Math.atan(Math.exp(-360 * y * d3_geo_radians)) / d3_geo_radians - 90
335
- ];
336
- };
337
-
338
- mercator.scale = function(x) {
339
- if (!arguments.length) return scale;
340
- scale = +x;
341
- return mercator;
342
- };
343
-
344
- mercator.translate = function(x) {
345
- if (!arguments.length) return translate;
346
- translate = [+x[0], +x[1]];
347
- return mercator;
348
- };
349
-
350
- return mercator;
351
- };
352
- function d3_geo_type(types, defaultValue) {
353
- return function(object) {
354
- return object && object.type in types ? types[object.type](object) : defaultValue;
355
- };
356
- }
357
- /**
358
- * Returns a function that, given a GeoJSON object (e.g., a feature), returns
359
- * the corresponding SVG path. The function can be customized by overriding the
360
- * projection. Point features are mapped to circles with a default radius of
361
- * 4.5px; the radius can be specified either as a constant or a function that
362
- * is evaluated per object.
363
- */
364
- d3.geo.path = function() {
365
- var pointRadius = 4.5,
366
- pointCircle = d3_path_circle(pointRadius),
367
- projection = d3.geo.albersUsa();
368
-
369
- function path(d, i) {
370
- if (typeof pointRadius === "function") {
371
- pointCircle = d3_path_circle(pointRadius.apply(this, arguments));
372
- }
373
- return pathType(d) || null;
374
- }
375
-
376
- function project(coordinates) {
377
- return projection(coordinates).join(",");
378
- }
379
-
380
- var pathType = d3_geo_type({
381
-
382
- FeatureCollection: function(o) {
383
- var path = [],
384
- features = o.features,
385
- i = -1, // features.index
386
- n = features.length;
387
- while (++i < n) path.push(pathType(features[i].geometry));
388
- return path.join("");
389
- },
390
-
391
- Feature: function(o) {
392
- return pathType(o.geometry);
393
- },
394
-
395
- Point: function(o) {
396
- return "M" + project(o.coordinates) + pointCircle;
397
- },
398
-
399
- MultiPoint: function(o) {
400
- var path = [],
401
- coordinates = o.coordinates,
402
- i = -1, // coordinates.index
403
- n = coordinates.length;
404
- while (++i < n) path.push("M", project(coordinates[i]), pointCircle);
405
- return path.join("");
406
- },
407
-
408
- LineString: function(o) {
409
- var path = ["M"],
410
- coordinates = o.coordinates,
411
- i = -1, // coordinates.index
412
- n = coordinates.length;
413
- while (++i < n) path.push(project(coordinates[i]), "L");
414
- path.pop();
415
- return path.join("");
416
- },
417
-
418
- MultiLineString: function(o) {
419
- var path = [],
420
- coordinates = o.coordinates,
421
- i = -1, // coordinates.index
422
- n = coordinates.length,
423
- subcoordinates, // coordinates[i]
424
- j, // subcoordinates.index
425
- m; // subcoordinates.length
426
- while (++i < n) {
427
- subcoordinates = coordinates[i];
428
- j = -1;
429
- m = subcoordinates.length;
430
- path.push("M");
431
- while (++j < m) path.push(project(subcoordinates[j]), "L");
432
- path.pop();
433
- }
434
- return path.join("");
435
- },
436
-
437
- Polygon: function(o) {
438
- var path = [],
439
- coordinates = o.coordinates,
440
- i = -1, // coordinates.index
441
- n = coordinates.length,
442
- subcoordinates, // coordinates[i]
443
- j, // subcoordinates.index
444
- m; // subcoordinates.length
445
- while (++i < n) {
446
- subcoordinates = coordinates[i];
447
- j = -1;
448
- if ((m = subcoordinates.length - 1) > 0) {
449
- path.push("M");
450
- while (++j < m) path.push(project(subcoordinates[j]), "L");
451
- path[path.length - 1] = "Z";
452
- }
453
- }
454
- return path.join("");
455
- },
456
-
457
- MultiPolygon: function(o) {
458
- var path = [],
459
- coordinates = o.coordinates,
460
- i = -1, // coordinates index
461
- n = coordinates.length,
462
- subcoordinates, // coordinates[i]
463
- j, // subcoordinates index
464
- m, // subcoordinates.length
465
- subsubcoordinates, // subcoordinates[j]
466
- k, // subsubcoordinates index
467
- p; // subsubcoordinates.length
468
- while (++i < n) {
469
- subcoordinates = coordinates[i];
470
- j = -1;
471
- m = subcoordinates.length;
472
- while (++j < m) {
473
- subsubcoordinates = subcoordinates[j];
474
- k = -1;
475
- if ((p = subsubcoordinates.length - 1) > 0) {
476
- path.push("M");
477
- while (++k < p) path.push(project(subsubcoordinates[k]), "L");
478
- path[path.length - 1] = "Z";
479
- }
480
- }
481
- }
482
- return path.join("");
483
- },
484
-
485
- GeometryCollection: function(o) {
486
- var path = [],
487
- geometries = o.geometries,
488
- i = -1, // geometries index
489
- n = geometries.length;
490
- while (++i < n) path.push(pathType(geometries[i]));
491
- return path.join("");
492
- }
493
-
494
- });
495
-
496
- var areaType = path.area = d3_geo_type({
497
-
498
- FeatureCollection: function(o) {
499
- var area = 0,
500
- features = o.features,
501
- i = -1, // features.index
502
- n = features.length;
503
- while (++i < n) area += areaType(features[i]);
504
- return area;
505
- },
506
-
507
- Feature: function(o) {
508
- return areaType(o.geometry);
509
- },
510
-
511
- Polygon: function(o) {
512
- return polygonArea(o.coordinates);
513
- },
514
-
515
- MultiPolygon: function(o) {
516
- var sum = 0,
517
- coordinates = o.coordinates,
518
- i = -1, // coordinates index
519
- n = coordinates.length;
520
- while (++i < n) sum += polygonArea(coordinates[i]);
521
- return sum;
522
- },
523
-
524
- GeometryCollection: function(o) {
525
- var sum = 0,
526
- geometries = o.geometries,
527
- i = -1, // geometries index
528
- n = geometries.length;
529
- while (++i < n) sum += areaType(geometries[i]);
530
- return sum;
531
- }
532
-
533
- }, 0);
534
-
535
- function polygonArea(coordinates) {
536
- var sum = area(coordinates[0]), // exterior ring
537
- i = 0, // coordinates.index
538
- n = coordinates.length;
539
- while (++i < n) sum -= area(coordinates[i]); // holes
540
- return sum;
541
- }
542
-
543
- function polygonCentroid(coordinates) {
544
- var polygon = d3.geom.polygon(coordinates[0].map(projection)), // exterior ring
545
- area = polygon.area(),
546
- centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1),
547
- x = centroid[0],
548
- y = centroid[1],
549
- z = area,
550
- i = 0, // coordinates index
551
- n = coordinates.length;
552
- while (++i < n) {
553
- polygon = d3.geom.polygon(coordinates[i].map(projection)); // holes
554
- area = polygon.area();
555
- centroid = polygon.centroid(area < 0 ? (area *= -1, 1) : -1);
556
- x -= centroid[0];
557
- y -= centroid[1];
558
- z -= area;
559
- }
560
- return [x, y, 6 * z]; // weighted centroid
561
- }
562
-
563
- var centroidType = path.centroid = d3_geo_type({
564
-
565
- // TODO FeatureCollection
566
- // TODO Point
567
- // TODO MultiPoint
568
- // TODO LineString
569
- // TODO MultiLineString
570
- // TODO GeometryCollection
571
-
572
- Feature: function(o) {
573
- return centroidType(o.geometry);
574
- },
575
-
576
- Polygon: function(o) {
577
- var centroid = polygonCentroid(o.coordinates);
578
- return [centroid[0] / centroid[2], centroid[1] / centroid[2]];
579
- },
580
-
581
- MultiPolygon: function(o) {
582
- var area = 0,
583
- coordinates = o.coordinates,
584
- centroid,
585
- x = 0,
586
- y = 0,
587
- z = 0,
588
- i = -1, // coordinates index
589
- n = coordinates.length;
590
- while (++i < n) {
591
- centroid = polygonCentroid(coordinates[i]);
592
- x += centroid[0];
593
- y += centroid[1];
594
- z += centroid[2];
595
- }
596
- return [x / z, y / z];
597
- }
598
-
599
- });
600
-
601
- function area(coordinates) {
602
- return Math.abs(d3.geom.polygon(coordinates.map(projection)).area());
603
- }
604
-
605
- path.projection = function(x) {
606
- projection = x;
607
- return path;
608
- };
609
-
610
- path.pointRadius = function(x) {
611
- if (typeof x === "function") pointRadius = x;
612
- else {
613
- pointRadius = +x;
614
- pointCircle = d3_path_circle(pointRadius);
615
- }
616
- return path;
617
- };
618
-
619
- return path;
620
- };
621
-
622
- function d3_path_circle(radius) {
623
- return "m0," + radius
624
- + "a" + radius + "," + radius + " 0 1,1 0," + (-2 * radius)
625
- + "a" + radius + "," + radius + " 0 1,1 0," + (+2 * radius)
626
- + "z";
627
- }
628
- /**
629
- * Given a GeoJSON object, returns the corresponding bounding box. The bounding
630
- * box is represented by a two-dimensional array: [[left, bottom], [right,
631
- * top]], where left is the minimum longitude, bottom is the minimum latitude,
632
- * right is maximum longitude, and top is the maximum latitude.
633
- */
634
- d3.geo.bounds = function(feature) {
635
- var left = Infinity,
636
- bottom = Infinity,
637
- right = -Infinity,
638
- top = -Infinity;
639
- d3_geo_bounds(feature, function(x, y) {
640
- if (x < left) left = x;
641
- if (x > right) right = x;
642
- if (y < bottom) bottom = y;
643
- if (y > top) top = y;
644
- });
645
- return [[left, bottom], [right, top]];
646
- };
647
-
648
- function d3_geo_bounds(o, f) {
649
- if (o.type in d3_geo_boundsTypes) d3_geo_boundsTypes[o.type](o, f);
650
- }
651
-
652
- var d3_geo_boundsTypes = {
653
- Feature: d3_geo_boundsFeature,
654
- FeatureCollection: d3_geo_boundsFeatureCollection,
655
- GeometryCollection: d3_geo_boundsGeometryCollection,
656
- LineString: d3_geo_boundsLineString,
657
- MultiLineString: d3_geo_boundsMultiLineString,
658
- MultiPoint: d3_geo_boundsLineString,
659
- MultiPolygon: d3_geo_boundsMultiPolygon,
660
- Point: d3_geo_boundsPoint,
661
- Polygon: d3_geo_boundsPolygon
662
- };
663
-
664
- function d3_geo_boundsFeature(o, f) {
665
- d3_geo_bounds(o.geometry, f);
666
- }
667
-
668
- function d3_geo_boundsFeatureCollection(o, f) {
669
- for (var a = o.features, i = 0, n = a.length; i < n; i++) {
670
- d3_geo_bounds(a[i].geometry, f);
671
- }
672
- }
673
-
674
- function d3_geo_boundsGeometryCollection(o, f) {
675
- for (var a = o.geometries, i = 0, n = a.length; i < n; i++) {
676
- d3_geo_bounds(a[i], f);
677
- }
678
- }
679
-
680
- function d3_geo_boundsLineString(o, f) {
681
- for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
682
- f.apply(null, a[i]);
683
- }
684
- }
685
-
686
- function d3_geo_boundsMultiLineString(o, f) {
687
- for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
688
- for (var b = a[i], j = 0, m = b.length; j < m; j++) {
689
- f.apply(null, b[j]);
690
- }
691
- }
692
- }
693
-
694
- function d3_geo_boundsMultiPolygon(o, f) {
695
- for (var a = o.coordinates, i = 0, n = a.length; i < n; i++) {
696
- for (var b = a[i][0], j = 0, m = b.length; j < m; j++) {
697
- f.apply(null, b[j]);
698
- }
699
- }
700
- }
701
-
702
- function d3_geo_boundsPoint(o, f) {
703
- f.apply(null, o.coordinates);
704
- }
705
-
706
- function d3_geo_boundsPolygon(o, f) {
707
- for (var a = o.coordinates[0], i = 0, n = a.length; i < n; i++) {
708
- f.apply(null, a[i]);
709
- }
710
- }
711
- // TODO breakAtDateLine?
712
-
713
- d3.geo.circle = function() {
714
- var origin = [0, 0],
715
- degrees = 90 - 1e-2,
716
- radians = degrees * d3_geo_radians,
717
- arc = d3.geo.greatArc().target(Object);
718
-
719
- function circle() {
720
- // TODO render a circle as a Polygon
721
- }
722
-
723
- function visible(point) {
724
- return arc.distance(point) < radians;
725
- }
726
-
727
- circle.clip = function(d) {
728
- arc.source(typeof origin === "function" ? origin.apply(this, arguments) : origin);
729
- return clipType(d);
730
- };
731
-
732
- var clipType = d3_geo_type({
733
-
734
- FeatureCollection: function(o) {
735
- var features = o.features.map(clipType).filter(Object);
736
- return features && (o = Object.create(o), o.features = features, o);
737
- },
738
-
739
- Feature: function(o) {
740
- var geometry = clipType(o.geometry);
741
- return geometry && (o = Object.create(o), o.geometry = geometry, o);
742
- },
743
-
744
- Point: function(o) {
745
- return visible(o.coordinates) && o;
746
- },
747
-
748
- MultiPoint: function(o) {
749
- var coordinates = o.coordinates.filter(visible);
750
- return coordinates.length && {
751
- type: o.type,
752
- coordinates: coordinates
753
- };
754
- },
755
-
756
- LineString: function(o) {
757
- var coordinates = clip(o.coordinates);
758
- return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
759
- },
760
-
761
- MultiLineString: function(o) {
762
- var coordinates = o.coordinates.map(clip).filter(function(d) { return d.length; });
763
- return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
764
- },
765
-
766
- Polygon: function(o) {
767
- var coordinates = o.coordinates.map(clip);
768
- return coordinates[0].length && (o = Object.create(o), o.coordinates = coordinates, o);
769
- },
770
-
771
- MultiPolygon: function(o) {
772
- var coordinates = o.coordinates.map(function(d) { return d.map(clip); }).filter(function(d) { return d[0].length; });
773
- return coordinates.length && (o = Object.create(o), o.coordinates = coordinates, o);
774
- },
775
-
776
- GeometryCollection: function(o) {
777
- var geometries = o.geometries.map(clipType).filter(Object);
778
- return geometries.length && (o = Object.create(o), o.geometries = geometries, o);
779
- }
780
-
781
- });
782
-
783
- function clip(coordinates) {
784
- var i = -1,
785
- n = coordinates.length,
786
- clipped = [],
787
- p0,
788
- p1,
789
- p2,
790
- d0,
791
- d1;
792
-
793
- while (++i < n) {
794
- d1 = arc.distance(p2 = coordinates[i]);
795
- if (d1 < radians) {
796
- if (p1) clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
797
- clipped.push(p2);
798
- p0 = p1 = null;
799
- } else {
800
- p1 = p2;
801
- if (!p0 && clipped.length) {
802
- clipped.push(d3_geo_greatArcInterpolate(clipped[clipped.length - 1], p1)((radians - d0) / (d1 - d0)));
803
- p0 = p1;
804
- }
805
- }
806
- d0 = d1;
807
- }
808
-
809
- if (p1 && clipped.length) {
810
- d1 = arc.distance(p2 = clipped[0]);
811
- clipped.push(d3_geo_greatArcInterpolate(p1, p2)((d0 - radians) / (d0 - d1)));
812
- }
813
-
814
- return resample(clipped);
815
- }
816
-
817
- // Resample coordinates, creating great arcs between each.
818
- function resample(coordinates) {
819
- var i = 0,
820
- n = coordinates.length,
821
- j,
822
- m,
823
- resampled = n ? [coordinates[0]] : coordinates,
824
- resamples,
825
- origin = arc.source();
826
-
827
- while (++i < n) {
828
- resamples = arc.source(coordinates[i - 1])(coordinates[i]).coordinates;
829
- for (j = 0, m = resamples.length; ++j < m;) resampled.push(resamples[j]);
830
- }
831
-
832
- arc.source(origin);
833
- return resampled;
834
- }
835
-
836
- circle.origin = function(x) {
837
- if (!arguments.length) return origin;
838
- origin = x;
839
- return circle;
840
- };
841
-
842
- circle.angle = function(x) {
843
- if (!arguments.length) return degrees;
844
- radians = (degrees = +x) * d3_geo_radians;
845
- return circle;
846
- };
847
-
848
- // Precision is specified in degrees.
849
- circle.precision = function(x) {
850
- if (!arguments.length) return arc.precision();
851
- arc.precision(x);
852
- return circle;
853
- };
854
-
855
- return circle;
856
- }
857
- d3.geo.greatArc = function() {
858
- var source = d3_geo_greatArcSource,
859
- target = d3_geo_greatArcTarget,
860
- precision = 6 * d3_geo_radians;
861
-
862
- function greatArc() {
863
- var a = typeof source === "function" ? source.apply(this, arguments) : source,
864
- b = typeof target === "function" ? target.apply(this, arguments) : target,
865
- i = d3_geo_greatArcInterpolate(a, b),
866
- dt = precision / i.d,
867
- t = 0,
868
- coordinates = [a];
869
- while ((t += dt) < 1) coordinates.push(i(t));
870
- coordinates.push(b);
871
- return {
872
- type: "LineString",
873
- coordinates: coordinates
874
- };
875
- }
876
-
877
- // Length returned in radians; multiply by radius for distance.
878
- greatArc.distance = function() {
879
- var a = typeof source === "function" ? source.apply(this, arguments) : source,
880
- b = typeof target === "function" ? target.apply(this, arguments) : target;
881
- return d3_geo_greatArcInterpolate(a, b).d;
882
- };
883
-
884
- greatArc.source = function(x) {
885
- if (!arguments.length) return source;
886
- source = x;
887
- return greatArc;
888
- };
889
-
890
- greatArc.target = function(x) {
891
- if (!arguments.length) return target;
892
- target = x;
893
- return greatArc;
894
- };
895
-
896
- // Precision is specified in degrees.
897
- greatArc.precision = function(x) {
898
- if (!arguments.length) return precision / d3_geo_radians;
899
- precision = x * d3_geo_radians;
900
- return greatArc;
901
- };
902
-
903
- return greatArc;
904
- };
905
-
906
- function d3_geo_greatArcSource(d) {
907
- return d.source;
908
- }
909
-
910
- function d3_geo_greatArcTarget(d) {
911
- return d.target;
912
- }
913
-
914
- function d3_geo_greatArcInterpolate(a, b) {
915
- var x0 = a[0] * d3_geo_radians, cx0 = Math.cos(x0), sx0 = Math.sin(x0),
916
- y0 = a[1] * d3_geo_radians, cy0 = Math.cos(y0), sy0 = Math.sin(y0),
917
- x1 = b[0] * d3_geo_radians, cx1 = Math.cos(x1), sx1 = Math.sin(x1),
918
- y1 = b[1] * d3_geo_radians, cy1 = Math.cos(y1), sy1 = Math.sin(y1),
919
- d = interpolate.d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))),
920
- sd = Math.sin(d);
921
-
922
- // From http://williams.best.vwh.net/avform.htm#Intermediate
923
- function interpolate(t) {
924
- var A = Math.sin(d - (t *= d)) / sd,
925
- B = Math.sin(t) / sd,
926
- x = A * cy0 * cx0 + B * cy1 * cx1,
927
- y = A * cy0 * sx0 + B * cy1 * sx1,
928
- z = A * sy0 + B * sy1;
929
- return [
930
- Math.atan2(y, x) / d3_geo_radians,
931
- Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_geo_radians
932
- ];
933
- }
934
-
935
- return interpolate;
936
- }
937
- d3.geo.greatCircle = d3.geo.circle;
938
- })();