Commit 7dbb732a authored by Mike Bostock's avatar Mike Bostock
Browse files

Merge branch '3.0.7'

parents 4648db5b 3855a60b
......@@ -198,6 +198,7 @@ d3.geo.js: \
src/geo/equirectangular.js \
src/geo/gnomonic.js \
src/geo/graticule.js \
src/geo/haversin.js \
src/geo/interpolate.js \
src/geo/greatArc.js \
src/geo/mercator.js \
......
{
"name": "d3",
"version": "3.0.6",
"version": "3.0.7",
"main": "./d3.js"
}
d3 = function() {
var π = Math.PI, ε = 1e-6, d3 = {
version: "3.0.6"
version: "3.0.7"
}, d3_radians = π / 180, d3_degrees = 180 / π, d3_document = document, d3_window = window;
function d3_target(d) {
return d.target;
......@@ -124,7 +124,7 @@ d3 = function() {
function d3_rebind(target, source, method) {
return function() {
var value = method.apply(source, arguments);
return arguments.length ? target : value;
return value === source ? target : value;
};
}
d3.ascending = function(a, b) {
......@@ -5794,9 +5794,15 @@ d3 = function() {
function d3_geo_clipPolygon(segments, interpolate, listener) {
var subject = [], clip = [];
segments.forEach(function(segment) {
var n = segment.length;
if (n <= 1) return;
var p0 = segment[0], p1 = segment[n - 1], a = {
if ((n = segment.length) <= 1) return;
var n, p0 = segment[0], p1 = segment[n - 1];
if (d3_geo_sphericalEqual(p0, p1)) {
listener.lineStart();
for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]);
listener.lineEnd();
return;
}
var a = {
point: p0,
points: segment,
other: null,
......@@ -6130,15 +6136,20 @@ d3 = function() {
});
};
}
function d3_geo_haversin(x) {
return (x = Math.sin(x / 2)) * x;
}
d3.geo.interpolate = function(source, target) {
return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians);
};
function d3_geo_interpolate(x0, y0, x1, y1) {
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);
function interpolate(t) {
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 = 2 * Math.asin(Math.sqrt(d3_geo_haversin(y1 - y0) + cy0 * cy1 * d3_geo_haversin(x1 - x0))), k = 1 / Math.sin(d);
var interpolate = d ? function(t) {
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;
return [ Math.atan2(y, x) / d3_radians, Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_radians ];
}
return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ];
} : function() {
return [ x0 * d3_degrees, y0 * d3_degrees ];
};
interpolate.distance = d;
return interpolate;
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "d3",
"version": "3.0.6",
"version": "3.0.7",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
......@@ -28,11 +28,11 @@
}
},
"dependencies": {
"jsdom": "0.3.4"
"jsdom": "0.3.x"
},
"devDependencies": {
"uglify-js": "2.2.3",
"vows": "0.7.0"
"uglify-js": "2.2.x",
"vows": "0.7.x"
},
"scripts": {
"test": "./node_modules/vows/bin/vows"
......
var π = Math.PI,
ε = 1e-6,
d3 = {version: "3.0.6"}, // semver
d3 = {version: "3.0.7"}, // semver
d3_radians = π / 180,
d3_degrees = 180 / π,
d3_document = document,
......
......@@ -11,6 +11,6 @@ d3.rebind = function(target, source) {
function d3_rebind(target, source, method) {
return function() {
var value = method.apply(source, arguments);
return arguments.length ? target : value;
return value === source ? target : value;
};
}
......@@ -115,11 +115,21 @@ function d3_geo_clipPolygon(segments, interpolate, listener) {
clip = [];
segments.forEach(function(segment) {
var n = segment.length;
if (n <= 1) return;
var p0 = segment[0],
p1 = segment[n - 1],
a = {point: p0, points: segment, other: null, visited: false, entry: true, subject: true},
if ((n = segment.length) <= 1) return;
var n, p0 = segment[0], p1 = segment[n - 1];
// If the first and last points of a segment are coincident, then treat as
// a closed ring.
// TODO if all rings are closed, then the winding order of the exterior
// ring should be checked.
if (d3_geo_sphericalEqual(p0, p1)) {
listener.lineStart();
for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]);
listener.lineEnd();
return;
}
var a = {point: p0, points: segment, other: null, visited: false, entry: true, subject: true},
b = {point: p0, points: [p0], other: a, visited: false, entry: false, subject: false};
a.other = b;
subject.push(a);
......
function d3_geo_haversin(x) {
return (x = Math.sin(x / 2)) * x;
}
......@@ -14,20 +14,20 @@ function d3_geo_interpolate(x0, y0, x1, y1) {
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)))),
d = 2 * Math.asin(Math.sqrt(d3_geo_haversin(y1 - y0) + cy0 * cy1 * d3_geo_haversin(x1 - x0))),
k = 1 / Math.sin(d);
function interpolate(t) {
var interpolate = d ? function(t) {
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;
return [
Math.atan2(y, x) / d3_radians,
Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_radians
Math.atan2(y, x) * d3_degrees,
Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees
];
}
} : function() { return [x0 * d3_degrees, y0 * d3_degrees]; };
interpolate.distance = d;
......
......@@ -17,11 +17,11 @@ console.log(JSON.stringify({
}
},
"dependencies": {
"jsdom": "0.3.4"
"jsdom": "0.3.x"
},
"devDependencies": {
"uglify-js": "2.2.3",
"vows": "0.7.0"
"uglify-js": "2.2.x",
"vows": "0.7.x"
},
"scripts": {"test": "./node_modules/vows/bin/vows"}
}, null, 2));
......@@ -10,40 +10,42 @@ suite.addBatch({
topic: function() {
return d3.rebind;
},
"bound function uses source as context": function(rebind) {
var a = {}, b = {foo: function() { that = this; }}, that;
rebind(a, b, "foo");
assert.strictEqual((a.foo(), that), b);
assert.strictEqual((a.foo.call({}), that), b);
"source function always has source as context": function(rebind) {
var target = {}, source = {method: function() { that = this; }}, that;
rebind(target, source, "method");
assert.strictEqual((target.method(), that), source);
assert.strictEqual((target.method.call({}), that), source);
},
"bound function receives any arguments": function(rebind) {
var a = {}, b = {foo: function() { those = Array.prototype.slice.call(arguments); }}, those;
rebind(a, b, "foo");
assert.deepEqual((a.foo(), those), []);
assert.deepEqual((a.foo(1), those), [1]);
assert.deepEqual((a.foo(null), those), [null]);
assert.deepEqual((a.foo(b, b, 1), those), [b, b, 1]);
"source function receives target function's arguments": function(rebind) {
var target = {}, source = {method: function() { those = Array.prototype.slice.call(arguments); }}, those;
rebind(target, source, "method");
assert.deepEqual((target.method(), those), []);
assert.deepEqual((target.method(1), those), [1]);
assert.deepEqual((target.method(null), those), [null]);
assert.deepEqual((target.method(source, source, 1), those), [source, source, 1]);
},
"bound function returns object if arguments": function(rebind) {
var a = {}, b = {foo: function() {}};
rebind(a, b, "foo");
assert.strictEqual(a.foo(1), a);
assert.strictEqual(a.foo(1, 2, 3), a);
"target function returns target if source function returns source": function(rebind) {
var target = {}, source = {method: function(value) { return value ? source : 42; }};
rebind(target, source, "method");
assert.strictEqual(target.method(true), target);
},
"bound function returns return value if no arguments": function(rebind) {
var a = {}, b = {foo: function() { return that; }}, that = {};
rebind(a, b, "foo");
assert.strictEqual(a.foo(), that);
"otherwise, target function returns source function return value": function(rebind) {
var target = {}, source = {method: function(value) { return value ? source : 42; }};
rebind(target, source, "method");
assert.strictEqual(target.method(false), 42);
},
"can bind multiple methods": function(rebind) {
var a = {}, b = {foo: function() { return 1; }, bar: function() { return 2; }};
rebind(a, b, "foo", "bar");
assert.strictEqual(a.foo(), 1);
assert.strictEqual(a.bar(), 2);
var target = {}, source = {
foo: function() { return 1; },
bar: function() { return 2; }
};
rebind(target, source, "foo", "bar");
assert.strictEqual(target.foo(), 1);
assert.strictEqual(target.bar(), 2);
},
"returns the target object": function(rebind) {
var a = {}, b = {foo: function() { return that; }}, that = {};
assert.strictEqual(rebind(a, b, "foo"), a);
var target = {}, source = {foo: function() {}};
assert.strictEqual(rebind(target, source, "foo"), target);
}
}
});
......
require("../env");
var vows = require("vows"),
assert = require("assert");
var suite = vows.describe("d3.geo.interpolate");
suite.addBatch({
"interpolate": {
topic: function() {
return d3.geo.interpolate;
},
"zero distance": function(arc) {
assert.deepEqual(d3.geo.interpolate([140.63289, -29.95101], [140.63289, -29.95101])(.5), [140.63289, -29.95101]);
},
"equator": function(arc) {
assert.inDelta(d3.geo.interpolate([10, 0], [20, 0])(.5), [15, 0], 1e-6);
},
"meridian": function(arc) {
assert.inDelta(d3.geo.interpolate([10, -20], [10, 40])(.5), [10, 10], 1e-6);
}
}
});
suite.export(module);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment