d3js-rails 3.0.0.pre → 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.
@@ -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;