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.
- data/.DS_Store +0 -0
- data/README.md +11 -39
- data/lib/.DS_Store +0 -0
- data/lib/d3_rails/.DS_Store +0 -0
- data/lib/d3_rails/version.rb +1 -1
- data/vendor/.DS_Store +0 -0
- data/vendor/assets/.DS_Store +0 -0
- data/vendor/assets/javascripts/.DS_Store +0 -0
- data/vendor/assets/javascripts/d3.js +1 -4765
- data/vendor/assets/javascripts/d3.min.js +1 -0
- data/vendor/assets/javascripts/{d3.v2.js → d3.v3.js} +5585 -4802
- data/vendor/assets/javascripts/d3.v3.min.js +4 -0
- data/vendor/assets/stylesheets/.DS_Store +0 -0
- metadata +11 -42
- data/vendor/assets/javascripts/LICENSE.txt +0 -26
- data/vendor/assets/javascripts/colorbrewer.js +0 -32
- data/vendor/assets/javascripts/d3.chart.js +0 -984
- data/vendor/assets/javascripts/d3.geo.js +0 -938
- data/vendor/assets/javascripts/d3.geom.js +0 -835
- data/vendor/assets/javascripts/d3.layout.js +0 -1882
- data/vendor/assets/javascripts/d3.time.js +0 -726
- data/vendor/assets/javascripts/d3.v2.min.js +0 -4
- data/vendor/assets/javascripts/d3_csv.js +0 -92
- data/vendor/assets/javascripts/d3_rails.js +0 -1
- data/vendor/assets/javascripts/science.js +0 -225
- data/vendor/assets/javascripts/science.lin.js +0 -27
- data/vendor/assets/javascripts/science.stats.js +0 -720
- data/vendor/assets/stylesheets/LICENSE.txt +0 -38
- data/vendor/assets/stylesheets/azimuthal.css +0 -21
- data/vendor/assets/stylesheets/box.css +0 -4
- data/vendor/assets/stylesheets/bubble.css +0 -8
- data/vendor/assets/stylesheets/bullet.css +0 -10
- data/vendor/assets/stylesheets/bundle-radial.css +0 -9
- data/vendor/assets/stylesheets/bundle-treemap.css +0 -14
- data/vendor/assets/stylesheets/button.css +0 -35
- data/vendor/assets/stylesheets/calendar.css +0 -16
- data/vendor/assets/stylesheets/cartogram.css +0 -20
- data/vendor/assets/stylesheets/chord.css +0 -9
- data/vendor/assets/stylesheets/choropleth.css +0 -16
- data/vendor/assets/stylesheets/clock.css +0 -23
- data/vendor/assets/stylesheets/cluster.css +0 -15
- data/vendor/assets/stylesheets/colorbrewer.css +0 -1327
- data/vendor/assets/stylesheets/d3_rails.css +0 -6
- data/vendor/assets/stylesheets/force.css +0 -9
- data/vendor/assets/stylesheets/horizon.css +0 -9
- data/vendor/assets/stylesheets/kde.css +0 -9
- 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
|
-
})();
|