d3js-rails 3.0.0.pre → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module D3js
2
2
  module Rails
3
- VERSION = "3.0.0.pre"
3
+ VERSION = "3.0.0"
4
4
  end
5
5
  end
@@ -12,12 +12,9 @@
12
12
  };
13
13
  }
14
14
  d3 = {
15
- version: "3.0.0pre"
15
+ version: "3.0.0"
16
16
  };
17
- var π = Math.PI, ε = 1e-6, εε = .001, d3_radians = π / 180, d3_degrees = 180 / π;
18
- function d3_zero() {
19
- return 0;
20
- }
17
+ var π = Math.PI, ε = 1e-6, d3_radians = π / 180, d3_degrees = 180 / π;
21
18
  function d3_target(d) {
22
19
  return d.target;
23
20
  }
@@ -234,9 +231,17 @@
234
231
  return s;
235
232
  };
236
233
  d3.quantile = function(values, p) {
237
- var H = (values.length - 1) * p + 1, h = Math.floor(H), v = values[h - 1], e = H - h;
234
+ var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;
238
235
  return e ? v + e * (values[h] - v) : v;
239
236
  };
237
+ d3.shuffle = function(array) {
238
+ var m = array.length, t, i;
239
+ while (m) {
240
+ i = Math.random() * m-- | 0;
241
+ t = array[m], array[m] = array[i], array[i] = t;
242
+ }
243
+ return array;
244
+ };
240
245
  d3.transpose = function(matrix) {
241
246
  return d3.zip.apply(d3, matrix);
242
247
  };
@@ -390,13 +395,14 @@
390
395
  return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);
391
396
  };
392
397
  d3.xhr = function(url, mimeType, callback) {
393
- var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new XMLHttpRequest();
394
- request.onreadystatechange = function() {
395
- if (request.readyState === 4) {
396
- var s = request.status;
397
- !s && request.response || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request);
398
- }
398
+ var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new (window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)();
399
+ "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {
400
+ request.readyState > 3 && respond();
399
401
  };
402
+ function respond() {
403
+ var s = request.status;
404
+ !s && request.responseText || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request);
405
+ }
400
406
  request.onprogress = function(event) {
401
407
  var o = d3.event;
402
408
  d3.event = event;
@@ -430,7 +436,7 @@
430
436
  if (arguments.length === 2 && typeof data === "function") callback = data, data = null;
431
437
  request.open(method, url, true);
432
438
  if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*";
433
- for (var name in headers) request.setRequestHeader(name, headers[name]);
439
+ if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]);
434
440
  if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);
435
441
  if (callback != null) xhr.on("error", callback).on("load", function(request) {
436
442
  callback(null, request);
@@ -445,8 +451,13 @@
445
451
  d3.rebind(xhr, dispatch, "on");
446
452
  if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType,
447
453
  mimeType = null;
448
- return callback == null ? xhr : xhr.get(callback);
454
+ return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));
449
455
  };
456
+ function d3_xhr_fixCallback(callback) {
457
+ return callback.length === 1 ? function(error, request) {
458
+ callback(error == null ? request : null);
459
+ } : callback;
460
+ }
450
461
  d3.text = function() {
451
462
  return d3.xhr.apply(d3, arguments).response(d3_text);
452
463
  };
@@ -3703,21 +3714,21 @@
3703
3714
  this.on("mousedown.drag", mousedown).on("touchstart.drag", mousedown);
3704
3715
  }
3705
3716
  function mousedown() {
3706
- var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, touchId = d3.event.touches && d3.event.changedTouches[0].identifier, offset, origin_ = point(), moved = 0;
3707
- var w = d3.select(window).on(touchId ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true);
3717
+ var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null, offset, origin_ = point(), moved = 0;
3718
+ var w = d3.select(window).on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true);
3708
3719
  if (origin) {
3709
3720
  offset = origin.apply(target, arguments);
3710
3721
  offset = [ offset.x - origin_[0], offset.y - origin_[1] ];
3711
3722
  } else {
3712
3723
  offset = [ 0, 0 ];
3713
3724
  }
3714
- if (!touchId) d3_eventCancel();
3725
+ if (touchId == null) d3_eventCancel();
3715
3726
  event_({
3716
3727
  type: "dragstart"
3717
3728
  });
3718
3729
  function point() {
3719
3730
  var p = target.parentNode;
3720
- return touchId ? d3.touches(p).filter(function(p) {
3731
+ return touchId != null ? d3.touches(p).filter(function(p) {
3721
3732
  return p.identifier === touchId;
3722
3733
  })[0] : d3.mouse(p);
3723
3734
  }
@@ -3743,7 +3754,7 @@
3743
3754
  d3_eventCancel();
3744
3755
  if (d3.event.target === eventTarget) w.on("click.drag", click, true);
3745
3756
  }
3746
- w.on(touchId ? "touchmove.drag-" + touchId : "mousemove.drag", null).on(touchId ? "touchend.drag-" + touchId : "mouseup.drag", null);
3757
+ w.on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", null).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", null);
3747
3758
  }
3748
3759
  function click() {
3749
3760
  d3_eventCancel();
@@ -3855,8 +3866,8 @@
3855
3866
  translate0 = null;
3856
3867
  }
3857
3868
  function dblclick() {
3858
- var p = d3.mouse(this), l = location(p);
3859
- scaleTo(d3.event.shiftKey ? scale / 2 : scale * 2);
3869
+ var p = d3.mouse(this), l = location(p), k = Math.log(scale) / Math.LN2;
3870
+ scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1));
3860
3871
  translateTo(p, l);
3861
3872
  dispatch(event.of(this, arguments));
3862
3873
  }
@@ -4267,8 +4278,7 @@
4267
4278
  this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag);
4268
4279
  };
4269
4280
  function dragmove(d) {
4270
- d.px = d3.event.x;
4271
- d.py = d3.event.y;
4281
+ d.px = d3.event.x, d.py = d3.event.y;
4272
4282
  force.resume();
4273
4283
  }
4274
4284
  return d3.rebind(force, event, "on");
@@ -4281,6 +4291,7 @@
4281
4291
  }
4282
4292
  function d3_layout_forceMouseover(d) {
4283
4293
  d.fixed |= 4;
4294
+ d.px = d.x, d.py = d.y;
4284
4295
  }
4285
4296
  function d3_layout_forceMouseout(d) {
4286
4297
  d.fixed &= 3;
@@ -4616,10 +4627,8 @@
4616
4627
  }
4617
4628
  d3.layout.hierarchy = function() {
4618
4629
  var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue;
4619
- function recurse(data, depth, nodes) {
4620
- var childs = children.call(hierarchy, data, depth), node = d3_layout_hierarchyInline ? data : {
4621
- data: data
4622
- };
4630
+ function recurse(node, depth, nodes) {
4631
+ var childs = children.call(hierarchy, node, depth);
4623
4632
  node.depth = depth;
4624
4633
  nodes.push(node);
4625
4634
  if (childs && (n = childs.length)) {
@@ -4633,7 +4642,7 @@
4633
4642
  if (sort) c.sort(sort);
4634
4643
  if (value) node.value = v;
4635
4644
  } else if (value) {
4636
- node.value = +value.call(hierarchy, data, depth) || 0;
4645
+ node.value = +value.call(hierarchy, node, depth) || 0;
4637
4646
  }
4638
4647
  return node;
4639
4648
  }
@@ -4643,7 +4652,7 @@
4643
4652
  var i = -1, n, j = depth + 1;
4644
4653
  while (++i < n) v += revalue(children[i], j);
4645
4654
  } else if (value) {
4646
- v = +value.call(hierarchy, d3_layout_hierarchyInline ? node : node.data, depth) || 0;
4655
+ v = +value.call(hierarchy, node, depth) || 0;
4647
4656
  }
4648
4657
  if (value) node.value = v;
4649
4658
  return v;
@@ -4676,11 +4685,8 @@
4676
4685
  };
4677
4686
  function d3_layout_hierarchyRebind(object, hierarchy) {
4678
4687
  d3.rebind(object, hierarchy, "sort", "children", "value");
4688
+ object.nodes = object;
4679
4689
  object.links = d3_layout_hierarchyLinks;
4680
- object.nodes = function(d) {
4681
- d3_layout_hierarchyInline = true;
4682
- return (object.nodes = object)(d);
4683
- };
4684
4690
  return object;
4685
4691
  }
4686
4692
  function d3_layout_hierarchyChildren(d) {
@@ -4702,7 +4708,6 @@
4702
4708
  });
4703
4709
  }));
4704
4710
  }
4705
- var d3_layout_hierarchyInline = false;
4706
4711
  d3.layout.pack = function() {
4707
4712
  var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ];
4708
4713
  function pack(d, i) {
@@ -5324,76 +5329,168 @@
5324
5329
  d3.csv = d3_dsv(",", "text/csv");
5325
5330
  d3.tsv = d3_dsv(" ", "text/tab-separated-values");
5326
5331
  d3.geo = {};
5327
- function d3_geo_type(types) {
5328
- for (var type in d3_geo_typeDefaults) {
5329
- if (!(type in types)) {
5330
- types[type] = d3_geo_typeDefaults[type];
5331
- }
5332
+ d3.geo.stream = function(object, listener) {
5333
+ if (d3_geo_streamObjectType.hasOwnProperty(object.type)) {
5334
+ d3_geo_streamObjectType[object.type](object, listener);
5335
+ } else {
5336
+ d3_geo_streamGeometry(object, listener);
5337
+ }
5338
+ };
5339
+ function d3_geo_streamGeometry(geometry, listener) {
5340
+ if (d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) {
5341
+ d3_geo_streamGeometryType[geometry.type](geometry, listener);
5332
5342
  }
5333
- return types;
5334
5343
  }
5335
- var d3_geo_typeDefaults = {
5336
- Feature: function(feature) {
5337
- this.geometry(feature.geometry);
5338
- },
5339
- FeatureCollection: function(collection) {
5340
- var features = collection.features, i = -1, n = features.length;
5341
- while (++i < n) this.Feature(features[i]);
5344
+ var d3_geo_streamObjectType = {
5345
+ Feature: function(feature, listener) {
5346
+ d3_geo_streamGeometry(feature.geometry, listener);
5342
5347
  },
5343
- GeometryCollection: function(collection) {
5344
- var geometries = collection.geometries, i = -1, n = geometries.length;
5345
- while (++i < n) this.geometry(geometries[i]);
5348
+ FeatureCollection: function(object, listener) {
5349
+ var features = object.features, i = -1, n = features.length;
5350
+ while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener);
5346
5351
  },
5347
- LineString: function(lineString) {
5348
- this.line(lineString.coordinates);
5349
- },
5350
- MultiLineString: function(multiLineString) {
5351
- var coordinates = multiLineString.coordinates, i = -1, n = coordinates.length;
5352
- while (++i < n) this.line(coordinates[i]);
5353
- },
5354
- MultiPoint: function(multiPoint) {
5355
- var coordinates = multiPoint.coordinates, i = -1, n = coordinates.length;
5356
- while (++i < n) this.point(coordinates[i]);
5357
- },
5358
- MultiPolygon: function(multiPolygon) {
5359
- var coordinates = multiPolygon.coordinates, i = -1, n = coordinates.length;
5360
- while (++i < n) this.polygon(coordinates[i]);
5352
+ GeometryCollection: function(object, listener) {
5353
+ var geometries = object.geometries, i = -1, n = geometries.length;
5354
+ while (++i < n) d3_geo_streamGeometry(geometries[i], listener);
5355
+ }
5356
+ };
5357
+ var d3_geo_streamGeometryType = {
5358
+ Sphere: function(object, listener) {
5359
+ listener.sphere();
5361
5360
  },
5362
- Point: function(point) {
5363
- this.point(point.coordinates);
5361
+ Point: function(object, listener) {
5362
+ var coordinate = object.coordinates;
5363
+ listener.point(coordinate[0], coordinate[1]);
5364
5364
  },
5365
- Polygon: function(polygon) {
5366
- this.polygon(polygon.coordinates);
5365
+ MultiPoint: function(object, listener) {
5366
+ var coordinates = object.coordinates, i = -1, n = coordinates.length, coordinate;
5367
+ while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
5367
5368
  },
5368
- object: function(object) {
5369
- return d3_geo_typeObjects.hasOwnProperty(object.type) ? this[object.type](object) : this.geometry(object);
5369
+ LineString: function(object, listener) {
5370
+ d3_geo_streamLine(object.coordinates, listener, 0);
5370
5371
  },
5371
- geometry: function(geometry) {
5372
- return d3_geo_typeGeometries.hasOwnProperty(geometry.type) ? this[geometry.type](geometry) : null;
5372
+ MultiLineString: function(object, listener) {
5373
+ var coordinates = object.coordinates, i = -1, n = coordinates.length;
5374
+ while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0);
5373
5375
  },
5374
- point: d3_noop,
5375
- line: function(coordinates) {
5376
- var i = -1, n = coordinates.length;
5377
- while (++i < n) this.point(coordinates[i]);
5376
+ Polygon: function(object, listener) {
5377
+ d3_geo_streamPolygon(object.coordinates, listener);
5378
5378
  },
5379
- polygon: function(coordinates) {
5380
- var i = -1, n = coordinates.length;
5381
- while (++i < n) this.line(coordinates[i]);
5379
+ MultiPolygon: function(object, listener) {
5380
+ var coordinates = object.coordinates, i = -1, n = coordinates.length;
5381
+ while (++i < n) d3_geo_streamPolygon(coordinates[i], listener);
5382
5382
  }
5383
5383
  };
5384
- var d3_geo_typeGeometries = {
5385
- LineString: 1,
5386
- MultiLineString: 1,
5387
- MultiPoint: 1,
5388
- MultiPolygon: 1,
5389
- Point: 1,
5390
- Polygon: 1
5391
- };
5392
- var d3_geo_typeObjects = {
5393
- Feature: 1,
5394
- FeatureCollection: 1,
5395
- GeometryCollection: 1
5396
- };
5384
+ function d3_geo_streamLine(coordinates, listener, closed) {
5385
+ var i = -1, n = coordinates.length - closed, coordinate;
5386
+ listener.lineStart();
5387
+ while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
5388
+ listener.lineEnd();
5389
+ }
5390
+ function d3_geo_streamPolygon(coordinates, listener) {
5391
+ var i = -1, n = coordinates.length;
5392
+ listener.polygonStart();
5393
+ while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1);
5394
+ listener.polygonEnd();
5395
+ }
5396
+ function d3_geo_spherical(cartesian) {
5397
+ return [ Math.atan2(cartesian[1], cartesian[0]), Math.asin(Math.max(-1, Math.min(1, cartesian[2]))) ];
5398
+ }
5399
+ function d3_geo_sphericalEqual(a, b) {
5400
+ return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε;
5401
+ }
5402
+ function d3_geo_cartesian(spherical) {
5403
+ var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ);
5404
+ return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ];
5405
+ }
5406
+ function d3_geo_cartesianDot(a, b) {
5407
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
5408
+ }
5409
+ function d3_geo_cartesianCross(a, b) {
5410
+ return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ];
5411
+ }
5412
+ function d3_geo_cartesianAdd(a, b) {
5413
+ a[0] += b[0];
5414
+ a[1] += b[1];
5415
+ a[2] += b[2];
5416
+ }
5417
+ function d3_geo_cartesianScale(vector, k) {
5418
+ return [ vector[0] * k, vector[1] * k, vector[2] * k ];
5419
+ }
5420
+ function d3_geo_cartesianNormalize(d) {
5421
+ var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
5422
+ d[0] /= l;
5423
+ d[1] /= l;
5424
+ d[2] /= l;
5425
+ }
5426
+ function d3_geo_resample(project) {
5427
+ var δ2 = .5, maxDepth = 16;
5428
+ function resample(stream) {
5429
+ var λ0, x0, y0, a0, b0, c0;
5430
+ var resample = {
5431
+ point: point,
5432
+ lineStart: lineStart,
5433
+ lineEnd: lineEnd,
5434
+ polygonStart: function() {
5435
+ stream.polygonStart();
5436
+ resample.lineStart = polygonLineStart;
5437
+ },
5438
+ polygonEnd: function() {
5439
+ stream.polygonEnd();
5440
+ resample.lineStart = lineStart;
5441
+ }
5442
+ };
5443
+ function point(x, y) {
5444
+ x = project(x, y);
5445
+ stream.point(x[0], x[1]);
5446
+ }
5447
+ function lineStart() {
5448
+ x0 = NaN;
5449
+ resample.point = linePoint;
5450
+ stream.lineStart();
5451
+ }
5452
+ function linePoint(λ, φ) {
5453
+ var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ);
5454
+ resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
5455
+ stream.point(x0, y0);
5456
+ }
5457
+ function lineEnd() {
5458
+ resample.point = point;
5459
+ stream.lineEnd();
5460
+ }
5461
+ function polygonLineStart() {
5462
+ var λ00, φ00, x00, y00, a00, b00, c00;
5463
+ lineStart();
5464
+ resample.point = function(λ, φ) {
5465
+ linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
5466
+ resample.point = linePoint;
5467
+ };
5468
+ resample.lineEnd = function() {
5469
+ resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
5470
+ resample.lineEnd = lineEnd;
5471
+ lineEnd();
5472
+ };
5473
+ }
5474
+ return resample;
5475
+ }
5476
+ function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
5477
+ var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy;
5478
+ if (d2 > 4 * δ2 && depth--) {
5479
+ var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;
5480
+ if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3) {
5481
+ resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
5482
+ stream.point(x2, y2);
5483
+ resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
5484
+ }
5485
+ }
5486
+ }
5487
+ resample.precision = function(_) {
5488
+ if (!arguments.length) return Math.sqrt(δ2);
5489
+ maxDepth = (δ2 = _ * _) > 0 && 16;
5490
+ return resample;
5491
+ };
5492
+ return resample;
5493
+ }
5397
5494
  d3.geo.albersUsa = function() {
5398
5495
  var lower48 = d3.geo.albers();
5399
5496
  var alaska = d3.geo.albers().rotate([ 160, 0 ]).center([ 0, 60 ]).parallels([ 55, 65 ]);
@@ -5406,15 +5503,6 @@
5406
5503
  var lon = point[0], lat = point[1];
5407
5504
  return lat > 50 ? alaska : lon < -140 ? hawaii : lat < 21 ? puertoRico : lower48;
5408
5505
  }
5409
- albersUsa.point = function(coordinates, context) {
5410
- return projection(coordinates).point(coordinates, context);
5411
- };
5412
- albersUsa.line = function(coordinates, context) {
5413
- return projection(coordinates[0]).line(coordinates, context);
5414
- };
5415
- albersUsa.polygon = function(coordinates, context) {
5416
- return projection(coordinates[0][0]).polygon(coordinates, context);
5417
- };
5418
5506
  albersUsa.scale = function(x) {
5419
5507
  if (!arguments.length) return lower48.scale();
5420
5508
  lower48.scale(x);
@@ -5469,39 +5557,122 @@
5469
5557
  (d3.geo.azimuthalEquidistant = function() {
5470
5558
  return d3_geo_projection(d3_geo_azimuthalEquidistant);
5471
5559
  }).raw = d3_geo_azimuthalEquidistant;
5472
- d3.geo.bounds = d3_geo_bounds(d3_identity);
5560
+ d3.geo.bounds = d3_geo_bounds();
5473
5561
  function d3_geo_bounds(projection) {
5474
- var x0, y0, x1, y1, bounds = d3_geo_type({
5475
- point: function(point) {
5476
- point = projection(point);
5477
- var x = point[0], y = point[1];
5478
- if (x < x0) x0 = x;
5479
- if (x > x1) x1 = x;
5480
- if (y < y0) y0 = y;
5481
- if (y > y1) y1 = y;
5562
+ var x0, y0, x1, y1;
5563
+ var bound = {
5564
+ point: boundPoint,
5565
+ lineStart: d3_noop,
5566
+ lineEnd: d3_noop,
5567
+ polygonStart: function() {
5568
+ bound.lineEnd = boundPolygonLineEnd;
5482
5569
  },
5483
- polygon: function(coordinates) {
5484
- this.line(coordinates[0]);
5570
+ polygonEnd: function() {
5571
+ bound.point = boundPoint;
5485
5572
  }
5486
- });
5573
+ };
5574
+ var projectBound = projection ? projection.stream(bound) : bound;
5575
+ function boundPoint(x, y) {
5576
+ if (x < x0) x0 = x;
5577
+ if (x > x1) x1 = x;
5578
+ if (y < y0) y0 = y;
5579
+ if (y > y1) y1 = y;
5580
+ }
5581
+ function boundPolygonLineEnd() {
5582
+ bound.point = bound.lineEnd = d3_noop;
5583
+ }
5487
5584
  return function(feature) {
5488
5585
  y1 = x1 = -(x0 = y0 = Infinity);
5489
- bounds.object(feature);
5586
+ d3.geo.stream(feature, projectBound);
5490
5587
  return [ [ x0, y0 ], [ x1, y1 ] ];
5491
5588
  };
5492
5589
  }
5590
+ d3.geo.centroid = function(object) {
5591
+ d3_geo_centroidDimension = d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
5592
+ d3.geo.stream(object, d3_geo_centroid);
5593
+ var m;
5594
+ if (d3_geo_centroidW && Math.abs(m = Math.sqrt(d3_geo_centroidX * d3_geo_centroidX + d3_geo_centroidY * d3_geo_centroidY + d3_geo_centroidZ * d3_geo_centroidZ)) > ε) {
5595
+ return [ Math.atan2(d3_geo_centroidY, d3_geo_centroidX) * d3_degrees, Math.asin(Math.max(-1, Math.min(1, d3_geo_centroidZ / m))) * d3_degrees ];
5596
+ }
5597
+ };
5598
+ var d3_geo_centroidDimension, d3_geo_centroidW, d3_geo_centroidX, d3_geo_centroidY, d3_geo_centroidZ;
5599
+ var d3_geo_centroid = {
5600
+ sphere: d3_noop,
5601
+ point: d3_geo_centroidPoint,
5602
+ lineStart: d3_geo_centroidLineStart,
5603
+ lineEnd: d3_geo_centroidLineEnd,
5604
+ polygonStart: function() {
5605
+ d3_geo_centroidDimension = 2;
5606
+ d3_geo_centroid.lineStart = d3_geo_centroidRingStart;
5607
+ },
5608
+ polygonEnd: function() {
5609
+ d3_geo_centroid.lineStart = d3_geo_centroidLineStart;
5610
+ }
5611
+ };
5612
+ function d3_geo_centroidPoint(λ, φ) {
5613
+ if (d3_geo_centroidDimension) return;
5614
+ ++d3_geo_centroidW;
5615
+ λ *= d3_radians;
5616
+ var cosφ = Math.cos(φ *= d3_radians);
5617
+ d3_geo_centroidX += (cosφ * Math.cos(λ) - d3_geo_centroidX) / d3_geo_centroidW;
5618
+ d3_geo_centroidY += (cosφ * Math.sin(λ) - d3_geo_centroidY) / d3_geo_centroidW;
5619
+ d3_geo_centroidZ += (Math.sin(φ) - d3_geo_centroidZ) / d3_geo_centroidW;
5620
+ }
5621
+ function d3_geo_centroidRingStart() {
5622
+ var λ00, φ00;
5623
+ if (d3_geo_centroidDimension < 2) {
5624
+ d3_geo_centroidDimension = 2;
5625
+ d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
5626
+ }
5627
+ d3_geo_centroidDimension = 1;
5628
+ d3_geo_centroidLineStart();
5629
+ d3_geo_centroidDimension = 2;
5630
+ var linePoint = d3_geo_centroid.point;
5631
+ d3_geo_centroid.point = function(λ, φ) {
5632
+ linePoint(λ00 = λ, φ00 = φ);
5633
+ };
5634
+ d3_geo_centroid.lineEnd = function() {
5635
+ d3_geo_centroid.point(λ00, φ00);
5636
+ d3_geo_centroidLineEnd();
5637
+ d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd;
5638
+ };
5639
+ }
5640
+ function d3_geo_centroidLineStart() {
5641
+ var x0, y0, z0;
5642
+ if (d3_geo_centroidDimension !== 1) {
5643
+ if (d3_geo_centroidDimension < 1) {
5644
+ d3_geo_centroidDimension = 1;
5645
+ d3_geo_centroidW = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
5646
+ } else return;
5647
+ }
5648
+ d3_geo_centroid.point = function(λ, φ) {
5649
+ λ *= d3_radians;
5650
+ var cosφ = Math.cos(φ *= d3_radians);
5651
+ x0 = cosφ * Math.cos(λ);
5652
+ y0 = cosφ * Math.sin(λ);
5653
+ z0 = Math.sin(φ);
5654
+ d3_geo_centroid.point = nextPoint;
5655
+ };
5656
+ function nextPoint(λ, φ) {
5657
+ λ *= d3_radians;
5658
+ var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
5659
+ d3_geo_centroidW += w;
5660
+ d3_geo_centroidX += w * (x0 + (x0 = x));
5661
+ d3_geo_centroidY += w * (y0 + (y0 = y));
5662
+ d3_geo_centroidZ += w * (z0 + (z0 = z));
5663
+ }
5664
+ }
5665
+ function d3_geo_centroidLineEnd() {
5666
+ d3_geo_centroid.point = d3_geo_centroidPoint;
5667
+ }
5493
5668
  d3.geo.circle = function() {
5494
- var origin = [ 0, 0 ], angle, precision = 6, rotate, interpolate;
5669
+ var origin = [ 0, 0 ], angle, precision = 6, interpolate;
5495
5670
  function circle() {
5496
- var o = typeof origin === "function" ? origin.apply(this, arguments) : origin;
5497
- rotate = d3_geo_rotation(-o[0] * d3_radians, -o[1] * d3_radians, 0);
5498
- var ring = [];
5499
- d3_geo_circleInterpolateCircle(interpolate, {
5500
- lineTo: function(λ, φ) {
5501
- var point = rotate.invert(λ, φ);
5502
- point[0] *= d3_degrees;
5503
- point[1] *= d3_degrees;
5504
- ring.push(point);
5671
+ var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(center[0] * d3_radians, center[1] * d3_radians, 0), ring = [];
5672
+ interpolate(null, null, 1, {
5673
+ point: function(x, y) {
5674
+ ring.push(x = rotate(x, y));
5675
+ x[0] *= d3_degrees, x[1] *= d3_degrees;
5505
5676
  }
5506
5677
  });
5507
5678
  return {
@@ -5521,116 +5692,130 @@
5521
5692
  };
5522
5693
  circle.precision = function(_) {
5523
5694
  if (!arguments.length) return precision;
5524
- interpolate = d3_geo_circleInterpolate(radians, (precision = +_) * d3_radians);
5695
+ interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians);
5525
5696
  return circle;
5526
5697
  };
5527
5698
  return circle.angle(90);
5528
5699
  };
5529
- function d3_geo_circleClip(degrees, rotate) {
5530
- var radians = degrees * d3_radians, cr = Math.cos(radians), center = [ cr, 0, 0 ], angle = d3_geo_circleAngle(center), interpolate = d3_geo_circleInterpolate(radians, 6 * d3_radians);
5531
- return {
5532
- point: function(coordinates, context) {
5533
- if (visible(coordinates = rotate(coordinates))) {
5534
- context.point(coordinates[0], coordinates[1]);
5535
- }
5536
- },
5537
- line: function(coordinates, context) {
5538
- clipLine(coordinates, context);
5539
- },
5540
- polygon: function(polygon, context) {
5541
- d3_geo_circleClipPolygon(polygon, context, clipLine, interpolate, angle);
5542
- }
5543
- };
5544
- function visible(point) {
5545
- return Math.cos(point[1]) * Math.cos(point[0]) > cr;
5546
- }
5547
- function clipLine(coordinates, context, winding) {
5548
- if (!(n = coordinates.length)) return;
5549
- var point0 = rotate(coordinates[0]), point2, inside = visible(point0), keepWinding = winding != null, closed = keepWinding && inside, n, move0, line0;
5550
- if (inside) context.moveTo((move0 = point0)[0], point0[1]);
5551
- for (var i = 1; i < n; i++) {
5552
- var point1 = rotate(coordinates[i]), v = visible(point1);
5553
- if (v !== inside) {
5554
- if (inside = v) {
5555
- point2 = intersect(point1, point0);
5556
- if (!line0 || Math.abs(line0[0] - point2[0]) > ε || Math.abs(line0[1] - point2[1]) > ε) {
5557
- if (move0) keepWinding = false;
5558
- context.moveTo((move0 = point2)[0], point2[1]);
5559
- }
5560
- if (keepWinding) winding += d3_geo_circleWinding(point2, point1);
5561
- point0 = point2;
5562
- } else {
5563
- line0 = point2 = intersect(point0, point1);
5564
- context.lineTo(point2[0], point2[1]);
5565
- if (keepWinding) {
5566
- if (Math.abs(move0[0] - point2[0]) > ε || Math.abs(move0[1] - point2[1]) > ε) {
5567
- keepWinding = false;
5568
- } else {
5569
- winding += d3_geo_circleWinding(point0, move0);
5570
- }
5571
- }
5572
- point0 = point2;
5700
+ function d3_geo_circleInterpolate(radians, precision) {
5701
+ var cr = Math.cos(radians), sr = Math.sin(radians);
5702
+ return function(from, to, direction, listener) {
5703
+ if (from != null) {
5704
+ from = d3_geo_circleAngle(cr, from);
5705
+ to = d3_geo_circleAngle(cr, to);
5706
+ if (direction > 0 ? from < to : from > to) from += direction * 2 * π;
5707
+ } else {
5708
+ from = radians + direction * 2 * π;
5709
+ to = radians;
5710
+ }
5711
+ var point;
5712
+ for (var step = direction * precision, t = from; direction > 0 ? t > to : t < to; t -= step) {
5713
+ listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]);
5714
+ }
5715
+ };
5716
+ }
5717
+ function d3_geo_circleAngle(cr, point) {
5718
+ var a = d3_geo_cartesian(point);
5719
+ a[0] -= cr;
5720
+ d3_geo_cartesianNormalize(a);
5721
+ var angle = Math.acos(Math.max(-1, Math.min(1, -a[1])));
5722
+ return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI);
5723
+ }
5724
+ function d3_geo_clip(pointVisible, clipLine, interpolate) {
5725
+ return function(listener) {
5726
+ var line = clipLine(listener);
5727
+ var clip = {
5728
+ point: point,
5729
+ lineStart: lineStart,
5730
+ lineEnd: lineEnd,
5731
+ polygonStart: function() {
5732
+ clip.point = pointRing;
5733
+ clip.lineStart = ringStart;
5734
+ clip.lineEnd = ringEnd;
5735
+ invisible = false;
5736
+ invisibleArea = visibleArea = 0;
5737
+ segments = [];
5738
+ listener.polygonStart();
5739
+ },
5740
+ polygonEnd: function() {
5741
+ clip.point = point;
5742
+ clip.lineStart = lineStart;
5743
+ clip.lineEnd = lineEnd;
5744
+ segments = d3.merge(segments);
5745
+ if (segments.length) {
5746
+ d3_geo_clipPolygon(segments, interpolate, listener);
5747
+ } else if (visibleArea < -ε || invisible && invisibleArea < -ε) {
5748
+ listener.lineStart();
5749
+ interpolate(null, null, 1, listener);
5750
+ listener.lineEnd();
5573
5751
  }
5752
+ listener.polygonEnd();
5753
+ segments = null;
5754
+ },
5755
+ sphere: function() {
5756
+ listener.polygonStart();
5757
+ listener.lineStart();
5758
+ interpolate(null, null, 1, listener);
5759
+ listener.lineEnd();
5760
+ listener.polygonEnd();
5761
+ }
5762
+ };
5763
+ function point(λ, φ) {
5764
+ if (pointVisible(λ, φ)) listener.point(λ, φ);
5765
+ }
5766
+ function pointLine(λ, φ) {
5767
+ line.point(λ, φ);
5768
+ }
5769
+ function lineStart() {
5770
+ clip.point = pointLine;
5771
+ line.lineStart();
5772
+ }
5773
+ function lineEnd() {
5774
+ clip.point = point;
5775
+ line.lineEnd();
5776
+ }
5777
+ var segments, visibleArea, invisibleArea, invisible;
5778
+ var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), ring;
5779
+ function pointRing(λ, φ) {
5780
+ ringListener.point(λ, φ);
5781
+ ring.push([ λ, φ ]);
5782
+ }
5783
+ function ringStart() {
5784
+ ringListener.lineStart();
5785
+ ring = [];
5786
+ }
5787
+ function ringEnd() {
5788
+ pointRing(ring[0][0], ring[0][1]);
5789
+ ringListener.lineEnd();
5790
+ var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length;
5791
+ if (!n) {
5792
+ invisible = true;
5793
+ invisibleArea += d3_geo_clipAreaRing(ring, -1);
5794
+ ring = null;
5795
+ return;
5796
+ }
5797
+ ring = null;
5798
+ if (clean & 1) {
5799
+ segment = ringSegments[0];
5800
+ visibleArea += d3_geo_clipAreaRing(segment, 1);
5801
+ var n = segment.length - 1, i = -1, point;
5802
+ listener.lineStart();
5803
+ while (++i < n) listener.point((point = segment[i])[0], point[1]);
5804
+ listener.lineEnd();
5805
+ return;
5574
5806
  }
5575
- if (keepWinding) winding += d3_geo_circleWinding(point0, point1);
5576
- if (v) context.lineTo(point1[0], point1[1]);
5577
- point0 = point1;
5807
+ if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
5808
+ segments.push(ringSegments.filter(d3_geo_clipSegmentLength1));
5578
5809
  }
5579
- if (closed && v) context.closePath();
5580
- return keepWinding && (!move0 || Math.abs(move0[0] - point0[0]) < ε && Math.abs(move0[1] - point0[1]) < ε) && winding;
5581
- }
5582
- function intersect(a, b) {
5583
- var pa = d3_geo_circleCartesian(a, [ 0, 0, 0 ]), pb = d3_geo_circleCartesian(b, [ 0, 0, 0 ]);
5584
- var n1 = [ 1, 0, 0 ], n2 = d3_geo_circleCross(pa, pb), n2n2 = d3_geo_circleDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2;
5585
- if (!determinant) return a;
5586
- var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_circleCross(n1, n2), A = d3_geo_circleScale(n1, c1), B = d3_geo_circleScale(n2, c2);
5587
- d3_geo_circleAdd(A, B);
5588
- var u = n1xn2, w = d3_geo_circleDot(A, u), uu = d3_geo_circleDot(u, u), t = Math.sqrt(w * w - uu * (d3_geo_circleDot(A, A) - 1)), q = d3_geo_circleScale(u, (-w - t) / uu);
5589
- d3_geo_circleAdd(q, A);
5590
- return d3_geo_circleSpherical(q);
5591
- }
5810
+ return clip;
5811
+ };
5592
5812
  }
5593
- function d3_geo_circleInterpolate(radians, precision) {
5594
- var cr = Math.cos(radians), sr = Math.sin(radians);
5595
- return function(from, to, direction, context) {
5596
- var step = direction * precision;
5597
- from = from.angle;
5598
- to = to.angle;
5599
- if (from < to) from += 2 * π;
5600
- for (var step = precision, t = from; direction > 0 ? t > to : t < to; t -= step) {
5601
- var c = Math.cos(t), s = Math.sin(t), point = d3_geo_circleSpherical([ cr, -sr * c, -sr * s ]);
5602
- context.lineTo(point[0], point[1]);
5603
- }
5604
- };
5605
- }
5606
- function d3_geo_circleClipPolygon(coordinates, context, clipLine, interpolate, angle) {
5607
- var subject = [], clip = [], segments = [], buffer = d3_geo_circleBufferSegments(clipLine), winding = 0, count = 0;
5608
- coordinates.forEach(function(ring) {
5609
- var x = buffer(ring, context), ringSegments = x[1];
5610
- winding += x[0];
5611
- var n = ringSegments.length;
5612
- if (!n) return;
5613
- count += n;
5614
- if (typeof x[0] === "number") {
5615
- var segment = ringSegments[0], point = segment[0], n = segment.length - 1, i = 0;
5616
- context.moveTo(point[0], point[1]);
5617
- while (++i < n) context.lineTo((point = segment[i])[0], point[1]);
5618
- context.closePath();
5619
- return;
5620
- }
5621
- segments = segments.concat(ringSegments);
5622
- });
5623
- if (count ? winding > 0 : winding < 0) {
5624
- var moved = false;
5625
- d3_geo_circleInterpolateCircle(interpolate, {
5626
- lineTo: function(x, y) {
5627
- (moved ? context.lineTo : (moved = true, context.moveTo))(x, y);
5628
- }
5629
- });
5630
- context.closePath();
5631
- }
5813
+ function d3_geo_clipPolygon(segments, interpolate, listener) {
5814
+ var subject = [], clip = [];
5632
5815
  segments.forEach(function(segment) {
5633
- var p0 = segment[0], p1 = segment[segment.length - 1], a = {
5816
+ var n = segment.length;
5817
+ if (n <= 1) return;
5818
+ var p0 = segment[0], p1 = segment[n - 1], a = {
5634
5819
  point: p0,
5635
5820
  points: segment,
5636
5821
  other: null,
@@ -5639,7 +5824,6 @@
5639
5824
  subject: true
5640
5825
  }, b = {
5641
5826
  point: p0,
5642
- angle: angle(p0),
5643
5827
  points: [ p0 ],
5644
5828
  other: a,
5645
5829
  visited: false,
@@ -5659,7 +5843,6 @@
5659
5843
  };
5660
5844
  b = {
5661
5845
  point: p1,
5662
- angle: angle(p1),
5663
5846
  points: [ p1 ],
5664
5847
  other: a,
5665
5848
  visited: false,
@@ -5670,134 +5853,224 @@
5670
5853
  subject.push(a);
5671
5854
  clip.push(b);
5672
5855
  });
5673
- clip.sort(d3_geo_circleClipSort);
5674
- d3_geo_circleLinkCircular(subject);
5675
- d3_geo_circleLinkCircular(clip);
5856
+ clip.sort(d3_geo_clipSort);
5857
+ d3_geo_clipLinkCircular(subject);
5858
+ d3_geo_clipLinkCircular(clip);
5676
5859
  if (!subject.length) return;
5677
5860
  var start = subject[0], current, points, point;
5678
5861
  while (1) {
5679
5862
  current = start;
5680
5863
  while (current.visited) if ((current = current.next) === start) return;
5681
5864
  points = current.points;
5682
- context.moveTo((point = points.shift())[0], point[1]);
5865
+ listener.lineStart();
5683
5866
  do {
5684
5867
  current.visited = current.other.visited = true;
5685
5868
  if (current.entry) {
5686
5869
  if (current.subject) {
5687
- for (var i = 0; i < points.length; i++) context.lineTo((point = points[i])[0], point[1]);
5870
+ for (var i = 0; i < points.length; i++) listener.point((point = points[i])[0], point[1]);
5688
5871
  } else {
5689
- interpolate(current, current.next, 1, context);
5872
+ interpolate(current.point, current.next.point, 1, listener);
5690
5873
  }
5691
5874
  current = current.next;
5692
5875
  } else {
5693
5876
  if (current.subject) {
5694
5877
  points = current.prev.points;
5695
- for (var i = points.length; --i >= 0; ) context.lineTo((point = points[i])[0], point[1]);
5878
+ for (var i = points.length; --i >= 0; ) listener.point((point = points[i])[0], point[1]);
5696
5879
  } else {
5697
- interpolate(current, current.prev, -1, context);
5880
+ interpolate(current.point, current.prev.point, -1, listener);
5698
5881
  }
5699
5882
  current = current.prev;
5700
5883
  }
5701
5884
  current = current.other;
5702
5885
  points = current.points;
5703
5886
  } while (!current.visited);
5704
- context.closePath();
5887
+ listener.lineEnd();
5705
5888
  }
5706
5889
  }
5707
- function d3_geo_circleLinkCircular(array) {
5708
- for (var i = 0, a = array[0], b, n = array.length; i < n; ) {
5709
- a.next = b = array[++i % n];
5890
+ function d3_geo_clipLinkCircular(array) {
5891
+ if (!(n = array.length)) return;
5892
+ var n, i = 0, a = array[0], b;
5893
+ while (++i < n) {
5894
+ a.next = b = array[i];
5710
5895
  b.prev = a;
5711
5896
  a = b;
5712
5897
  }
5898
+ a.next = b = array[0];
5899
+ b.prev = a;
5713
5900
  }
5714
- function d3_geo_circleClipSort(a, b) {
5715
- return b.angle - a.angle;
5716
- }
5717
- function d3_geo_circleAngle(center) {
5718
- return function(point) {
5719
- var a = d3_geo_circleCartesian(point, center);
5720
- d3_geo_circleNormalize(a);
5721
- var angle = Math.acos(Math.max(-1, Math.min(1, -a[1])));
5722
- return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI) % (2 * Math.PI);
5723
- };
5724
- }
5725
- function d3_geo_circleCartesian(point, origin) {
5726
- var p0 = point[0], p1 = point[1], c1 = Math.cos(p1);
5727
- return [ c1 * Math.cos(p0) - origin[0], c1 * Math.sin(p0) - origin[1], Math.sin(p1) - origin[2] ];
5901
+ function d3_geo_clipSort(a, b) {
5902
+ return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1]) - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]);
5728
5903
  }
5729
- function d3_geo_circleSpherical(point) {
5730
- return [ Math.atan2(point[1], point[0]), Math.asin(Math.max(-1, Math.min(1, point[2]))) ];
5904
+ function d3_geo_clipSegmentLength1(segment) {
5905
+ return segment.length > 1;
5731
5906
  }
5732
- function d3_geo_circleDot(a, b) {
5733
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
5907
+ function d3_geo_clipBufferListener() {
5908
+ var lines = [], line;
5909
+ return {
5910
+ lineStart: function() {
5911
+ lines.push(line = []);
5912
+ },
5913
+ point: function(λ, φ) {
5914
+ line.push([ λ, φ ]);
5915
+ },
5916
+ lineEnd: d3_noop,
5917
+ buffer: function() {
5918
+ var buffer = lines;
5919
+ lines = [];
5920
+ line = null;
5921
+ return buffer;
5922
+ }
5923
+ };
5734
5924
  }
5735
- function d3_geo_circleCross(a, b) {
5736
- return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ];
5925
+ function d3_geo_clipAreaRing(ring, invisible) {
5926
+ if (!(n = ring.length)) return 0;
5927
+ var n, i = 0, area = 0, p = ring[0], λ = p[0], φ = p[1], cosφ = Math.cos(φ), x0 = Math.atan2(invisible * Math.sin(λ) * cosφ, Math.sin(φ)), y0 = 1 - invisible * Math.cos(λ) * cosφ, x1 = x0, x, y;
5928
+ while (++i < n) {
5929
+ p = ring[i];
5930
+ cosφ = Math.cos(φ = p[1]);
5931
+ x = Math.atan2(invisible * Math.sin(λ = p[0]) * cosφ, Math.sin(φ));
5932
+ y = 1 - invisible * Math.cos(λ) * cosφ;
5933
+ if (Math.abs(y0 - 2) < ε && Math.abs(y - 2) < ε) continue;
5934
+ if (Math.abs(y) < ε || Math.abs(y0) < ε) {} else if (Math.abs(Math.abs(x - x0) - π) < ε) {
5935
+ if (y + y0 > 2) area += 4 * (x - x0);
5936
+ } else if (Math.abs(y0 - 2) < ε) area += 4 * (x - x1); else area += ((3 * π + x - x0) % (2 * π) - π) * (y0 + y);
5937
+ x1 = x0, x0 = x, y0 = y;
5938
+ }
5939
+ return area;
5737
5940
  }
5738
- function d3_geo_circleAdd(a, b) {
5739
- a[0] += b[0];
5740
- a[1] += b[1];
5741
- a[2] += b[2];
5941
+ var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate);
5942
+ function d3_geo_clipAntimeridianLine(listener) {
5943
+ var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean;
5944
+ return {
5945
+ lineStart: function() {
5946
+ listener.lineStart();
5947
+ clean = 1;
5948
+ },
5949
+ point: function(λ1, φ1) {
5950
+ var sλ1 = λ1 > 0 ? π : -π, dλ = Math.abs(λ1 - λ0);
5951
+ if (Math.abs(dλ - π) < ε) {
5952
+ listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2);
5953
+ listener.point(sλ0, φ0);
5954
+ listener.lineEnd();
5955
+ listener.lineStart();
5956
+ listener.point(sλ1, φ0);
5957
+ listener.point(λ1, φ0);
5958
+ clean = 0;
5959
+ } else if (sλ0 !== sλ1 && dλ >= π) {
5960
+ if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;
5961
+ if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;
5962
+ φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1);
5963
+ listener.point(sλ0, φ0);
5964
+ listener.lineEnd();
5965
+ listener.lineStart();
5966
+ listener.point(sλ1, φ0);
5967
+ clean = 0;
5968
+ }
5969
+ listener.point(λ0 = λ1, φ0 = φ1);
5970
+ sλ0 = sλ1;
5971
+ },
5972
+ lineEnd: function() {
5973
+ listener.lineEnd();
5974
+ λ0 = φ0 = NaN;
5975
+ },
5976
+ clean: function() {
5977
+ return 2 - clean;
5978
+ }
5979
+ };
5742
5980
  }
5743
- function d3_geo_circleScale(vector, s) {
5744
- return [ vector[0] * s, vector[1] * s, vector[2] * s ];
5981
+ function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
5982
+ var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1);
5983
+ return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2;
5745
5984
  }
5746
- function d3_geo_circleNormalize(d) {
5747
- var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
5748
- d[0] /= l;
5749
- d[1] /= l;
5750
- d[2] /= l;
5985
+ function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
5986
+ var φ;
5987
+ if (from == null) {
5988
+ φ = direction * π / 2;
5989
+ listener.point(-π, φ);
5990
+ listener.point(0, φ);
5991
+ listener.point(π, φ);
5992
+ listener.point(π, 0);
5993
+ listener.point(π, -φ);
5994
+ listener.point(0, -φ);
5995
+ listener.point(-π, -φ);
5996
+ listener.point(-π, 0);
5997
+ listener.point(-π, φ);
5998
+ } else if (Math.abs(from[0] - to[0]) > ε) {
5999
+ var s = (from[0] < to[0] ? 1 : -1) * π;
6000
+ φ = direction * s / 2;
6001
+ listener.point(-s, φ);
6002
+ listener.point(0, φ);
6003
+ listener.point(s, φ);
6004
+ } else {
6005
+ listener.point(to[0], to[1]);
6006
+ }
5751
6007
  }
5752
- function d3_geo_circleBufferSegments(f) {
5753
- return function(coordinates) {
5754
- var segments = [], segment;
5755
- return [ f(coordinates, {
5756
- point: d3_noop,
5757
- moveTo: function(x, y) {
5758
- segments.push(segment = [ [ x, y ] ]);
6008
+ function d3_geo_clipCircle(degrees) {
6009
+ var radians = degrees * d3_radians, cr = Math.cos(radians), interpolate = d3_geo_circleInterpolate(radians, 6 * d3_radians);
6010
+ return d3_geo_clip(visible, clipLine, interpolate);
6011
+ function visible(λ, φ) {
6012
+ return Math.cos(λ) * Math.cos(φ) > cr;
6013
+ }
6014
+ function clipLine(listener) {
6015
+ var point0, v0, v00, clean;
6016
+ return {
6017
+ lineStart: function() {
6018
+ v00 = v0 = false;
6019
+ clean = 1;
6020
+ },
6021
+ point: function(λ, φ) {
6022
+ var point1 = [ λ, φ ], point2, v = visible(λ, φ);
6023
+ if (!point0 && (v00 = v0 = v)) listener.lineStart();
6024
+ if (v !== v0) {
6025
+ point2 = intersect(point0, point1);
6026
+ if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) {
6027
+ point1[0] += ε;
6028
+ point1[1] += ε;
6029
+ v = visible(point1[0], point1[1]);
6030
+ }
6031
+ }
6032
+ if (v !== v0) {
6033
+ clean = 0;
6034
+ if (v0 = v) {
6035
+ listener.lineStart();
6036
+ point2 = intersect(point1, point0);
6037
+ listener.point(point2[0], point2[1]);
6038
+ } else {
6039
+ point2 = intersect(point0, point1);
6040
+ listener.point(point2[0], point2[1]);
6041
+ listener.lineEnd();
6042
+ }
6043
+ point0 = point2;
6044
+ }
6045
+ if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) listener.point(point1[0], point1[1]);
6046
+ point0 = point1;
5759
6047
  },
5760
- lineTo: function(x, y) {
5761
- segment.push([ x, y ]);
6048
+ lineEnd: function() {
6049
+ if (v0) listener.lineEnd();
6050
+ point0 = null;
5762
6051
  },
5763
- closePath: function() {
5764
- if (segments.length < 2) return;
5765
- segments.pop();
5766
- segments.push(segment = segment.concat(segments.shift()));
6052
+ clean: function() {
6053
+ return clean | (v00 && v0) << 1;
5767
6054
  }
5768
- }, 0), segments ];
5769
- };
5770
- }
5771
- function d3_geo_circleWinding(p0, p) {
5772
- var c0 = Math.cos(p0[1]), k0 = 1 + Math.cos(p0[0]) * c0, c = Math.cos(p[1]), k = 1 + Math.cos(p[0]) * c;
5773
- p0 = [ c0 * Math.sin(p0[0]) / k0, Math.sin(p0[1]) / k0 ];
5774
- p = [ c * Math.sin(p[0]) / k, Math.sin(p[1]) / k ];
5775
- if (p0[1] <= 0) {
5776
- if (p[1] > 0 && (p0[0] - p[0]) * p0[1] + p0[0] * (p[1] - p0[1]) > 0) return 1;
5777
- } else {
5778
- if (p[1] <= 0 && (p0[0] - p[0]) * p0[1] + p0[0] * (p[1] - p0[1]) < 0) return -1;
6055
+ };
5779
6056
  }
5780
- return 0;
5781
- }
5782
- function d3_geo_circleInterpolateCircle(interpolate, context) {
5783
- for (var i = 0; i < 4; i++) {
5784
- interpolate({
5785
- angle: -i * π / 2
5786
- }, {
5787
- angle: -(i + 1) * π / 2
5788
- }, 1, context);
6057
+ function intersect(a, b) {
6058
+ var pa = d3_geo_cartesian(a, 0), pb = d3_geo_cartesian(b, 0);
6059
+ var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2;
6060
+ if (!determinant) return a;
6061
+ var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2);
6062
+ d3_geo_cartesianAdd(A, B);
6063
+ var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t = Math.sqrt(w * w - uu * (d3_geo_cartesianDot(A, A) - 1)), q = d3_geo_cartesianScale(u, (-w - t) / uu);
6064
+ d3_geo_cartesianAdd(q, A);
6065
+ return d3_geo_spherical(q);
5789
6066
  }
5790
6067
  }
5791
6068
  function d3_geo_compose(a, b) {
5792
- if (a === d3_geo_equirectangular) return b;
5793
- if (b === d3_geo_equirectangular) return a;
5794
- function compose(λ, φ) {
5795
- var coordinates = a(λ, φ);
5796
- return b(coordinates[0], coordinates[1]);
6069
+ function compose(x, y) {
6070
+ return x = a(x, y), b(x[0], x[1]);
5797
6071
  }
5798
6072
  if (a.invert && b.invert) compose.invert = function(x, y) {
5799
- var coordinates = b.invert(x, y);
5800
- return a.invert(coordinates[0], coordinates[1]);
6073
+ return x = b.invert(x, y), a.invert(x[0], x[1]);
5801
6074
  };
5802
6075
  return compose;
5803
6076
  }
@@ -5817,12 +6090,15 @@
5817
6090
  var x1, x0, y1, y0, dx = 22.5, dy = dx, x, y, precision = 2.5;
5818
6091
  function graticule() {
5819
6092
  return {
5820
- type: "GeometryCollection",
5821
- geometries: graticule.lines()
6093
+ type: "MultiLineString",
6094
+ coordinates: lines()
5822
6095
  };
5823
6096
  }
6097
+ function lines() {
6098
+ return d3.range(Math.ceil(x0 / dx) * dx, x1, dx).map(x).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).map(y));
6099
+ }
5824
6100
  graticule.lines = function() {
5825
- return d3.range(Math.ceil(x0 / dx) * dx, x1, dx).map(x).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).map(y)).map(function(coordinates) {
6101
+ return lines().map(function(coordinates) {
5826
6102
  return {
5827
6103
  type: "LineString",
5828
6104
  coordinates: coordinates
@@ -5873,11 +6149,23 @@
5873
6149
  });
5874
6150
  };
5875
6151
  }
6152
+ d3.geo.interpolate = function(source, target) {
6153
+ return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians);
6154
+ };
6155
+ function d3_geo_interpolate(x0, y0, x1, y1) {
6156
+ var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))), k = 1 / Math.sin(d);
6157
+ function interpolate(t) {
6158
+ var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1;
6159
+ return [ Math.atan2(y, x) / d3_radians, Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_radians ];
6160
+ }
6161
+ interpolate.distance = d;
6162
+ return interpolate;
6163
+ }
5876
6164
  d3.geo.greatArc = function() {
5877
- var source = d3_source, p0, target = d3_target, p1, precision = 6 * d3_radians, interpolate = d3_geo_greatArcInterpolator();
6165
+ var source = d3_source, s, target = d3_target, t, precision = 6 * d3_radians, interpolate;
5878
6166
  function greatArc() {
5879
- var d = greatArc.distance.apply(this, arguments), t = 0, dt = precision / d, coordinates = [ p0 ];
5880
- while ((t += dt) < 1) coordinates.push(interpolate(t));
6167
+ var p0 = s || source.apply(this, arguments), p1 = t || target.apply(this, arguments), i = interpolate || d3.geo.interpolate(p0, p1), t = 0, dt = precision / i.distance, coordinates = [ p0 ];
6168
+ while ((t += dt) < 1) coordinates.push(i(t));
5881
6169
  coordinates.push(p1);
5882
6170
  return {
5883
6171
  type: "LineString",
@@ -5885,20 +6173,18 @@
5885
6173
  };
5886
6174
  }
5887
6175
  greatArc.distance = function() {
5888
- if (typeof source === "function") interpolate.source(p0 = source.apply(this, arguments));
5889
- if (typeof target === "function") interpolate.target(p1 = target.apply(this, arguments));
5890
- return interpolate.distance();
6176
+ return (interpolate || d3.geo.interpolate(s || source.apply(this, arguments), t || target.apply(this, arguments))).distance;
5891
6177
  };
5892
6178
  greatArc.source = function(_) {
5893
6179
  if (!arguments.length) return source;
5894
- source = _;
5895
- if (typeof source !== "function") interpolate.source(p0 = source);
6180
+ source = _, s = typeof _ === "function" ? null : _;
6181
+ interpolate = s && t ? d3.geo.interpolate(s, t) : null;
5896
6182
  return greatArc;
5897
6183
  };
5898
6184
  greatArc.target = function(_) {
5899
6185
  if (!arguments.length) return target;
5900
- target = _;
5901
- if (typeof target !== "function") interpolate.target(p1 = target);
6186
+ target = _, t = typeof _ === "function" ? null : _;
6187
+ interpolate = s && t ? d3.geo.interpolate(s, t) : null;
5902
6188
  return greatArc;
5903
6189
  };
5904
6190
  greatArc.precision = function(_) {
@@ -5908,36 +6194,6 @@
5908
6194
  };
5909
6195
  return greatArc;
5910
6196
  };
5911
- function d3_geo_greatArcInterpolator() {
5912
- var x0, y0, cy0, sy0, kx0, ky0, x1, y1, cy1, sy1, kx1, ky1, d, k;
5913
- function interpolate(t) {
5914
- var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1;
5915
- return [ Math.atan2(y, x) / d3_radians, Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_radians ];
5916
- }
5917
- interpolate.distance = function() {
5918
- if (d == null) k = 1 / Math.sin(d = Math.acos(Math.max(-1, Math.min(1, sy0 * sy1 + cy0 * cy1 * Math.cos(x1 - x0)))));
5919
- return d;
5920
- };
5921
- interpolate.source = function(_) {
5922
- var cx0 = Math.cos(x0 = _[0] * d3_radians), sx0 = Math.sin(x0);
5923
- cy0 = Math.cos(y0 = _[1] * d3_radians);
5924
- sy0 = Math.sin(y0);
5925
- kx0 = cy0 * cx0;
5926
- ky0 = cy0 * sx0;
5927
- d = null;
5928
- return interpolate;
5929
- };
5930
- interpolate.target = function(_) {
5931
- var cx1 = Math.cos(x1 = _[0] * d3_radians), sx1 = Math.sin(x1);
5932
- cy1 = Math.cos(y1 = _[1] * d3_radians);
5933
- sy1 = Math.sin(y1);
5934
- kx1 = cy1 * cx1;
5935
- ky1 = cy1 * sx1;
5936
- d = null;
5937
- return interpolate;
5938
- };
5939
- return interpolate;
5940
- }
5941
6197
  function d3_geo_mercator(λ, φ) {
5942
6198
  return [ λ / (2 * π), Math.max(-.5, Math.min(+.5, Math.log(Math.tan(π / 4 + φ / 2)) / (2 * π))) ];
5943
6199
  }
@@ -5954,163 +6210,288 @@
5954
6210
  return d3_geo_projection(d3_geo_orthographic);
5955
6211
  }).raw = d3_geo_orthographic;
5956
6212
  d3.geo.path = function() {
5957
- var pointRadius = 4.5, pointCircle = d3_geo_pathCircle(pointRadius), projection = d3.geo.albersUsa(), bounds, buffer = [];
5958
- var bufferContext = {
5959
- point: function(x, y) {
5960
- buffer.push("M", x, ",", y, pointCircle);
5961
- },
5962
- moveTo: function(x, y) {
5963
- buffer.push("M", x, ",", y);
5964
- },
5965
- lineTo: function(x, y) {
5966
- buffer.push("L", x, ",", y);
5967
- },
5968
- closePath: function() {
5969
- buffer.push("Z");
5970
- }
5971
- };
5972
- var context = bufferContext;
6213
+ var pointRadius = 4.5, projection, context, projectStream, contextStream;
5973
6214
  function path(object) {
5974
- var result = null;
5975
- if (object != result) {
5976
- if (typeof pointRadius === "function") pointCircle = d3_geo_pathCircle(pointRadius.apply(this, arguments));
5977
- pathType.object(object);
5978
- if (buffer.length) result = buffer.join(""), buffer = [];
5979
- }
5980
- return result;
5981
- }
5982
- var pathType = d3_geo_type({
5983
- line: function(coordinates) {
5984
- projection.line(coordinates, context);
5985
- },
5986
- polygon: function(coordinates) {
5987
- projection.polygon(coordinates, context);
5988
- },
5989
- point: function(coordinates) {
5990
- projection.point(coordinates, context);
5991
- }
5992
- });
5993
- var areaType = d3_geo_type({
5994
- Feature: function(feature) {
5995
- return areaType.geometry(feature.geometry);
5996
- },
5997
- FeatureCollection: function(collection) {
5998
- return d3.sum(collection.features, areaType.Feature);
5999
- },
6000
- GeometryCollection: function(collection) {
6001
- return d3.sum(collection.geometries, areaType.geometry);
6002
- },
6003
- LineString: d3_zero,
6004
- MultiLineString: d3_zero,
6005
- MultiPoint: d3_zero,
6006
- MultiPolygon: function(multiPolygon) {
6007
- return d3.sum(multiPolygon.coordinates, polygonArea);
6008
- },
6009
- Point: d3_zero,
6010
- Polygon: function(polygon) {
6011
- return polygonArea(polygon.coordinates);
6012
- }
6013
- });
6014
- function ringArea(coordinates) {
6015
- return Math.abs(d3.geom.polygon(coordinates.map(projection)).area());
6016
- }
6017
- function polygonArea(coordinates) {
6018
- return ringArea(coordinates[0]) - d3.sum(coordinates.slice(1), ringArea);
6215
+ if (object) d3.geo.stream(object, projectStream(contextStream.pointRadius(typeof pointRadius === "function" ? +pointRadius.apply(this, arguments) : pointRadius)));
6216
+ return contextStream.result();
6019
6217
  }
6020
6218
  path.area = function(object) {
6021
- return areaType.object(object);
6022
- };
6023
- var centroidType = d3_geo_type({
6024
- Feature: function(feature) {
6025
- return centroidType.geometry(feature.geometry);
6026
- },
6027
- LineString: d3_geo_pathCentroid1(lineCentroid),
6028
- MultiLineString: d3_geo_pathCentroid2(lineCentroid),
6029
- MultiPoint: d3_geo_pathCentroid2(pointCentroid),
6030
- MultiPolygon: d3_geo_pathCentroid3(ringCentroid),
6031
- Point: d3_geo_pathCentroid1(pointCentroid),
6032
- Polygon: d3_geo_pathCentroid2(ringCentroid)
6033
- });
6034
- function pointCentroid(centroid, point) {
6035
- point = projection(point);
6036
- centroid[0] += point[0];
6037
- centroid[1] += point[1];
6038
- return 1;
6039
- }
6040
- function lineCentroid(centroid, line) {
6041
- if (!(n = line.length)) return 0;
6042
- var n, point = projection(line[0]), x0 = point[0], y0 = point[1], x1, y1, dx, dy, i = 0, δ, z = 0;
6043
- while (++i < n) {
6044
- point = projection(line[i]);
6045
- x1 = point[0];
6046
- y1 = point[1];
6047
- dx = x1 - x0;
6048
- dy = y1 - y0;
6049
- z += δ = Math.sqrt(dx * dx + dy * dy);
6050
- centroid[0] += δ * (x0 + x1) / 2;
6051
- centroid[1] += δ * (y0 + y1) / 2;
6052
- x0 = x1;
6053
- y0 = y1;
6054
- }
6055
- return z;
6056
- }
6057
- function ringCentroid(centroid, ring, i) {
6058
- var polygon = d3.geom.polygon(ring.map(projection)), area = polygon.area(), point = polygon.centroid(area < 0 ? (area *= -1,
6059
- 1) : -1);
6060
- centroid[0] += point[0];
6061
- centroid[1] += point[1];
6062
- return area * (i > 0 ? -6 : 6);
6063
- }
6064
- path.bounds = function(object) {
6065
- return (bounds || (bounds = d3_geo_bounds(projection)))(object);
6219
+ d3_geo_pathAreaSum = 0;
6220
+ d3.geo.stream(object, projectStream(d3_geo_pathArea));
6221
+ return d3_geo_pathAreaSum;
6066
6222
  };
6067
6223
  path.centroid = function(object) {
6068
- return centroidType.object(object);
6224
+ d3_geo_centroidDimension = d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
6225
+ d3.geo.stream(object, projectStream(d3_geo_pathCentroid));
6226
+ return d3_geo_centroidZ ? [ d3_geo_centroidX / d3_geo_centroidZ, d3_geo_centroidY / d3_geo_centroidZ ] : undefined;
6227
+ };
6228
+ path.bounds = function(object) {
6229
+ return d3_geo_bounds(projection)(object);
6069
6230
  };
6070
6231
  path.projection = function(_) {
6071
6232
  if (!arguments.length) return projection;
6072
- projection = _;
6073
- bounds = null;
6233
+ projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity;
6074
6234
  return path;
6075
6235
  };
6076
6236
  path.context = function(_) {
6077
- if (!arguments.length) return context === bufferContext ? null : context;
6078
- context = _;
6079
- if (context == null) context = bufferContext;
6237
+ if (!arguments.length) return context;
6238
+ contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_);
6080
6239
  return path;
6081
6240
  };
6082
- path.pointRadius = function(x) {
6241
+ path.pointRadius = function(_) {
6083
6242
  if (!arguments.length) return pointRadius;
6084
- if (typeof x === "function") pointRadius = x; else pointCircle = d3_geo_pathCircle(pointRadius = +x);
6243
+ pointRadius = typeof _ === "function" ? _ : +_;
6085
6244
  return path;
6086
6245
  };
6087
- return path;
6246
+ return path.projection(d3.geo.albersUsa()).context(null);
6088
6247
  };
6089
6248
  function d3_geo_pathCircle(radius) {
6090
6249
  return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + +2 * radius + "z";
6091
6250
  }
6092
- function d3_geo_pathCentroid1(weightedCentroid) {
6093
- return function(line) {
6094
- var centroid = [ 0, 0 ], z = weightedCentroid(centroid, line.coordinates, 0);
6095
- return z ? (centroid[0] /= z, centroid[1] /= z, centroid) : null;
6251
+ function d3_geo_pathProjectStream(project) {
6252
+ var resample = d3_geo_resample(function(λ, φ) {
6253
+ return project([ λ * d3_degrees, φ * d3_degrees ]);
6254
+ });
6255
+ return function(stream) {
6256
+ stream = resample(stream);
6257
+ return {
6258
+ point: function(λ, φ) {
6259
+ stream.point(λ * d3_radians, φ * d3_radians);
6260
+ },
6261
+ sphere: function() {
6262
+ stream.sphere();
6263
+ },
6264
+ lineStart: function() {
6265
+ stream.lineStart();
6266
+ },
6267
+ lineEnd: function() {
6268
+ stream.lineEnd();
6269
+ },
6270
+ polygonStart: function() {
6271
+ stream.polygonStart();
6272
+ },
6273
+ polygonEnd: function() {
6274
+ stream.polygonEnd();
6275
+ }
6276
+ };
6096
6277
  };
6097
6278
  }
6098
- function d3_geo_pathCentroid2(weightedCentroid) {
6099
- return function(polygon) {
6100
- for (var centroid = [ 0, 0 ], z = 0, rings = polygon.coordinates, i = 0, n = rings.length; i < n; ++i) {
6101
- z += weightedCentroid(centroid, rings[i], i);
6279
+ function d3_geo_pathBuffer() {
6280
+ var pointCircle = d3_geo_pathCircle(4.5), buffer = [];
6281
+ var stream = {
6282
+ point: point,
6283
+ lineStart: function() {
6284
+ stream.point = pointLineStart;
6285
+ },
6286
+ lineEnd: lineEnd,
6287
+ polygonStart: function() {
6288
+ stream.lineEnd = lineEndPolygon;
6289
+ },
6290
+ polygonEnd: function() {
6291
+ stream.lineEnd = lineEnd;
6292
+ stream.point = point;
6293
+ },
6294
+ pointRadius: function(_) {
6295
+ pointCircle = d3_geo_pathCircle(_);
6296
+ return stream;
6297
+ },
6298
+ result: function() {
6299
+ if (buffer.length) {
6300
+ var result = buffer.join("");
6301
+ buffer = [];
6302
+ return result;
6303
+ }
6102
6304
  }
6103
- return z ? (centroid[0] /= z, centroid[1] /= z, centroid) : null;
6104
6305
  };
6306
+ function point(x, y) {
6307
+ buffer.push("M", x, ",", y, pointCircle);
6308
+ }
6309
+ function pointLineStart(x, y) {
6310
+ buffer.push("M", x, ",", y);
6311
+ stream.point = pointLine;
6312
+ }
6313
+ function pointLine(x, y) {
6314
+ buffer.push("L", x, ",", y);
6315
+ }
6316
+ function lineEnd() {
6317
+ stream.point = point;
6318
+ }
6319
+ function lineEndPolygon() {
6320
+ buffer.push("Z");
6321
+ }
6322
+ return stream;
6105
6323
  }
6106
- function d3_geo_pathCentroid3(weightedCentroid) {
6107
- return function(multiPolygon) {
6108
- for (var centroid = [ 0, 0 ], z = 0, polygons = multiPolygon.coordinates, i = 0, n = polygons.length; i < n; ++i) {
6109
- for (var rings = polygons[i], j = 0, m = rings.length; j < m; ++j) {
6110
- z += weightedCentroid(centroid, rings[j], j);
6111
- }
6324
+ function d3_geo_pathContext(context) {
6325
+ var pointRadius = 4.5;
6326
+ var stream = {
6327
+ point: point,
6328
+ lineStart: function() {
6329
+ stream.point = pointLineStart;
6330
+ },
6331
+ lineEnd: lineEnd,
6332
+ polygonStart: function() {
6333
+ stream.lineEnd = lineEndPolygon;
6334
+ },
6335
+ polygonEnd: function() {
6336
+ stream.lineEnd = lineEnd;
6337
+ stream.point = point;
6338
+ },
6339
+ pointRadius: function(_) {
6340
+ pointRadius = _;
6341
+ return stream;
6342
+ },
6343
+ result: d3_noop
6344
+ };
6345
+ function point(x, y) {
6346
+ context.moveTo(x, y);
6347
+ context.arc(x, y, pointRadius, 0, 2 * π);
6348
+ }
6349
+ function pointLineStart(x, y) {
6350
+ context.moveTo(x, y);
6351
+ stream.point = pointLine;
6352
+ }
6353
+ function pointLine(x, y) {
6354
+ context.lineTo(x, y);
6355
+ }
6356
+ function lineEnd() {
6357
+ stream.point = point;
6358
+ }
6359
+ function lineEndPolygon() {
6360
+ context.closePath();
6361
+ }
6362
+ return stream;
6363
+ }
6364
+ var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = {
6365
+ point: d3_noop,
6366
+ lineStart: d3_noop,
6367
+ lineEnd: d3_noop,
6368
+ polygonStart: function() {
6369
+ d3_geo_pathAreaPolygon = 0;
6370
+ d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
6371
+ },
6372
+ polygonEnd: function() {
6373
+ d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
6374
+ d3_geo_pathAreaSum += Math.abs(d3_geo_pathAreaPolygon / 2);
6375
+ }
6376
+ };
6377
+ function d3_geo_pathAreaRingStart() {
6378
+ var x00, y00, x0, y0;
6379
+ d3_geo_pathArea.point = function(x, y) {
6380
+ d3_geo_pathArea.point = nextPoint;
6381
+ x00 = x0 = x, y00 = y0 = y;
6382
+ };
6383
+ function nextPoint(x, y) {
6384
+ d3_geo_pathAreaPolygon += y0 * x - x0 * y;
6385
+ x0 = x, y0 = y;
6386
+ }
6387
+ d3_geo_pathArea.lineEnd = function() {
6388
+ nextPoint(x00, y00);
6389
+ };
6390
+ }
6391
+ var d3_geo_pathCentroid = {
6392
+ point: d3_geo_pathCentroidPoint,
6393
+ lineStart: d3_geo_pathCentroidLineStart,
6394
+ lineEnd: d3_geo_pathCentroidLineEnd,
6395
+ polygonStart: function() {
6396
+ d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart;
6397
+ },
6398
+ polygonEnd: function() {
6399
+ d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
6400
+ d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart;
6401
+ d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd;
6402
+ }
6403
+ };
6404
+ function d3_geo_pathCentroidPoint(x, y) {
6405
+ if (d3_geo_centroidDimension) return;
6406
+ d3_geo_centroidX += x;
6407
+ d3_geo_centroidY += y;
6408
+ ++d3_geo_centroidZ;
6409
+ }
6410
+ function d3_geo_pathCentroidLineStart() {
6411
+ var x0, y0;
6412
+ if (d3_geo_centroidDimension !== 1) {
6413
+ if (d3_geo_centroidDimension < 1) {
6414
+ d3_geo_centroidDimension = 1;
6415
+ d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
6416
+ } else return;
6417
+ }
6418
+ d3_geo_pathCentroid.point = function(x, y) {
6419
+ d3_geo_pathCentroid.point = nextPoint;
6420
+ x0 = x, y0 = y;
6421
+ };
6422
+ function nextPoint(x, y) {
6423
+ var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy);
6424
+ d3_geo_centroidX += z * (x0 + x) / 2;
6425
+ d3_geo_centroidY += z * (y0 + y) / 2;
6426
+ d3_geo_centroidZ += z;
6427
+ x0 = x, y0 = y;
6428
+ }
6429
+ }
6430
+ function d3_geo_pathCentroidLineEnd() {
6431
+ d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint;
6432
+ }
6433
+ function d3_geo_pathCentroidRingStart() {
6434
+ var x00, y00, x0, y0;
6435
+ if (d3_geo_centroidDimension < 2) {
6436
+ d3_geo_centroidDimension = 2;
6437
+ d3_geo_centroidX = d3_geo_centroidY = d3_geo_centroidZ = 0;
6438
+ }
6439
+ d3_geo_pathCentroid.point = function(x, y) {
6440
+ d3_geo_pathCentroid.point = nextPoint;
6441
+ x00 = x0 = x, y00 = y0 = y;
6442
+ };
6443
+ function nextPoint(x, y) {
6444
+ var z = y0 * x - x0 * y;
6445
+ d3_geo_centroidX += z * (x0 + x);
6446
+ d3_geo_centroidY += z * (y0 + y);
6447
+ d3_geo_centroidZ += z * 3;
6448
+ x0 = x, y0 = y;
6449
+ }
6450
+ d3_geo_pathCentroid.lineEnd = function() {
6451
+ nextPoint(x00, y00);
6452
+ };
6453
+ }
6454
+ d3.geo.area = function(object) {
6455
+ d3_geo_areaSum = 0;
6456
+ d3.geo.stream(object, d3_geo_area);
6457
+ return d3_geo_areaSum;
6458
+ };
6459
+ var d3_geo_areaSum, d3_geo_areaRing;
6460
+ var d3_geo_area = {
6461
+ sphere: function() {
6462
+ d3_geo_areaSum += 4 * π;
6463
+ },
6464
+ point: d3_noop,
6465
+ lineStart: d3_noop,
6466
+ lineEnd: d3_noop,
6467
+ polygonStart: function() {
6468
+ d3_geo_areaRing = 0;
6469
+ d3_geo_area.lineStart = d3_geo_areaRingStart;
6470
+ },
6471
+ polygonEnd: function() {
6472
+ d3_geo_areaSum += d3_geo_areaRing < 0 ? 4 * π + d3_geo_areaRing : d3_geo_areaRing;
6473
+ d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop;
6474
+ }
6475
+ };
6476
+ function d3_geo_areaRingStart() {
6477
+ var λ00, φ00, λ1, λ0, φ0, cosφ0, sinφ0;
6478
+ d3_geo_area.point = function(λ, φ) {
6479
+ d3_geo_area.point = nextPoint;
6480
+ λ1 = λ0 = (λ00 = λ) * d3_radians, φ0 = (φ00 = φ) * d3_radians, cosφ0 = Math.cos(φ0),
6481
+ sinφ0 = Math.sin(φ0);
6482
+ };
6483
+ function nextPoint(λ, φ) {
6484
+ λ *= d3_radians, φ *= d3_radians;
6485
+ if (Math.abs(Math.abs(φ0) - π / 2) < ε && Math.abs(Math.abs(φ) - π / 2) < ε) return;
6486
+ var cosφ = Math.cos(φ), sinφ = Math.sin(φ);
6487
+ if (Math.abs(φ0 - π / 2) < ε) d3_geo_areaRing += (λ - λ1) * 2; else {
6488
+ var dλ = λ - λ0, cosdλ = Math.cos(dλ), d = Math.atan2(Math.sqrt((d = cosφ * Math.sin(dλ)) * d + (d = cosφ0 * sinφ - sinφ0 * cosφ * cosdλ) * d), sinφ0 * sinφ + cosφ0 * cosφ * cosdλ), s = (d + π + φ0 + φ) / 4;
6489
+ d3_geo_areaRing += (dλ < 0 && dλ > -π || dλ > π ? -4 : 4) * Math.atan(Math.sqrt(Math.abs(Math.tan(s) * Math.tan(s - d / 2) * Math.tan(s - π / 4 - φ0 / 2) * Math.tan(s - π / 4 - φ / 2))));
6112
6490
  }
6113
- return z ? (centroid[0] /= z, centroid[1] /= z, centroid) : null;
6491
+ λ1 = λ0, λ0 = λ, φ0 = φ, cosφ0 = cosφ, sinφ0 = sinφ;
6492
+ }
6493
+ d3_geo_area.lineEnd = function() {
6494
+ nextPoint(λ00, φ00);
6114
6495
  };
6115
6496
  }
6116
6497
  d3.geo.projection = d3_geo_projection;
@@ -6121,81 +6502,26 @@
6121
6502
  })();
6122
6503
  }
6123
6504
  function d3_geo_projectionMutator(projectAt) {
6124
- var project, rotate, projectRotate, k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx = x, δy = y, δ2 = .5, clip = d3_geo_projectionCutAntemeridian(rotatePoint), clipAngle = null, context;
6125
- function projection(coordinates) {
6126
- coordinates = projectRotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
6127
- return [ coordinates[0] * k + δx, δy - coordinates[1] * k ];
6128
- }
6129
- function invert(coordinates) {
6130
- coordinates = projectRotate.invert((coordinates[0] - δx) / k, (δy - coordinates[1]) / k);
6131
- return [ coordinates[0] * d3_degrees, coordinates[1] * d3_degrees ];
6132
- }
6133
- projection.point = function(coordinates, c) {
6134
- context = c;
6135
- clip.point(coordinates, resample);
6136
- context = null;
6137
- };
6138
- projection.line = function(coordinates, c) {
6139
- context = c;
6140
- clip.line(coordinates, resample);
6141
- context = null;
6142
- };
6143
- projection.polygon = function(coordinates, c) {
6144
- context = c;
6145
- clip.polygon(coordinates, resample);
6146
- context = null;
6505
+ var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) {
6506
+ x = project(x, y);
6507
+ return [ x[0] * k + δx, δy - x[1] * k ];
6508
+ }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, clip = d3_geo_clipAntimeridian, clipAngle = null;
6509
+ function projection(point) {
6510
+ point = projectRotate(point[0] * d3_radians, point[1] * d3_radians);
6511
+ return [ point[0] * k + δx, δy - point[1] * k ];
6512
+ }
6513
+ function invert(point) {
6514
+ point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k);
6515
+ return [ point[0] * d3_degrees, point[1] * d3_degrees ];
6516
+ }
6517
+ projection.stream = function(stream) {
6518
+ return d3_geo_projectionRadiansRotate(rotate, clip(projectResample(stream)));
6147
6519
  };
6148
6520
  projection.clipAngle = function(_) {
6149
6521
  if (!arguments.length) return clipAngle;
6150
- clip = _ == null ? (clipAngle = _, d3_geo_projectionCutAntemeridian(rotatePoint)) : d3_geo_circleClip(clipAngle = +_, rotatePoint);
6522
+ clip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle(clipAngle = +_);
6151
6523
  return projection;
6152
6524
  };
6153
- var λ00, φ00, λ0, sinφ0, cosφ0, x0, y0, maxDepth = 16;
6154
- function point(λ, φ) {
6155
- var p = projectPoint(λ, φ);
6156
- context.point(p[0], p[1]);
6157
- }
6158
- function moveTo(λ, φ) {
6159
- var p = projectPoint(λ00 = λ0 = λ, φ00 = φ);
6160
- sinφ0 = Math.sin(φ);
6161
- cosφ0 = Math.cos(φ);
6162
- context.moveTo(x0 = p[0], y0 = p[1]);
6163
- }
6164
- function lineTo(λ, φ) {
6165
- var p = projectPoint(λ, φ);
6166
- resampleLineTo(x0, y0, λ0, sinφ0, cosφ0, x0 = p[0], y0 = p[1], λ0 = λ, sinφ0 = Math.sin(φ), cosφ0 = Math.cos(φ), maxDepth);
6167
- context.lineTo(x0, y0);
6168
- }
6169
- function resampleLineTo(x0, y0, λ0, sinφ0, cosφ0, x1, y1, λ1, sinφ1, cosφ1, depth) {
6170
- var dx = x1 - x0, dy = y1 - y0, distance2 = dx * dx + dy * dy;
6171
- if (distance2 > 4 * δ2 && depth--) {
6172
- var cosΩ = sinφ0 * sinφ1 + cosφ0 * cosφ1 * Math.cos(λ1 - λ0), k = 1 / (Math.SQRT2 * Math.sqrt(1 + cosΩ)), x = k * (cosφ0 * Math.cos(λ0) + cosφ1 * Math.cos(λ1)), y = k * (cosφ0 * Math.sin(λ0) + cosφ1 * Math.sin(λ1)), z = Math.max(-1, Math.min(1, k * (sinφ0 + sinφ1))), φ2 = Math.asin(z), zε = Math.abs(Math.abs(z) - 1), λ2 = zε < ε || zε < εε && (Math.abs(cosφ0) < εε || Math.abs(cosφ1) < εε) ? (λ0 + λ1) / 2 : Math.atan2(y, x), p = projectPoint(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x0 - x2, dy2 = y0 - y2, dz = dx * dy2 - dy * dx2;
6173
- if (dz * dz / distance2 > δ2) {
6174
- var cosφ2 = Math.cos(φ2);
6175
- resampleLineTo(x0, y0, λ0, sinφ0, cosφ0, x2, y2, λ2, z, cosφ2, depth);
6176
- context.lineTo(x2, y2);
6177
- resampleLineTo(x2, y2, λ2, z, cosφ2, x1, y1, λ1, sinφ1, cosφ1, depth);
6178
- }
6179
- }
6180
- }
6181
- function closePath() {
6182
- var p = projectPoint(λ00, φ00);
6183
- resampleLineTo(x0, y0, λ0, sinφ0, cosφ0, p[0], p[1], λ00, Math.sin(φ00), Math.cos(φ00), maxDepth);
6184
- context.closePath();
6185
- }
6186
- var resample = {
6187
- point: point,
6188
- moveTo: moveTo,
6189
- lineTo: lineTo,
6190
- closePath: closePath
6191
- };
6192
- function rotatePoint(coordinates) {
6193
- return rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians);
6194
- }
6195
- function projectPoint(λ, φ) {
6196
- var point = project(λ, φ);
6197
- return [ point[0] * k + δx, δy - point[1] * k ];
6198
- }
6199
6525
  projection.scale = function(_) {
6200
6526
  if (!arguments.length) return k;
6201
6527
  k = +_;
@@ -6220,11 +6546,7 @@
6220
6546
  δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0;
6221
6547
  return reset();
6222
6548
  };
6223
- projection.precision = function(_) {
6224
- if (!arguments.length) return Math.sqrt(δ2);
6225
- maxDepth = (δ2 = _ * _) > 0 && 16;
6226
- return projection;
6227
- };
6549
+ d3.rebind(projection, projectResample, "precision");
6228
6550
  function reset() {
6229
6551
  projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project);
6230
6552
  var center = project(λ, φ);
@@ -6238,79 +6560,35 @@
6238
6560
  return reset();
6239
6561
  };
6240
6562
  }
6241
- function d3_geo_projectionIntersectAntemeridian(λ0, φ0, λ1, φ1) {
6242
- var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1);
6243
- return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2;
6244
- }
6245
- function d3_geo_projectionCutAntemeridian(rotatePoint) {
6246
- var clip = {
6247
- point: function(coordinates, context) {
6248
- var point = rotatePoint(coordinates);
6249
- context.point(point[0], point[1]);
6563
+ function d3_geo_projectionRadiansRotate(rotate, stream) {
6564
+ return {
6565
+ point: function(x, y) {
6566
+ y = rotate(x * d3_radians, y * d3_radians), x = y[0];
6567
+ stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]);
6250
6568
  },
6251
- line: function(coordinates, context, winding) {
6252
- if (!(n = coordinates.length)) return;
6253
- var point = rotatePoint(coordinates[0]), keepWinding = true, λ0 = point[0], φ0 = point[1], λ1, φ1, sλ0 = λ0 > 0 ? π : -π, sλ1, dλ, i = 0, n;
6254
- context.moveTo(λ0, φ0);
6255
- while (++i < n) {
6256
- point = rotatePoint(coordinates[i]);
6257
- λ1 = point[0];
6258
- φ1 = point[1];
6259
- sλ1 = λ1 > 0 ? π : -π;
6260
- dλ = Math.abs(λ1 - λ0);
6261
- if (Math.abs(dλ - π) < ε) {
6262
- context.lineTo(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2);
6263
- context.lineTo(sλ0, φ0);
6264
- context.moveTo(sλ1, φ0);
6265
- context.lineTo(λ1, φ0);
6266
- context.lineTo(λ0 = λ1, φ0 = φ1);
6267
- keepWinding = false;
6268
- } else if (sλ0 !== sλ1 && dλ >= π) {
6269
- φ0 = d3_geo_projectionIntersectAntemeridian(λ0, φ0, λ1, φ1);
6270
- if (Math.abs(λ0 - sλ0) > ε) context.lineTo(sλ0, φ0);
6271
- if (Math.abs(λ1 - sλ1) > ε) context.moveTo(sλ1, φ0), context.lineTo(λ0 = λ1, φ0 = φ1); else context.moveTo(λ0 = λ1, φ0 = φ1);
6272
- keepWinding = false;
6273
- } else {
6274
- context.lineTo(λ0 = λ1, φ0 = φ1);
6275
- }
6276
- sλ0 = sλ1;
6277
- }
6278
- if (winding != null) context.closePath();
6279
- return keepWinding && winding;
6569
+ sphere: function() {
6570
+ stream.sphere();
6571
+ },
6572
+ lineStart: function() {
6573
+ stream.lineStart();
6280
6574
  },
6281
- polygon: function(polygon, context) {
6282
- d3_geo_circleClipPolygon(polygon, context, clip.line, d3_geo_antemeridianInterpolate, d3_geo_antemeridianAngle);
6575
+ lineEnd: function() {
6576
+ stream.lineEnd();
6577
+ },
6578
+ polygonStart: function() {
6579
+ stream.polygonStart();
6580
+ },
6581
+ polygonEnd: function() {
6582
+ stream.polygonEnd();
6283
6583
  }
6284
6584
  };
6285
- return clip;
6286
- }
6287
- function d3_geo_antemeridianAngle(point) {
6288
- return -(point[0] < 0 ? point[1] - π / 2 : π / 2 - point[1]);
6289
- }
6290
- function d3_geo_antemeridianInterpolate(from, to, direction, context) {
6291
- from = from.point;
6292
- to = to.point;
6293
- if (Math.abs(from[0] - to[0]) > ε) {
6294
- var s = (from[0] < to[0] ? 1 : -1) * direction * π, φ = s / 2;
6295
- context.lineTo(-s, φ);
6296
- context.lineTo(0, φ);
6297
- context.lineTo(s, φ);
6298
- } else {
6299
- context.lineTo(to[0], to[1]);
6300
- }
6301
6585
  }
6302
6586
  function d3_geo_rotation(δλ, δφ, δγ) {
6303
- return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation;
6587
+ return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_equirectangular;
6304
6588
  }
6305
- function d3_geo_identityRotation(λ, φ) {
6306
- return [ λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ ];
6307
- }
6308
- d3_geo_identityRotation.invert = function(x, y) {
6309
- return [ x, y ];
6310
- };
6311
6589
  function d3_geo_forwardRotationλ(δλ) {
6312
6590
  return function(λ, φ) {
6313
- return [ (λ += δλ) > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ ];
6591
+ return λ += δλ, [ λ > π ? λ - 2 * π : λ < -π ? λ + 2 * π : λ, φ ];
6314
6592
  };
6315
6593
  }
6316
6594
  function d3_geo_rotationλ(δλ) {
@@ -6432,12 +6710,11 @@
6432
6710
  }
6433
6711
  d3.geom.polygon = function(coordinates) {
6434
6712
  coordinates.area = function() {
6435
- var i = 0, n = coordinates.length, a = coordinates[n - 1][0] * coordinates[0][1], b = coordinates[n - 1][1] * coordinates[0][0];
6713
+ var i = 0, n = coordinates.length, area = coordinates[n - 1][1] * coordinates[0][0] - coordinates[n - 1][0] * coordinates[0][1];
6436
6714
  while (++i < n) {
6437
- a += coordinates[i - 1][0] * coordinates[i][1];
6438
- b += coordinates[i - 1][1] * coordinates[i][0];
6715
+ area += coordinates[i - 1][1] * coordinates[i][0] - coordinates[i - 1][0] * coordinates[i][1];
6439
6716
  }
6440
- return (b - a) * .5;
6717
+ return area * .5;
6441
6718
  };
6442
6719
  coordinates.centroid = function(k) {
6443
6720
  var i = -1, n = coordinates.length, x = 0, y = 0, a, b = coordinates[n - 1], c;