Merge branch 'master' into enter-insert-in-order

Conflicts:
	src/selection/insert.js
This commit is contained in:
Mike Bostock 2013-07-03 10:08:27 -07:00
Родитель 6fa6e04ab6 747c523e02
Коммит 27a7252dce
36 изменённых файлов: 455 добавлений и 355 удалений

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

@ -9,10 +9,22 @@ console.log(JSON.stringify({
"scripts": [
"d3.js"
],
"ignore": fs.readdirSync(".").filter(function(d) {
return d !== "d3.js"
&& d !== "bower.json"
&& d !== "LICENSE"
&& d !== "README.md";
})
"ignore": [
".DS_Store",
".git",
".gitignore",
".npmignore",
".travis.yml",
"Makefile",
"bin",
"component.json",
"d3.min.js",
"index-browserify.js",
"index.js",
"lib",
"node_modules",
"package.json",
"src",
"test"
]
}, null, 2));

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

@ -1,6 +1,6 @@
{
"name": "d3",
"version": "3.2.2",
"version": "3.2.3",
"main": "d3.js",
"scripts": [
"d3.js"

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

@ -10,7 +10,7 @@
"animation",
"canvas"
],
"version": "3.2.2",
"version": "3.2.3",
"main": "index-browserify.js",
"scripts": [
"d3.js",

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

@ -1,6 +1,6 @@
d3 = function() {
var d3 = {
version: "3.2.2"
version: "3.2.3"
};
if (!Date.now) Date.now = function() {
return +new Date();
@ -380,11 +380,6 @@ d3 = function() {
} catch (e) {
d3_array = d3_arrayCopy;
}
var d3_arraySubclass = [].__proto__ ? function(array, prototype) {
array.__proto__ = prototype;
} : function(array, prototype) {
for (var property in prototype) array[property] = prototype[property];
};
function d3_noop() {}
d3.dispatch = function() {
var dispatch = new d3_dispatch(), i = -1, n = arguments.length;
@ -458,8 +453,13 @@ d3 = function() {
return s.replace(d3_requote_re, "\\$&");
};
var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
var d3_subclass = {}.__proto__ ? function(object, prototype) {
object.__proto__ = prototype;
} : function(object, prototype) {
for (var property in prototype) object[property] = prototype[property];
};
function d3_selection(groups) {
d3_arraySubclass(groups, d3_selectionPrototype);
d3_subclass(groups, d3_selectionPrototype);
return groups;
}
var d3_select = function(s, n) {
@ -484,7 +484,7 @@ d3 = function() {
var d3_selectionPrototype = d3.selection.prototype = [];
d3_selectionPrototype.select = function(selector) {
var subgroups = [], subgroup, subnode, group, node;
if (typeof selector !== "function") selector = d3_selection_selector(selector);
selector = d3_selection_selector(selector);
for (var j = -1, m = this.length; ++j < m; ) {
subgroups.push(subgroup = []);
subgroup.parentNode = (group = this[j]).parentNode;
@ -500,13 +500,13 @@ d3 = function() {
return d3_selection(subgroups);
};
function d3_selection_selector(selector) {
return function() {
return typeof selector === "function" ? selector : function() {
return d3_select(selector, this);
};
}
d3_selectionPrototype.selectAll = function(selector) {
var subgroups = [], subgroup, node;
if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
selector = d3_selection_selectorAll(selector);
for (var j = -1, m = this.length; ++j < m; ) {
for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
if (node = group[i]) {
@ -518,7 +518,7 @@ d3 = function() {
return d3_selection(subgroups);
};
function d3_selection_selectorAll(selector) {
return function() {
return typeof selector === "function" ? selector : function() {
return d3_selectAll(selector, this);
};
}
@ -696,25 +696,24 @@ d3 = function() {
}) : this.node().innerHTML;
};
d3_selectionPrototype.append = function(name) {
name = d3.ns.qualify(name);
function append() {
return this.appendChild(d3_document.createElementNS(this.namespaceURI, name));
}
function appendNS() {
return this.appendChild(d3_document.createElementNS(name.space, name.local));
}
return this.select(name.local ? appendNS : append);
name = d3_selection_creator(name);
return this.select(function() {
return this.appendChild(name.apply(this, arguments));
});
};
function d3_selection_creator(name) {
return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() {
return d3_document.createElementNS(name.space, name.local);
} : function() {
return d3_document.createElementNS(this.namespaceURI, name);
};
}
d3_selectionPrototype.insert = function(name, before) {
name = d3.ns.qualify(name);
if (typeof before !== "function") before = d3_selection_selector(before);
function insert() {
return this.insertBefore(d3_document.createElementNS(this.namespaceURI, name), before.apply(this, arguments));
}
function insertNS() {
return this.insertBefore(d3_document.createElementNS(name.space, name.local), before.apply(this, arguments));
}
return this.select(name.local ? insertNS : insert);
name = d3_selection_creator(name);
before = d3_selection_selector(before);
return this.select(function() {
return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments));
});
};
d3_selectionPrototype.remove = function() {
return this.each(function() {
@ -891,7 +890,7 @@ d3 = function() {
return n;
};
function d3_selection_enter(selection) {
d3_arraySubclass(selection, d3_selection_enterPrototype);
d3_subclass(selection, d3_selection_enterPrototype);
return selection;
}
var d3_selection_enterPrototype = [];
@ -4297,32 +4296,38 @@ d3 = function() {
return (f - b) * (c - a) - (d - b) * (e - a) > 0;
}
d3.geom.polygon = function(coordinates) {
coordinates.area = function() {
var i = 0, n = coordinates.length, area = coordinates[n - 1][1] * coordinates[0][0] - coordinates[n - 1][0] * coordinates[0][1];
d3_subclass(coordinates, d3_geom_polygonPrototype);
return coordinates;
};
var d3_geom_polygonPrototype = d3.geom.polygon.prototype = [];
d3_geom_polygonPrototype.area = function() {
var i = -1, n = this.length, a, b = this[n - 1], area = 0;
while (++i < n) {
area += coordinates[i - 1][1] * coordinates[i][0] - coordinates[i - 1][0] * coordinates[i][1];
a = b;
b = this[i];
area += a[1] * b[0] - a[0] * b[1];
}
return area * .5;
};
coordinates.centroid = function(k) {
var i = -1, n = coordinates.length, x = 0, y = 0, a, b = coordinates[n - 1], c;
if (!arguments.length) k = -1 / (6 * coordinates.area());
d3_geom_polygonPrototype.centroid = function(k) {
var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c;
if (!arguments.length) k = -1 / (6 * this.area());
while (++i < n) {
a = b;
b = coordinates[i];
b = this[i];
c = a[0] * b[1] - b[0] * a[1];
x += (a[0] + b[0]) * c;
y += (a[1] + b[1]) * c;
}
return [ x * k, y * k ];
};
coordinates.clip = function(subject) {
var input, i = -1, n = coordinates.length, j, m, a = coordinates[n - 1], b, c, d;
d3_geom_polygonPrototype.clip = function(subject) {
var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d;
while (++i < n) {
input = subject.slice();
subject.length = 0;
b = coordinates[i];
c = input[(m = input.length) - 1];
b = this[i];
c = input[(m = input.length - closed) - 1];
j = -1;
while (++j < m) {
d = input[j];
@ -4336,12 +4341,11 @@ d3 = function() {
}
c = d;
}
if (closed) subject.push(subject[0]);
a = b;
}
return subject;
};
return coordinates;
};
function d3_geom_polygonInside(p, a, b) {
return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
}
@ -4349,6 +4353,10 @@ d3 = function() {
var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
return [ x1 + ua * x21, y1 + ua * y21 ];
}
function d3_geom_polygonClosed(coordinates) {
var a = coordinates[0], b = coordinates[coordinates.length - 1];
return !(a[0] - b[0] || a[1] - b[1]);
}
d3.geom.delaunay = function(vertices) {
var edges = vertices.map(function() {
return [];
@ -4904,122 +4912,12 @@ d3 = function() {
return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t));
};
}
d3.transform = function(string) {
var g = d3_document.createElementNS(d3.ns.prefix.svg, "g");
return (d3.transform = function(string) {
if (string != null) {
g.setAttribute("transform", string);
var t = g.transform.baseVal.consolidate();
}
return new d3_transform(t ? t.matrix : d3_transformIdentity);
})(string);
};
function d3_transform(m) {
var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
if (r0[0] * r1[1] < r1[0] * r0[1]) {
r0[0] *= -1;
r0[1] *= -1;
kx *= -1;
kz *= -1;
}
this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees;
this.translate = [ m.e, m.f ];
this.scale = [ kx, ky ];
this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0;
}
d3_transform.prototype.toString = function() {
return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")";
};
function d3_transformDot(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
function d3_transformNormalize(a) {
var k = Math.sqrt(d3_transformDot(a, a));
if (k) {
a[0] /= k;
a[1] /= k;
}
return k;
}
function d3_transformCombine(a, b, k) {
a[0] += k * b[0];
a[1] += k * b[1];
return a;
}
var d3_transformIdentity = {
a: 1,
b: 0,
c: 0,
d: 1,
e: 0,
f: 0
};
d3.interpolateNumber = d3_interpolateNumber;
function d3_interpolateNumber(a, b) {
b -= a = +a;
return function(t) {
return a + b * t;
};
}
d3.interpolateTransform = d3_interpolateTransform;
function d3_interpolateTransform(a, b) {
var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale;
if (ta[0] != tb[0] || ta[1] != tb[1]) {
s.push("translate(", null, ",", null, ")");
q.push({
i: 1,
x: d3_interpolateNumber(ta[0], tb[0])
}, {
i: 3,
x: d3_interpolateNumber(ta[1], tb[1])
});
} else if (tb[0] || tb[1]) {
s.push("translate(" + tb + ")");
} else {
s.push("");
}
if (ra != rb) {
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;
q.push({
i: s.push(s.pop() + "rotate(", null, ")") - 2,
x: d3_interpolateNumber(ra, rb)
});
} else if (rb) {
s.push(s.pop() + "rotate(" + rb + ")");
}
if (wa != wb) {
q.push({
i: s.push(s.pop() + "skewX(", null, ")") - 2,
x: d3_interpolateNumber(wa, wb)
});
} else if (wb) {
s.push(s.pop() + "skewX(" + wb + ")");
}
if (ka[0] != kb[0] || ka[1] != kb[1]) {
n = s.push(s.pop() + "scale(", null, ",", null, ")");
q.push({
i: n - 4,
x: d3_interpolateNumber(ka[0], kb[0])
}, {
i: n - 2,
x: d3_interpolateNumber(ka[1], kb[1])
});
} else if (kb[0] != 1 || kb[1] != 1) {
s.push(s.pop() + "scale(" + kb + ")");
}
n = q.length;
return function(t) {
var i = -1, o;
while (++i < n) s[(o = q[i]).i] = o.x(t);
return s.join("");
};
}
d3.interpolateObject = d3_interpolateObject;
function d3_interpolateObject(a, b) {
var i = {}, c = {}, k;
for (k in a) {
if (k in b) {
i[k] = d3_interpolateByName(k)(a[k], b[k]);
i[k] = d3_interpolate(a[k], b[k]);
} else {
c[k] = a[k];
}
@ -5034,6 +4932,13 @@ d3 = function() {
return c;
};
}
d3.interpolateNumber = d3_interpolateNumber;
function d3_interpolateNumber(a, b) {
b -= a = +a;
return function(t) {
return a + b * t;
};
}
d3.interpolateString = d3_interpolateString;
function d3_interpolateString(a, b) {
var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o;
@ -5107,9 +5012,6 @@ d3 = function() {
while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ;
return f;
}
function d3_interpolateByName(name) {
return name == "transform" ? d3_interpolateTransform : d3_interpolate;
}
d3.interpolators = [ function(a, b) {
var t = typeof b;
return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : t === "object" ? Array.isArray(b) ? d3_interpolateArray : d3_interpolateObject : d3_interpolateNumber)(a, b);
@ -5262,6 +5164,109 @@ d3 = function() {
return Math.round(a + b * t);
};
}
d3.transform = function(string) {
var g = d3_document.createElementNS(d3.ns.prefix.svg, "g");
return (d3.transform = function(string) {
if (string != null) {
g.setAttribute("transform", string);
var t = g.transform.baseVal.consolidate();
}
return new d3_transform(t ? t.matrix : d3_transformIdentity);
})(string);
};
function d3_transform(m) {
var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
if (r0[0] * r1[1] < r1[0] * r0[1]) {
r0[0] *= -1;
r0[1] *= -1;
kx *= -1;
kz *= -1;
}
this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees;
this.translate = [ m.e, m.f ];
this.scale = [ kx, ky ];
this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0;
}
d3_transform.prototype.toString = function() {
return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")";
};
function d3_transformDot(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
function d3_transformNormalize(a) {
var k = Math.sqrt(d3_transformDot(a, a));
if (k) {
a[0] /= k;
a[1] /= k;
}
return k;
}
function d3_transformCombine(a, b, k) {
a[0] += k * b[0];
a[1] += k * b[1];
return a;
}
var d3_transformIdentity = {
a: 1,
b: 0,
c: 0,
d: 1,
e: 0,
f: 0
};
d3.interpolateTransform = d3_interpolateTransform;
function d3_interpolateTransform(a, b) {
var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale;
if (ta[0] != tb[0] || ta[1] != tb[1]) {
s.push("translate(", null, ",", null, ")");
q.push({
i: 1,
x: d3_interpolateNumber(ta[0], tb[0])
}, {
i: 3,
x: d3_interpolateNumber(ta[1], tb[1])
});
} else if (tb[0] || tb[1]) {
s.push("translate(" + tb + ")");
} else {
s.push("");
}
if (ra != rb) {
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;
q.push({
i: s.push(s.pop() + "rotate(", null, ")") - 2,
x: d3_interpolateNumber(ra, rb)
});
} else if (rb) {
s.push(s.pop() + "rotate(" + rb + ")");
}
if (wa != wb) {
q.push({
i: s.push(s.pop() + "skewX(", null, ")") - 2,
x: d3_interpolateNumber(wa, wb)
});
} else if (wb) {
s.push(s.pop() + "skewX(" + wb + ")");
}
if (ka[0] != kb[0] || ka[1] != kb[1]) {
n = s.push(s.pop() + "scale(", null, ",", null, ")");
q.push({
i: n - 4,
x: d3_interpolateNumber(ka[0], kb[0])
}, {
i: n - 2,
x: d3_interpolateNumber(ka[1], kb[1])
});
} else if (kb[0] != 1 || kb[1] != 1) {
s.push(s.pop() + "scale(" + kb + ")");
}
n = q.length;
return function(t) {
var i = -1, o;
while (++i < n) s[(o = q[i]).i] = o.x(t);
return s.join("");
};
}
function d3_uninterpolateNumber(a, b) {
b = b - (a = +a) ? 1 / (b - a) : 0;
return function(x) {
@ -6235,10 +6240,12 @@ d3 = function() {
d3.layout.pack = function() {
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius;
function pack(d, i) {
var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius || Math.sqrt;
var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() {
return radius;
};
root.x = root.y = 0;
d3_layout_treeVisitAfter(root, function(d) {
d.r = r(d.value);
d.r = +r(d.value);
});
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
if (padding) {
@ -6261,7 +6268,7 @@ d3 = function() {
};
pack.radius = function(_) {
if (!arguments.length) return radius;
radius = _;
radius = _ == null || typeof _ === "function" ? _ : +_;
return pack;
};
pack.padding = function(_) {
@ -7432,7 +7439,7 @@ d3 = function() {
d3.svg.symbolTypes = d3_svg_symbols.keys();
var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians);
function d3_transition(groups, id) {
d3_arraySubclass(groups, d3_transitionPrototype);
d3_subclass(groups, d3_transitionPrototype);
groups.id = id;
return groups;
}
@ -7451,7 +7458,7 @@ d3 = function() {
d3.transition.prototype = d3_transitionPrototype;
d3_transitionPrototype.select = function(selector) {
var id = this.id, subgroups = [], subgroup, subnode, node;
if (typeof selector !== "function") selector = d3_selection_selector(selector);
selector = d3_selection_selector(selector);
for (var j = -1, m = this.length; ++j < m; ) {
subgroups.push(subgroup = []);
for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
@ -7468,7 +7475,7 @@ d3 = function() {
};
d3_transitionPrototype.selectAll = function(selector) {
var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition;
if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
selector = d3_selection_selectorAll(selector);
for (var j = -1, m = this.length; ++j < m; ) {
for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
if (node = group[i]) {
@ -7519,7 +7526,7 @@ d3 = function() {
for (value in nameNS) this.attr(value, nameNS[value]);
return this;
}
var interpolate = d3_interpolateByName(nameNS), name = d3.ns.qualify(nameNS);
var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);
function attrNull() {
this.removeAttribute(name);
}
@ -7570,14 +7577,13 @@ d3 = function() {
}
priority = "";
}
var interpolate = d3_interpolateByName(name);
function styleNull() {
this.style.removeProperty(name);
}
function styleString(b) {
return b == null ? styleNull : (b += "", function() {
var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i;
return a !== b && (i = interpolate(a, b), function(t) {
return a !== b && (i = d3_interpolate(a, b), function(t) {
this.style.setProperty(name, i(t), priority);
});
});

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

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

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

@ -1,6 +1,6 @@
{
"name": "d3",
"version": "3.2.2",
"version": "3.2.3",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",

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

@ -17,15 +17,3 @@ try {
} catch(e) {
d3_array = d3_arrayCopy;
}
var d3_arraySubclass = [].__proto__?
// Until ECMAScript supports array subclassing, prototype injection works well.
function(array, prototype) {
array.__proto__ = prototype;
}:
// And if your browser doesn't support __proto__, we'll use direct extension.
function(array, prototype) {
for (var property in prototype) array[property] = prototype[property];
};

11
src/core/subclass.js Normal file
Просмотреть файл

@ -0,0 +1,11 @@
var d3_subclass = {}.__proto__?
// Until ECMAScript supports array subclassing, prototype injection works well.
function(object, prototype) {
object.__proto__ = prototype;
}:
// And if your browser doesn't support __proto__, we'll use direct extension.
function(object, prototype) {
for (var property in prototype) object[property] = prototype[property];
};

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

@ -1,53 +1,70 @@
import "../core/subclass";
import "geom";
d3.geom.polygon = function(coordinates) {
d3_subclass(coordinates, d3_geom_polygonPrototype);
return coordinates;
};
coordinates.area = function() {
var i = 0,
n = coordinates.length,
area = coordinates[n - 1][1] * coordinates[0][0] - coordinates[n - 1][0] * coordinates[0][1];
while (++i < n) {
area += coordinates[i - 1][1] * coordinates[i][0] - coordinates[i - 1][0] * coordinates[i][1];
}
return area * .5;
};
var d3_geom_polygonPrototype = d3.geom.polygon.prototype = [];
coordinates.centroid = function(k) {
d3_geom_polygonPrototype.area = function() {
var i = -1,
n = coordinates.length,
n = this.length,
a,
b = this[n - 1],
area = 0;
while (++i < n) {
a = b;
b = this[i];
area += a[1] * b[0] - a[0] * b[1];
}
return area * .5;
};
d3_geom_polygonPrototype.centroid = function(k) {
var i = -1,
n = this.length,
x = 0,
y = 0,
a,
b = coordinates[n - 1],
b = this[n - 1],
c;
if (!arguments.length) k = -1 / (6 * coordinates.area());
if (!arguments.length) k = -1 / (6 * this.area());
while (++i < n) {
a = b;
b = coordinates[i];
b = this[i];
c = a[0] * b[1] - b[0] * a[1];
x += (a[0] + b[0]) * c;
y += (a[1] + b[1]) * c;
}
return [x * k, y * k];
};
// The Sutherland-Hodgman clipping algorithm.
// Note: requires the clip polygon to be counterclockwise and convex.
coordinates.clip = function(subject) {
return [x * k, y * k];
};
// The Sutherland-Hodgman clipping algorithm.
// Note: requires the clip polygon to be counterclockwise and convex.
d3_geom_polygonPrototype.clip = function(subject) {
var input,
closed = d3_geom_polygonClosed(subject),
i = -1,
n = coordinates.length,
n = this.length - d3_geom_polygonClosed(this),
j,
m,
a = coordinates[n - 1],
a = this[n - 1],
b,
c,
d;
while (++i < n) {
input = subject.slice();
subject.length = 0;
b = coordinates[i];
c = input[(m = input.length) - 1];
b = this[i];
c = input[(m = input.length - closed) - 1];
j = -1;
while (++j < m) {
d = input[j];
@ -61,12 +78,11 @@ d3.geom.polygon = function(coordinates) {
}
c = d;
}
if (closed) subject.push(subject[0]);
a = b;
}
return subject;
};
return coordinates;
return subject;
};
function d3_geom_polygonInside(p, a, b) {
@ -80,3 +96,10 @@ function d3_geom_polygonIntersect(c, d, a, b) {
ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
return [x1 + ua * x21, y1 + ua * y21];
}
// Returns true if the polygon is closed.
function d3_geom_polygonClosed(coordinates) {
var a = coordinates[0],
b = coordinates[coordinates.length - 1];
return !(a[0] - b[0] || a[1] - b[1]);
}

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

@ -1,7 +1,6 @@
import "../color/color";
import "../color/rgb";
import "rgb";
import "transform";
import "object";
import "array";
import "number";
@ -15,12 +14,6 @@ function d3_interpolate(a, b) {
return f;
}
function d3_interpolateByName(name) {
return name == "transform"
? d3_interpolateTransform
: d3_interpolate;
}
d3.interpolators = [
function(a, b) {
var t = typeof b;

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

@ -8,7 +8,7 @@ function d3_interpolateObject(a, b) {
k;
for (k in a) {
if (k in b) {
i[k] = d3_interpolateByName(k)(a[k], b[k]);
i[k] = d3_interpolate(a[k], b[k]);
} else {
c[k] = a[k];
}

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

@ -13,11 +13,11 @@ d3.layout.pack = function() {
root = nodes[0],
w = size[0],
h = size[1],
r = radius || Math.sqrt;
r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { return radius; };
// Recursively compute the layout.
root.x = root.y = 0;
d3_layout_treeVisitAfter(root, function(d) { d.r = r(d.value); });
d3_layout_treeVisitAfter(root, function(d) { d.r = +r(d.value); });
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
// When padding, recompute the layout using scaled padding.
@ -42,7 +42,7 @@ d3.layout.pack = function() {
pack.radius = function(_) {
if (!arguments.length) return radius;
radius = _;
radius = _ == null || typeof _ === "function" ? _ : +_;
return pack;
};

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

@ -2,18 +2,15 @@ import "../core/document";
import "../core/ns";
import "selection";
// TODO append(node)?
// TODO append(function)?
d3_selectionPrototype.append = function(name) {
name = d3.ns.qualify(name);
function append() {
return this.appendChild(d3_document.createElementNS(this.namespaceURI, name));
}
function appendNS() {
return this.appendChild(d3_document.createElementNS(name.space, name.local));
}
return this.select(name.local ? appendNS : append);
name = d3_selection_creator(name);
return this.select(function() {
return this.appendChild(name.apply(this, arguments));
});
};
function d3_selection_creator(name) {
return typeof name === "function" ? name
: (name = d3.ns.qualify(name)).local ? function() { return d3_document.createElementNS(name.space, name.local); }
: function() { return d3_document.createElementNS(this.namespaceURI, name); };
}

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

@ -1,8 +1,8 @@
import "../core/array";
import "../core/subclass";
import "selection";
function d3_selection_enter(selection) {
d3_arraySubclass(selection, d3_selection_enterPrototype);
d3_subclass(selection, d3_selection_enterPrototype);
return selection;
}

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

@ -1,23 +1,9 @@
import "../core/document";
import "../core/ns";
import "selection";
d3_selectionPrototype.insert = function(name, before) {
name = d3.ns.qualify(name);
if (typeof before !== "function") before = d3_selection_selector(before);
function insert() {
return this.insertBefore(
d3_document.createElementNS(this.namespaceURI, name),
before.apply(this, arguments));
}
function insertNS() {
return this.insertBefore(
d3_document.createElementNS(name.space, name.local),
before.apply(this, arguments));
}
return this.select(name.local ? insertNS : insert);
name = d3_selection_creator(name);
before = d3_selection_selector(before);
return this.select(function() {
return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments));
});
};

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

@ -7,7 +7,7 @@ d3_selectionPrototype.select = function(selector) {
group,
node;
if (typeof selector !== "function") selector = d3_selection_selector(selector);
selector = d3_selection_selector(selector);
for (var j = -1, m = this.length; ++j < m;) {
subgroups.push(subgroup = []);
@ -26,7 +26,7 @@ d3_selectionPrototype.select = function(selector) {
};
function d3_selection_selector(selector) {
return function() {
return typeof selector === "function" ? selector : function() {
return d3_select(selector, this);
};
}

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

@ -6,7 +6,7 @@ d3_selectionPrototype.selectAll = function(selector) {
subgroup,
node;
if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
selector = d3_selection_selectorAll(selector);
for (var j = -1, m = this.length; ++j < m;) {
for (var group = this[j], i = -1, n = group.length; ++i < n;) {
@ -21,7 +21,7 @@ d3_selectionPrototype.selectAll = function(selector) {
};
function d3_selection_selectorAll(selector) {
return function() {
return typeof selector === "function" ? selector : function() {
return d3_selectAll(selector, this);
};
}

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

@ -1,9 +1,10 @@
import "../core/array";
import "../core/document";
import "../core/subclass";
import "../core/vendor";
function d3_selection(groups) {
d3_arraySubclass(groups, d3_selectionPrototype);
d3_subclass(groups, d3_selectionPrototype);
return groups;
}

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

@ -1,2 +1,2 @@
d3 = (function(){
var d3 = {version: "3.2.2"}; // semver
var d3 = {version: "3.2.3"}; // semver

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

@ -1,5 +1,6 @@
import "../core/ns";
import "../interpolate/interpolate";
import "../interpolate/transform";
import "transition";
import "tween";
@ -13,7 +14,7 @@ d3_transitionPrototype.attr = function(nameNS, value) {
return this;
}
var interpolate = d3_interpolateByName(nameNS),
var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate,
name = d3.ns.qualify(nameNS);
// For attr(string, null), remove the attribute with the specified name.

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

@ -8,7 +8,7 @@ d3_transitionPrototype.select = function(selector) {
subnode,
node;
if (typeof selector !== "function") selector = d3_selection_selector(selector);
selector = d3_selection_selector(selector);
for (var j = -1, m = this.length; ++j < m;) {
subgroups.push(subgroup = []);

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

@ -10,7 +10,7 @@ d3_transitionPrototype.selectAll = function(selector) {
subnode,
transition;
if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
selector = d3_selection_selectorAll(selector);
for (var j = -1, m = this.length; ++j < m;) {
for (var group = this[j], i = -1, n = group.length; ++i < n;) {

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

@ -22,8 +22,6 @@ d3_transitionPrototype.style = function(name, value, priority) {
priority = "";
}
var interpolate = d3_interpolateByName(name);
// For style(name, null) or style(name, null, priority), remove the style
// property with the specified name. The priority is ignored.
function styleNull() {
@ -36,7 +34,7 @@ d3_transitionPrototype.style = function(name, value, priority) {
function styleString(b) {
return b == null ? styleNull : (b += "", function() {
var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i;
return a !== b && (i = interpolate(a, b), function(t) { this.style.setProperty(name, i(t), priority); });
return a !== b && (i = d3_interpolate(a, b), function(t) { this.style.setProperty(name, i(t), priority); });
});
}

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

@ -1,12 +1,12 @@
import "../arrays/map";
import "../core/array";
import "../core/subclass";
import "../event/dispatch";
import "../event/timer";
import "../interpolate/ease";
import "../selection/selection";
function d3_transition(groups, id) {
d3_arraySubclass(groups, d3_transitionPrototype);
d3_subclass(groups, d3_transitionPrototype);
groups.id = id; // Note: read-only!

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

@ -12,70 +12,105 @@ suite.addBatch({
topic: function(polygon) {
return polygon([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]);
},
"preserves input coordinates": function(p) {
assertPolygonInDelta(p, [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]);
},
"has area 1": function(p) {
assert.equal(p.area(), 1);
},
"has centroid ⟨.5,.5⟩": function(p) {
assert.deepEqual(p.centroid(), [.5, .5]);
assertPointInDelta(p.centroid(), [.5, .5]);
},
"can clip an open counterclockwise triangle": function(p) {
assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1]], 1e-4);
},
"can clip a closed counterclockwise triangle": function(p) {
assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1], [0.9, 0.5]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1], [0.9, 0.5]], 1e-4);
}
},
"closed clockwise unit square": {
topic: function(polygon) {
return polygon([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]);
},
"preserves input coordinates": function(p) {
assertPolygonInDelta(p, [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]);
},
"has area 1": function(p) {
assert.equal(p.area(), -1);
},
"has centroid ⟨.5,.5⟩": function(p) {
assert.deepEqual(p.centroid(), [.5, .5]);
assertPointInDelta(p.centroid(), [.5, .5]);
},
"is not currently supported for clipping": function(p) {
// because clipping requires a counterclockwise source polygon
}
},
"closed clockwise triangle": {
topic: function(polygon) {
return polygon([[1, 1], [3, 2], [2, 3], [1, 1]]);
},
"preserves input coordinates": function(p) {
assertPolygonInDelta(p, [[1, 1], [3, 2], [2, 3], [1, 1]]);
},
"has area 1.5": function(p) {
assert.equal(p.area(), -1.5);
},
"has centroid ⟨2,2⟩": function(p) {
var centroid = p.centroid();
assert.inDelta(centroid[0], 2, 1e-6);
assert.inDelta(centroid[1], 2, 1e-6);
assertPointInDelta(p.centroid(), [2, 2]);
},
"is not currently supported for clipping": function(p) {
// because clipping requires a counterclockwise source polygon
}
},
"open counterclockwise unit square": {
topic: function(polygon) {
return polygon([[0, 0], [0, 1], [1, 1], [1, 0]]);
},
"remains an open polygon": function(p) {
assertPolygonInDelta(p, [[0, 0], [0, 1], [1, 1], [1, 0]]);
},
"has area 1": function(p) {
assert.equal(p.area(), 1);
},
"has centroid ⟨.5,.5⟩": function(p) {
assert.deepEqual(p.centroid(), [.5, .5]);
assertPointInDelta(p.centroid(), [.5, .5]);
},
"can clip an open counterclockwise triangle": function(p) {
assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1]], 1e-4);
},
"can clip an closed counterclockwise triangle": function(p) {
assertPolygonInDelta(p.clip([[0.9, 0.5], [2, -1], [0.5, 0.1], [0.9, 0.5]]), [[0.9, 0.5], [1, 0.363636], [1, 0], [0.636363, 0], [0.5, 0.1], [0.9, 0.5]], 1e-4);
}
},
"open clockwise unit square": {
topic: function(polygon) {
return polygon([[0, 0], [1, 0], [1, 1], [0, 1]]);
},
"remains an open polygon": function(p) {
assertPolygonInDelta(p, [[0, 0], [1, 0], [1, 1], [0, 1]]);
},
"has area 1": function(p) {
assert.equal(p.area(), -1);
},
"has centroid ⟨.5,.5⟩": function(p) {
assert.deepEqual(p.centroid(), [.5, .5]);
assertPointInDelta(p.centroid(), [.5, .5]);
},
"is not currently supported for clipping": function(p) {
// because clipping requires a counterclockwise source polygon
}
},
"open clockwise triangle": {
topic: function(polygon) {
return polygon([[1, 1], [3, 2], [2, 3]]);
},
"remains an open polygon": function(p) {
assertPolygonInDelta(p, [[1, 1], [3, 2], [2, 3]]);
},
"has area 1.5": function(p) {
assert.equal(p.area(), -1.5);
},
"has centroid ⟨2,2⟩": function(p) {
var centroid = p.centroid();
assert.inDelta(centroid[0], 2, 1e-6);
assert.inDelta(centroid[1], 2, 1e-6);
assertPointInDelta(p.centroid(), [2, 2]);
}
},
"large square": {
@ -95,4 +130,22 @@ suite.addBatch({
}
});
function assertPointInDelta(expected, actual, δ, message) {
if (!δ) δ = 0;
if (!pointInDelta(expected, actual, δ)) {
assert.fail(JSON.stringify(actual), JSON.stringify(expected), message || "expected {expected}, got {actual}", "===", assertPointInDelta);
}
}
function assertPolygonInDelta(expected, actual, δ, message) {
if (!δ) δ = 0;
if (expected.length !== actual.length || expected.some(function(e, i) { return !pointInDelta(e, actual[i], δ); })) {
assert.fail(JSON.stringify(actual), JSON.stringify(expected), message || "expected {expected}, got {actual}", "===", assertPolygonInDelta);
}
}
function pointInDelta(a, b, δ) {
return !(Math.abs(a[0] - b[0]) > δ || Math.abs(a[1] - b[1]) > δ);
}
suite.export(module);

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.interpolateArray");
suite.addBatch({
"interpolateArray": {
topic: load("interpolate/array").expression("d3.interpolateArray").document(),
topic: load("interpolate/array").expression("d3.interpolateArray"),
"interpolates defined elements": function(interpolate) {
assert.deepEqual(interpolate([2, 12], [4, 24])(.5), [3, 18]);
},

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.interpolate");
suite.addBatch({
"interpolate": {
topic: load("interpolate/interpolate").document(),
topic: load("interpolate/interpolate"),
"when b is a number": {
"interpolates numbers": function(d3) {

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.interpolateObject");
suite.addBatch({
"interpolateObject": {
topic: load("interpolate/object").expression("d3.interpolateObject").document(),
topic: load("interpolate/object").expression("d3.interpolateObject"),
"interpolates defined properties": function(interpolate) {
assert.deepEqual(interpolate({a: 2, b: 12}, {a: 4, b: 24})(.5), {a: 3, b: 18});
},

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

@ -82,11 +82,36 @@ suite.addBatch({
assert.equal(pack().radius(), null);
},
"radius can be specified using a custom function of value": function(pack) {
var p = pack().radius(function(value) { return Math.sqrt(value) * 10; });
var r = function(value) { return Math.sqrt(value) * 10; },
p = pack().radius(r);
assert.strictEqual(p.radius(), r);
assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [
{value: 1, depth: 0, x: 0.5, y: 0.5, r: 10},
{value: 1, depth: 1, x: 0.5, y: 0.5, r: 10}
]);
},
"radius can be specified as a constant": function(pack) {
var p = pack().radius(5);
assert.equal(p.radius(), 5);
assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [
{value: 1, depth: 0, x: 0.5, y: 0.5, r: 5},
{value: 1, depth: 1, x: 0.5, y: 0.5, r: 5}
]);
},
"radius constant value is coerced to a number": function(pack) {
var p = pack().radius("5");
assert.equal(p.radius(), 5);
assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [
{value: 1, depth: 0, x: 0.5, y: 0.5, r: 5},
{value: 1, depth: 1, x: 0.5, y: 0.5, r: 5}
]);
},
"radius function value is coerced to a number": function(pack) {
var p = pack().radius(function() { return "5"; });
assert.deepEqual(p.nodes({children: [{value: 1}]}).map(layout), [
{value: 1, depth: 0, x: 0.5, y: 0.5, r: 5},
{value: 1, depth: 1, x: 0.5, y: 0.5, r: 5}
]);
}
}
});

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

@ -8,7 +8,7 @@ require("./XMLHttpRequest");
module.exports = function() {
var files = [].slice.call(arguments).map(function(d) { return "src/" + d; }),
expression = "d3",
sandbox = {Date: Date}; // so we can use deepEqual in tests
sandbox = {console: console, Date: Date}; // so we can use deepEqual in tests
files.unshift("src/start");
files.push("src/end");

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.scale.identity");
suite.addBatch({
"identity": {
topic: load("scale/identity").expression("d3.scale.identity").document(),
topic: load("scale/identity").expression("d3.scale.identity"),
"domain and range": {
"are identical": function(identity) {

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.scale.linear");
suite.addBatch({
"linear": {
topic: load("scale/linear", "interpolate/hsl").document(), // beware instanceof d3_Color
topic: load("scale/linear", "interpolate/hsl"), // beware instanceof d3_Color
"domain": {
"defaults to [0, 1]": function(d3) {

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.scale.log");
suite.addBatch({
"log": {
topic: load("scale/log", "interpolate/hsl").document(), // beware instanceof d3_Color
topic: load("scale/log", "interpolate/hsl"), // beware instanceof d3_Color
"domain": {
"defaults to [1, 10], exactly": function(d3) {

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.scale.pow");
suite.addBatch({
"pow": {
topic: load("scale/pow", "interpolate/hsl").document(), // beware instance of d3_Colorr
topic: load("scale/pow", "interpolate/hsl"), // beware instance of d3_Colorr
"domain": {
"defaults to [0, 1]": function(d3) {

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

@ -6,7 +6,7 @@ var suite = vows.describe("d3.scale.sqrt");
suite.addBatch({
"sqrt": {
topic: load("scale/sqrt", "interpolate/hsl").document(), // beware instanceof d3_Color
topic: load("scale/sqrt", "interpolate/hsl"), // beware instanceof d3_Color
"domain": {
"defaults to [0, 1]": function(d3) {

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

@ -25,6 +25,12 @@ suite.addBatch({
assert.isTrue(svg[0][0].parentNode === body.node());
assert.isTrue(svg[0][0] === body.node().lastChild);
},
"appends an element specified as a function": function(body) {
var svg = body.select("svg").remove().node();
assert.isFalse(svg === body.node().lastChild);
body.append(function() { return svg; });
assert.isTrue(svg === body.node().lastChild);
},
"propagates data to new element": function(body) {
var data = new Object(), div = body.data([data]).append("div");
assert.strictEqual(div[0][0].__data__, data);