Update d3 and lodash

This commit is contained in:
Tom MacWright
2012-12-07 18:14:56 -05:00
parent 225a50fdf0
commit 3f2b12ad87
2 changed files with 798 additions and 569 deletions
+268 -197
View File
@@ -237,6 +237,14 @@
var H = (values.length - 1) * p + 1, h = Math.floor(H), v = values[h - 1], e = H - h;
return e ? v + e * (values[h] - v) : v;
};
d3.shuffle = function(array) {
var m = array.length, t, i;
while (m) {
i = Math.random() * m-- | 0;
t = array[m], array[m] = array[i], array[i] = t;
}
return array;
};
d3.transpose = function(matrix) {
return d3.zip.apply(d3, matrix);
};
@@ -390,13 +398,14 @@
return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);
};
d3.xhr = function(url, mimeType, callback) {
var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
var s = request.status;
!s && request.response || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request);
}
var xhr = {}, dispatch = d3.dispatch("progress", "load", "error"), headers = {}, response = d3_identity, request = new (window.XDomainRequest && /^(http(s)?:)?\/\//.test(url) ? XDomainRequest : XMLHttpRequest)();
"onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {
request.readyState > 3 && respond();
};
function respond() {
var s = request.status;
!s && request.responseText || s >= 200 && s < 300 || s === 304 ? dispatch.load.call(xhr, response.call(xhr, request)) : dispatch.error.call(xhr, request);
}
request.onprogress = function(event) {
var o = d3.event;
d3.event = event;
@@ -430,7 +439,7 @@
if (arguments.length === 2 && typeof data === "function") callback = data, data = null;
request.open(method, url, true);
if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*";
for (var name in headers) request.setRequestHeader(name, headers[name]);
if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]);
if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);
if (callback != null) xhr.on("error", callback).on("load", function(request) {
callback(null, request);
@@ -3703,21 +3712,21 @@
this.on("mousedown.drag", mousedown).on("touchstart.drag", mousedown);
}
function mousedown() {
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;
var w = d3.select(window).on(touchId ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true);
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;
var w = d3.select(window).on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true);
if (origin) {
offset = origin.apply(target, arguments);
offset = [ offset.x - origin_[0], offset.y - origin_[1] ];
} else {
offset = [ 0, 0 ];
}
if (!touchId) d3_eventCancel();
if (touchId == null) d3_eventCancel();
event_({
type: "dragstart"
});
function point() {
var p = target.parentNode;
return touchId ? d3.touches(p).filter(function(p) {
return touchId != null ? d3.touches(p).filter(function(p) {
return p.identifier === touchId;
})[0] : d3.mouse(p);
}
@@ -3743,7 +3752,7 @@
d3_eventCancel();
if (d3.event.target === eventTarget) w.on("click.drag", click, true);
}
w.on(touchId ? "touchmove.drag-" + touchId : "mousemove.drag", null).on(touchId ? "touchend.drag-" + touchId : "mouseup.drag", null);
w.on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", null).on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", null);
}
function click() {
d3_eventCancel();
@@ -4267,8 +4276,7 @@
this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag);
};
function dragmove(d) {
d.px = d3.event.x;
d.py = d3.event.y;
d.px = d3.event.x, d.py = d3.event.y;
force.resume();
}
return d3.rebind(force, event, "on");
@@ -4281,6 +4289,7 @@
}
function d3_layout_forceMouseover(d) {
d.fixed |= 4;
d.px = d.x, d.py = d.y;
}
function d3_layout_forceMouseout(d) {
d.fixed &= 3;
@@ -5365,6 +5374,7 @@
Polygon: function(polygon) {
this.polygon(polygon.coordinates);
},
Sphere: d3_noop,
object: function(object) {
return d3_geo_typeObjects.hasOwnProperty(object.type) ? this[object.type](object) : this.geometry(object);
},
@@ -5387,7 +5397,8 @@
MultiPoint: 1,
MultiPolygon: 1,
Point: 1,
Polygon: 1
Polygon: 1,
Sphere: 1
};
var d3_geo_typeObjects = {
Feature: 1,
@@ -5496,7 +5507,7 @@
var o = typeof origin === "function" ? origin.apply(this, arguments) : origin;
rotate = d3_geo_rotation(-o[0] * d3_radians, -o[1] * d3_radians, 0);
var ring = [];
d3_geo_circleInterpolateCircle(interpolate, {
interpolate(null, null, 1, {
lineTo: function(λ, φ) {
var point = rotate.invert(λ, φ);
point[0] *= d3_degrees;
@@ -5521,13 +5532,13 @@
};
circle.precision = function(_) {
if (!arguments.length) return precision;
interpolate = d3_geo_circleInterpolate(radians, (precision = +_) * d3_radians);
interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians);
return circle;
};
return circle.angle(90);
};
function d3_geo_circleClip(degrees, rotate) {
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);
var radians = degrees * d3_radians, cr = Math.cos(radians), interpolate = d3_geo_circleInterpolate(radians, 6 * d3_radians);
return {
point: function(coordinates, context) {
if (visible(coordinates = rotate(coordinates))) {
@@ -5538,46 +5549,57 @@
clipLine(coordinates, context);
},
polygon: function(polygon, context) {
d3_geo_circleClipPolygon(polygon, context, clipLine, interpolate, angle);
d3_geo_circleClipPolygon(polygon, context, clipLine, interpolate);
},
sphere: function(context) {
d3_geo_projectionSphere(context, interpolate);
}
};
function visible(point) {
return Math.cos(point[1]) * Math.cos(point[0]) > cr;
}
function clipLine(coordinates, context, winding) {
if (!(n = coordinates.length)) return;
var point0 = rotate(coordinates[0]), point2, inside = visible(point0), keepWinding = winding != null, closed = keepWinding && inside, n, move0, line0;
if (inside) context.moveTo((move0 = point0)[0], point0[1]);
function clipLine(coordinates, context, ring) {
if (!(n = coordinates.length)) return [ ring && 0, false ];
var point0 = rotate(coordinates[0]), point1, point2, v0 = visible(point0), v00 = ring && v0, v, n, clean = ring, area = 0, p, x0, x, y0, y;
if (clean) {
x0 = (p = d3_geo_stereographic(point0[0] + (v0 ? 0 : π), point0[1]))[0];
y0 = p[1];
}
if (v0) context.moveTo(point0[0], point0[1]);
for (var i = 1; i < n; i++) {
var point1 = rotate(coordinates[i]), v = visible(point1);
if (v !== inside) {
if (inside = v) {
point2 = intersect(point1, point0);
if (!line0 || Math.abs(line0[0] - point2[0]) > ε || Math.abs(line0[1] - point2[1]) > ε) {
if (move0) keepWinding = false;
context.moveTo((move0 = point2)[0], point2[1]);
}
if (keepWinding) winding += d3_geo_circleWinding(point2, point1);
point0 = point2;
} else {
line0 = point2 = intersect(point0, point1);
context.lineTo(point2[0], point2[1]);
if (keepWinding) {
if (Math.abs(move0[0] - point2[0]) > ε || Math.abs(move0[1] - point2[1]) > ε) {
keepWinding = false;
} else {
winding += d3_geo_circleWinding(point0, move0);
}
}
point0 = point2;
point1 = rotate(coordinates[i]);
v = visible(point1);
if (v !== v0) {
point2 = intersect(point0, point1);
if (d3_geo_circlePointsEqual(point0, point2) || d3_geo_circlePointsEqual(point1, point2)) {
point1[0] += ε;
point1[1] += ε;
v = visible(point1);
}
}
if (keepWinding) winding += d3_geo_circleWinding(point0, point1);
if (v) context.lineTo(point1[0], point1[1]);
if (v !== v0) {
clean = false;
if (v0 = v) {
point2 = intersect(point1, point0);
context.moveTo(point2[0], point2[1]);
} else {
point2 = intersect(point0, point1);
context.lineTo(point2[0], point2[1]);
}
point0 = point2;
}
if (clean) {
p = d3_geo_stereographic(point1[0] + (v ? 0 : π), point1[1]);
x = p[0];
y = p[1];
area += y0 * x - x0 * y;
x0 = x;
y0 = y;
}
if (v && !d3_geo_circlePointsEqual(point0, point1)) context.lineTo(point1[0], point1[1]);
point0 = point1;
}
if (closed && v) context.closePath();
return keepWinding && (!move0 || Math.abs(move0[0] - point0[0]) < ε && Math.abs(move0[1] - point0[1]) < ε) && winding;
return [ clean && area * .5, v00 && v ];
}
function intersect(a, b) {
var pa = d3_geo_circleCartesian(a, [ 0, 0, 0 ]), pb = d3_geo_circleCartesian(b, [ 0, 0, 0 ]);
@@ -5593,44 +5615,50 @@
function d3_geo_circleInterpolate(radians, precision) {
var cr = Math.cos(radians), sr = Math.sin(radians);
return function(from, to, direction, context) {
var step = direction * precision;
from = from.angle;
to = to.angle;
if (from < to) from += 2 * π;
for (var step = precision, t = from; direction > 0 ? t > to : t < to; t -= step) {
if (from != null) {
from = d3_geo_circleAngle(cr, from);
to = d3_geo_circleAngle(cr, to);
if (direction > 0 ? from < to : from > to) from += direction * 2 * π;
} else {
from = radians + direction * 2 * π;
to = radians;
}
for (var step = direction * precision, t = from; direction > 0 ? t > to : t < to; t -= step) {
var c = Math.cos(t), s = Math.sin(t), point = d3_geo_circleSpherical([ cr, -sr * c, -sr * s ]);
context.lineTo(point[0], point[1]);
}
};
}
function d3_geo_circleClipPolygon(coordinates, context, clipLine, interpolate, angle) {
var subject = [], clip = [], segments = [], buffer = d3_geo_circleBufferSegments(clipLine), winding = 0, count = 0;
function d3_geo_circleClipPolygon(coordinates, context, clipLine, interpolate) {
var subject = [], clip = [], segments = [], buffer = d3_geo_circleBufferSegments(clipLine), draw = [], visibleArea = 0, invisibleArea = 0, invisible = false;
coordinates.forEach(function(ring) {
var x = buffer(ring, context), ringSegments = x[1];
winding += x[0];
var n = ringSegments.length;
if (!n) return;
count += n;
if (typeof x[0] === "number") {
var segment = ringSegments[0], point = segment[0], n = segment.length - 1, i = 0;
var x = buffer(ring, context), ringSegments = x[1], segment, n = ringSegments.length;
if (!n) {
invisible = true;
invisibleArea += x[0][0];
return;
}
if (x[0][0] !== false) {
visibleArea += x[0][0];
draw.push(segment = ringSegments[0]);
var point = segment[0], n = segment.length - 1, i = 0;
context.moveTo(point[0], point[1]);
while (++i < n) context.lineTo((point = segment[i])[0], point[1]);
context.closePath();
return;
}
segments = segments.concat(ringSegments);
if (n > 1 && x[0][1]) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
segments = segments.concat(ringSegments.filter(d3_geo_circleSegmentLength1));
});
if (count ? winding > 0 : winding < 0) {
var moved = false;
d3_geo_circleInterpolateCircle(interpolate, {
lineTo: function(x, y) {
(moved ? context.lineTo : (moved = true, context.moveTo))(x, y);
}
});
context.closePath();
if (!segments.length) {
if (visibleArea < 0 || invisible && invisibleArea < 0) {
d3_geo_projectionSphere(context, interpolate);
}
}
segments.forEach(function(segment) {
var p0 = segment[0], p1 = segment[segment.length - 1], a = {
var n = segment.length;
if (n <= 1) return;
var p0 = segment[0], p1 = segment[n - 1], a = {
point: p0,
points: segment,
other: null,
@@ -5639,7 +5667,6 @@
subject: true
}, b = {
point: p0,
angle: angle(p0),
points: [ p0 ],
other: a,
visited: false,
@@ -5659,7 +5686,6 @@
};
b = {
point: p1,
angle: angle(p1),
points: [ p1 ],
other: a,
visited: false,
@@ -5686,7 +5712,7 @@
if (current.subject) {
for (var i = 0; i < points.length; i++) context.lineTo((point = points[i])[0], point[1]);
} else {
interpolate(current, current.next, 1, context);
interpolate(current.point, current.next.point, 1, context);
}
current = current.next;
} else {
@@ -5694,7 +5720,7 @@
points = current.prev.points;
for (var i = points.length; --i >= 0; ) context.lineTo((point = points[i])[0], point[1]);
} else {
interpolate(current, current.prev, -1, context);
interpolate(current.point, current.prev.point, -1, context);
}
current = current.prev;
}
@@ -5712,15 +5738,13 @@
}
}
function d3_geo_circleClipSort(a, b) {
return b.angle - a.angle;
return ((a = a.point)[0] < 0 ? a[1] - π / 2 - ε : π / 2 - a[1]) - ((b = b.point)[0] < 0 ? b[1] - π / 2 - ε : π / 2 - b[1]);
}
function d3_geo_circleAngle(center) {
return function(point) {
var a = d3_geo_circleCartesian(point, center);
d3_geo_circleNormalize(a);
var angle = Math.acos(Math.max(-1, Math.min(1, -a[1])));
return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI) % (2 * Math.PI);
};
function d3_geo_circleAngle(cr, point) {
var a = d3_geo_circleCartesian(point, [ cr, 0, 0 ]);
d3_geo_circleNormalize(a);
var angle = Math.acos(Math.max(-1, Math.min(1, -a[1])));
return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI);
}
function d3_geo_circleCartesian(point, origin) {
var p0 = point[0], p1 = point[1], c1 = Math.cos(p1);
@@ -5753,40 +5777,20 @@
return function(coordinates) {
var segments = [], segment;
return [ f(coordinates, {
point: d3_noop,
moveTo: function(x, y) {
segments.push(segment = [ [ x, y ] ]);
},
lineTo: function(x, y) {
segment.push([ x, y ]);
},
closePath: function() {
if (segments.length < 2) return;
segments.pop();
segments.push(segment = segment.concat(segments.shift()));
}
}, 0), segments ];
}, true), segments ];
};
}
function d3_geo_circleWinding(p0, p) {
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;
p0 = [ c0 * Math.sin(p0[0]) / k0, Math.sin(p0[1]) / k0 ];
p = [ c * Math.sin(p[0]) / k, Math.sin(p[1]) / k ];
if (p0[1] <= 0) {
if (p[1] > 0 && (p0[0] - p[0]) * p0[1] + p0[0] * (p[1] - p0[1]) > 0) return 1;
} else {
if (p[1] <= 0 && (p0[0] - p[0]) * p0[1] + p0[0] * (p[1] - p0[1]) < 0) return -1;
}
return 0;
function d3_geo_circlePointsEqual(a, b) {
return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε;
}
function d3_geo_circleInterpolateCircle(interpolate, context) {
for (var i = 0; i < 4; i++) {
interpolate({
angle: -i * π / 2
}, {
angle: -(i + 1) * π / 2
}, 1, context);
}
function d3_geo_circleSegmentLength1(segment) {
return segment.length > 1;
}
function d3_geo_compose(a, b) {
if (a === d3_geo_equirectangular) return b;
@@ -5969,6 +5973,54 @@
buffer.push("Z");
}
};
var area, centroidWeight, x00, y00, x0, y0, cx, cy;
var areaContext = {
point: d3_noop,
moveTo: moveTo,
lineTo: function(x, y) {
area += y0 * x - x0 * y;
x0 = x;
y0 = y;
},
closePath: closePath
};
var lineCentroidContext = {
point: function(x, y) {
cx += x;
cy += y;
++centroidWeight;
},
moveTo: moveTo,
lineTo: function(x, y) {
var dx = x - x0, dy = y - y0, δ = Math.sqrt(dx * dx + dy * dy);
centroidWeight += δ;
cx += δ * (x0 + x) / 2;
cy += δ * (y0 + y) / 2;
x0 = x;
y0 = y;
},
closePath: closePath
};
var polygonCentroidContext = {
point: d3_noop,
moveTo: moveTo,
lineTo: function(x, y) {
var δ = y0 * x - x0 * y;
centroidWeight += δ * 3;
cx += δ * (x0 + x);
cy += δ * (y0 + y);
x0 = x;
y0 = y;
},
closePath: closePath
};
function moveTo(x, y) {
x00 = x0 = x;
y00 = y0 = y;
}
function closePath() {
this.lineTo(x00, y00);
}
var context = bufferContext;
function path(object) {
var result = null;
@@ -5988,6 +6040,9 @@
},
point: function(coordinates) {
projection.point(coordinates, context);
},
Sphere: function() {
projection.sphere(context);
}
});
var areaType = d3_geo_type({
@@ -6009,13 +6064,18 @@
Point: d3_zero,
Polygon: function(polygon) {
return polygonArea(polygon.coordinates);
}
},
Sphere: sphereArea
});
function ringArea(coordinates) {
return Math.abs(d3.geom.polygon(coordinates.map(projection)).area());
}
function polygonArea(coordinates) {
return ringArea(coordinates[0]) - d3.sum(coordinates.slice(1), ringArea);
area = 0;
projection.polygon(coordinates, areaContext);
return Math.abs(area) / 2;
}
function sphereArea() {
area = 0;
projection.sphere(areaContext);
return Math.abs(area) / 2;
}
path.area = function(object) {
return areaType.object(object);
@@ -6024,42 +6084,37 @@
Feature: function(feature) {
return centroidType.geometry(feature.geometry);
},
LineString: d3_geo_pathCentroid1(lineCentroid),
MultiLineString: d3_geo_pathCentroid2(lineCentroid),
MultiPoint: d3_geo_pathCentroid2(pointCentroid),
MultiPolygon: d3_geo_pathCentroid3(ringCentroid),
Point: d3_geo_pathCentroid1(pointCentroid),
Polygon: d3_geo_pathCentroid2(ringCentroid)
LineString: weightedCentroid(function(lineString) {
projection.line(lineString.coordinates, lineCentroidContext);
}),
MultiLineString: weightedCentroid(function(multiLineString) {
var coordinates = multiLineString.coordinates, i = -1, n = coordinates.length;
while (++i < n) projection.line(coordinates[i], lineCentroidContext);
}),
MultiPoint: weightedCentroid(function(multiPoint) {
var coordinates = multiPoint.coordinates, i = -1, n = coordinates.length;
while (++i < n) projection.point(coordinates[i], lineCentroidContext);
}),
MultiPolygon: weightedCentroid(function(multiPolygon) {
var coordinates = multiPolygon.coordinates, i = -1, n = coordinates.length;
while (++i < n) projection.polygon(coordinates[i], polygonCentroidContext);
}),
Point: weightedCentroid(function(point) {
projection.point(point.coordinates, lineCentroidContext);
}),
Polygon: weightedCentroid(function(polygon) {
projection.polygon(polygon.coordinates, polygonCentroidContext);
}),
Sphere: weightedCentroid(function() {
projection.sphere(polygonCentroidContext);
})
});
function pointCentroid(centroid, point) {
point = projection(point);
centroid[0] += point[0];
centroid[1] += point[1];
return 1;
}
function lineCentroid(centroid, line) {
if (!(n = line.length)) return 0;
var n, point = projection(line[0]), x0 = point[0], y0 = point[1], x1, y1, dx, dy, i = 0, δ, z = 0;
while (++i < n) {
point = projection(line[i]);
x1 = point[0];
y1 = point[1];
dx = x1 - x0;
dy = y1 - y0;
z += δ = Math.sqrt(dx * dx + dy * dy);
centroid[0] += δ * (x0 + x1) / 2;
centroid[1] += δ * (y0 + y1) / 2;
x0 = x1;
y0 = y1;
}
return z;
}
function ringCentroid(centroid, ring, i) {
var polygon = d3.geom.polygon(ring.map(projection)), area = polygon.area(), point = polygon.centroid(area < 0 ? (area *= -1,
1) : -1);
centroid[0] += point[0];
centroid[1] += point[1];
return area * (i > 0 ? -6 : 6);
function weightedCentroid(f) {
return function() {
centroidWeight = cx = cy = 0;
f.apply(this, arguments);
return centroidWeight ? [ cx / centroidWeight, cy / centroidWeight ] : null;
};
}
path.bounds = function(object) {
return (bounds || (bounds = d3_geo_bounds(projection)))(object);
@@ -6089,30 +6144,17 @@
function d3_geo_pathCircle(radius) {
return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + +2 * radius + "z";
}
function d3_geo_pathCentroid1(weightedCentroid) {
return function(line) {
var centroid = [ 0, 0 ], z = weightedCentroid(centroid, line.coordinates, 0);
return z ? (centroid[0] /= z, centroid[1] /= z, centroid) : null;
};
}
function d3_geo_pathCentroid2(weightedCentroid) {
return function(polygon) {
for (var centroid = [ 0, 0 ], z = 0, rings = polygon.coordinates, i = 0, n = rings.length; i < n; ++i) {
z += weightedCentroid(centroid, rings[i], i);
}
return z ? (centroid[0] /= z, centroid[1] /= z, centroid) : null;
};
}
function d3_geo_pathCentroid3(weightedCentroid) {
return function(multiPolygon) {
for (var centroid = [ 0, 0 ], z = 0, polygons = multiPolygon.coordinates, i = 0, n = polygons.length; i < n; ++i) {
for (var rings = polygons[i], j = 0, m = rings.length; j < m; ++j) {
z += weightedCentroid(centroid, rings[j], j);
}
}
return z ? (centroid[0] /= z, centroid[1] /= z, centroid) : null;
};
}
var d3_geo_pathIdentity = d3.geo.path().projection({
polygon: function(polygon, context) {
polygon.forEach(function(ring) {
var n = ring.length, i = 0, point;
context.moveTo((point = ring[0])[0], point[1]);
while (++i < n) context.lineTo((point = ring[i])[0], point[1]);
context.closePath();
});
}
});
d3.geo.centroid = d3_geo_pathIdentity.centroid;
d3.geo.projection = d3_geo_projection;
d3.geo.projectionMutator = d3_geo_projectionMutator;
function d3_geo_projection(project) {
@@ -6145,6 +6187,11 @@
clip.polygon(coordinates, resample);
context = null;
};
projection.sphere = function(c) {
context = c;
clip.sphere(resample);
context = null;
};
projection.clipAngle = function(_) {
if (!arguments.length) return clipAngle;
clip = _ == null ? (clipAngle = _, d3_geo_projectionCutAntemeridian(rotatePoint)) : d3_geo_circleClip(clipAngle = +_, rotatePoint);
@@ -6248,9 +6295,9 @@
var point = rotatePoint(coordinates);
context.point(point[0], point[1]);
},
line: function(coordinates, context, winding) {
if (!(n = coordinates.length)) return;
var point = rotatePoint(coordinates[0]), keepWinding = true, λ0 = point[0], φ0 = point[1], λ1, φ1, sλ0 = λ0 > 0 ? π : -π, sλ1, , i = 0, n;
line: function(coordinates, context, ring) {
if (!(n = coordinates.length)) return [ ring && 0, false ];
var point = rotatePoint(coordinates[0]), λ0 = point[0], φ0 = point[1], λ1, φ1, sλ0 = λ0 > 0 ? π : -π, sλ1, , i = 0, n, clean = ring, area = 0, x0 = (point = d3_geo_stereographic(λ0, φ0))[0], x, y0 = point[1], y;
context.moveTo(λ0, φ0);
while (++i < n) {
point = rotatePoint(coordinates[i]);
@@ -6263,35 +6310,51 @@
context.lineTo(sλ0, φ0);
context.moveTo(sλ1, φ0);
context.lineTo(λ1, φ0);
context.lineTo(λ0 = λ1, φ0 = φ1);
keepWinding = false;
clean = false;
} else if (sλ0 !== sλ1 && >= π) {
if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε;
if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε;
φ0 = d3_geo_projectionIntersectAntemeridian(λ0, φ0, λ1, φ1);
if (Math.abs(λ0 - sλ0) > ε) context.lineTo(sλ0, φ0);
if (Math.abs(λ1 - sλ1) > ε) context.moveTo(sλ1, φ0), context.lineTo(λ0 = λ1, φ0 = φ1); else context.moveTo(λ0 = λ1, φ0 = φ1);
keepWinding = false;
} else {
context.lineTo(λ0 = λ1, φ0 = φ1);
context.lineTo(sλ0, φ0);
context.moveTo(sλ1, φ0);
clean = false;
}
if (clean) {
x = (point = d3_geo_stereographic(λ1, φ1))[0];
y = point[1];
area += y0 * x - x0 * y;
x0 = x;
y0 = y;
}
context.lineTo(λ0 = λ1, φ0 = φ1);
sλ0 = sλ1;
}
if (winding != null) context.closePath();
return keepWinding && winding;
return [ clean && area, true ];
},
polygon: function(polygon, context) {
d3_geo_circleClipPolygon(polygon, context, clip.line, d3_geo_antemeridianInterpolate, d3_geo_antemeridianAngle);
d3_geo_circleClipPolygon(polygon, context, clip.line, d3_geo_antemeridianInterpolate);
},
sphere: function(context) {
d3_geo_projectionSphere(context, d3_geo_antemeridianInterpolate);
}
};
return clip;
}
function d3_geo_antemeridianAngle(point) {
return -(point[0] < 0 ? point[1] - π / 2 : π / 2 - point[1]);
}
function d3_geo_antemeridianInterpolate(from, to, direction, context) {
from = from.point;
to = to.point;
if (Math.abs(from[0] - to[0]) > ε) {
var s = (from[0] < to[0] ? 1 : -1) * direction * π, φ = s / 2;
var φ;
if (from == null) {
φ = direction * π / 2;
context.lineTo(-π, φ);
context.lineTo(0, φ);
context.lineTo(π, φ);
context.lineTo(π, 0);
context.lineTo(π, -φ);
context.lineTo(0, -φ);
context.lineTo(-π, -φ);
context.lineTo(-π, 0);
} else if (Math.abs(from[0] - to[0]) > ε) {
var s = (from[0] < to[0] ? 1 : -1) * π;
φ = direction * s / 2;
context.lineTo(-s, φ);
context.lineTo(0, φ);
context.lineTo(s, φ);
@@ -6299,6 +6362,15 @@
context.lineTo(to[0], to[1]);
}
}
function d3_geo_projectionSphere(context, interpolate) {
var moved = false;
interpolate(null, null, 1, {
lineTo: function(x, y) {
(moved ? context.lineTo : (moved = true, context.moveTo))(x, y);
}
});
context.closePath();
}
function d3_geo_rotation(δλ, δφ, δγ) {
return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation;
}
@@ -6432,12 +6504,11 @@
}
d3.geom.polygon = function(coordinates) {
coordinates.area = function() {
var i = 0, n = coordinates.length, a = coordinates[n - 1][0] * coordinates[0][1], b = coordinates[n - 1][1] * coordinates[0][0];
var i = 0, n = coordinates.length, area = coordinates[n - 1][1] * coordinates[0][0] - coordinates[n - 1][0] * coordinates[0][1];
while (++i < n) {
a += coordinates[i - 1][0] * coordinates[i][1];
b += coordinates[i - 1][1] * coordinates[i][0];
area += coordinates[i - 1][1] * coordinates[i][0] - coordinates[i - 1][0] * coordinates[i][1];
}
return (b - a) * .5;
return area * .5;
};
coordinates.centroid = function(k) {
var i = -1, n = coordinates.length, x = 0, y = 0, a, b = coordinates[n - 1], c;
+530 -372
View File
File diff suppressed because it is too large Load Diff