Merge branch '3.2.3'
This commit is contained in:
Коммит
747c523e02
|
@ -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",
|
||||
|
|
|
@ -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(d, i) {
|
||||
return this.insertBefore(d3_document.createElementNS(this.namespaceURI, name), before.call(this, d, i));
|
||||
}
|
||||
function insertNS(d, i) {
|
||||
return this.insertBefore(d3_document.createElementNS(name.space, name.local), before.call(this, d, i));
|
||||
}
|
||||
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 = [];
|
||||
|
@ -4284,50 +4283,55 @@ 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];
|
||||
while (++i < n) {
|
||||
area += coordinates[i - 1][1] * coordinates[i][0] - coordinates[i - 1][0] * coordinates[i][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());
|
||||
while (++i < n) {
|
||||
a = b;
|
||||
b = coordinates[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;
|
||||
while (++i < n) {
|
||||
input = subject.slice();
|
||||
subject.length = 0;
|
||||
b = coordinates[i];
|
||||
c = input[(m = input.length) - 1];
|
||||
j = -1;
|
||||
while (++j < m) {
|
||||
d = input[j];
|
||||
if (d3_geom_polygonInside(d, a, b)) {
|
||||
if (!d3_geom_polygonInside(c, a, b)) {
|
||||
subject.push(d3_geom_polygonIntersect(c, d, a, b));
|
||||
}
|
||||
subject.push(d);
|
||||
} else if (d3_geom_polygonInside(c, a, b)) {
|
||||
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) {
|
||||
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 = this[n - 1], c;
|
||||
if (!arguments.length) k = -1 / (6 * this.area());
|
||||
while (++i < n) {
|
||||
a = b;
|
||||
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 ];
|
||||
};
|
||||
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 = this[i];
|
||||
c = input[(m = input.length - closed) - 1];
|
||||
j = -1;
|
||||
while (++j < m) {
|
||||
d = input[j];
|
||||
if (d3_geom_polygonInside(d, a, b)) {
|
||||
if (!d3_geom_polygonInside(c, a, b)) {
|
||||
subject.push(d3_geom_polygonIntersect(c, d, a, b));
|
||||
}
|
||||
c = d;
|
||||
subject.push(d);
|
||||
} else if (d3_geom_polygonInside(c, a, b)) {
|
||||
subject.push(d3_geom_polygonIntersect(c, d, a, b));
|
||||
}
|
||||
a = b;
|
||||
c = d;
|
||||
}
|
||||
return subject;
|
||||
};
|
||||
return coordinates;
|
||||
if (closed) subject.push(subject[0]);
|
||||
a = b;
|
||||
}
|
||||
return subject;
|
||||
};
|
||||
function d3_geom_polygonInside(p, a, b) {
|
||||
return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
|
||||
|
@ -4336,6 +4340,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 [];
|
||||
|
@ -4891,122 +4899,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];
|
||||
}
|
||||
|
@ -5021,6 +4919,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;
|
||||
|
@ -5094,9 +4999,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);
|
||||
|
@ -5249,6 +5151,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) {
|
||||
|
@ -6222,10 +6227,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) {
|
||||
|
@ -6248,7 +6255,7 @@ d3 = function() {
|
|||
};
|
||||
pack.radius = function(_) {
|
||||
if (!arguments.length) return radius;
|
||||
radius = _;
|
||||
radius = _ == null || typeof _ === "function" ? _ : +_;
|
||||
return pack;
|
||||
};
|
||||
pack.padding = function(_) {
|
||||
|
@ -7419,7 +7426,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;
|
||||
}
|
||||
|
@ -7438,7 +7445,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; ) {
|
||||
|
@ -7455,7 +7462,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]) {
|
||||
|
@ -7506,7 +7513,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);
|
||||
}
|
||||
|
@ -7557,14 +7564,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);
|
||||
});
|
||||
});
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -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];
|
||||
};
|
||||
|
|
|
@ -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,72 +1,88 @@
|
|||
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) {
|
||||
var i = -1,
|
||||
n = coordinates.length,
|
||||
x = 0,
|
||||
y = 0,
|
||||
a,
|
||||
b = coordinates[n - 1],
|
||||
c;
|
||||
if (!arguments.length) k = -1 / (6 * coordinates.area());
|
||||
while (++i < n) {
|
||||
a = b;
|
||||
b = coordinates[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];
|
||||
};
|
||||
d3_geom_polygonPrototype.area = function() {
|
||||
var i = -1,
|
||||
n = this.length,
|
||||
a,
|
||||
b = this[n - 1],
|
||||
area = 0;
|
||||
|
||||
// The Sutherland-Hodgman clipping algorithm.
|
||||
// Note: requires the clip polygon to be counterclockwise and convex.
|
||||
coordinates.clip = function(subject) {
|
||||
var input,
|
||||
i = -1,
|
||||
n = coordinates.length,
|
||||
j,
|
||||
m,
|
||||
a = coordinates[n - 1],
|
||||
b,
|
||||
c,
|
||||
d;
|
||||
while (++i < n) {
|
||||
input = subject.slice();
|
||||
subject.length = 0;
|
||||
b = coordinates[i];
|
||||
c = input[(m = input.length) - 1];
|
||||
j = -1;
|
||||
while (++j < m) {
|
||||
d = input[j];
|
||||
if (d3_geom_polygonInside(d, a, b)) {
|
||||
if (!d3_geom_polygonInside(c, a, b)) {
|
||||
subject.push(d3_geom_polygonIntersect(c, d, a, b));
|
||||
}
|
||||
subject.push(d);
|
||||
} else if (d3_geom_polygonInside(c, a, b)) {
|
||||
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 = this[n - 1],
|
||||
c;
|
||||
|
||||
if (!arguments.length) k = -1 / (6 * this.area());
|
||||
|
||||
while (++i < n) {
|
||||
a = b;
|
||||
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.
|
||||
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 = this[i];
|
||||
c = input[(m = input.length - closed) - 1];
|
||||
j = -1;
|
||||
while (++j < m) {
|
||||
d = input[j];
|
||||
if (d3_geom_polygonInside(d, a, b)) {
|
||||
if (!d3_geom_polygonInside(c, a, b)) {
|
||||
subject.push(d3_geom_polygonIntersect(c, d, a, b));
|
||||
}
|
||||
c = d;
|
||||
subject.push(d);
|
||||
} else if (d3_geom_polygonInside(c, a, b)) {
|
||||
subject.push(d3_geom_polygonIntersect(c, d, a, b));
|
||||
}
|
||||
a = b;
|
||||
c = d;
|
||||
}
|
||||
return subject;
|
||||
};
|
||||
if (closed) subject.push(subject[0]);
|
||||
a = b;
|
||||
}
|
||||
|
||||
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(d, i) {
|
||||
return this.insertBefore(
|
||||
d3_document.createElementNS(this.namespaceURI, name),
|
||||
before.call(this, d, i));
|
||||
}
|
||||
|
||||
function insertNS(d, i) {
|
||||
return this.insertBefore(
|
||||
d3_document.createElementNS(name.space, name.local),
|
||||
before.call(this, d, i));
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче