This commit is contained in:
Mike Bostock 2013-03-03 09:11:21 -08:00
Родитель 4648db5bdd 3855a60b86
Коммит 7dbb732a6f
13 изменённых файлов: 112 добавлений и 60 удалений

Просмотреть файл

@ -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 \

Просмотреть файл

@ -1,5 +1,5 @@
{
"name": "d3",
"version": "3.0.6",
"version": "3.0.7",
"main": "./d3.js"
}

29
d3.js поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
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;
}

8
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,6 +1,6 @@
{
"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"

Просмотреть файл

@ -1,6 +1,6 @@
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);

3
src/geo/haversin.js Normal file
Просмотреть файл

@ -0,0 +1,3 @@
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);
}
}
});

Просмотреть файл

@ -0,0 +1,25 @@
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);