Merge branch '3.4.7'
This commit is contained in:
Коммит
61c568f818
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "d3",
|
||||
"version": "3.4.6",
|
||||
"version": "3.4.7",
|
||||
"main": "d3.js",
|
||||
"scripts": [
|
||||
"d3.js"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"animation",
|
||||
"canvas"
|
||||
],
|
||||
"version": "3.4.6",
|
||||
"version": "3.4.7",
|
||||
"main": "d3.js",
|
||||
"scripts": [
|
||||
"d3.js"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
!function() {
|
||||
var d3 = {
|
||||
version: "3.4.6"
|
||||
version: "3.4.7"
|
||||
};
|
||||
if (!Date.now) Date.now = function() {
|
||||
return +new Date();
|
||||
|
@ -1362,7 +1362,7 @@
|
|||
}
|
||||
}
|
||||
function touchstarted() {
|
||||
var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, target = d3.select(d3.event.target).on(touchmove, moved).on(touchend, ended), subject = d3.select(that).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
|
||||
var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
|
||||
d3_selection_interrupt.call(that);
|
||||
started();
|
||||
zoomstarted(dispatch);
|
||||
|
@ -1375,6 +1375,9 @@
|
|||
return touches;
|
||||
}
|
||||
function started() {
|
||||
var target = d3.event.target;
|
||||
d3.select(target).on(touchmove, moved).on(touchend, ended);
|
||||
targets.push(target);
|
||||
var changed = d3.event.changedTouches;
|
||||
for (var i = 0, n = changed.length; i < n; ++i) {
|
||||
locations0[changed[i].identifier] = null;
|
||||
|
@ -1423,7 +1426,7 @@
|
|||
return void relocate();
|
||||
}
|
||||
}
|
||||
target.on(zoomName, null);
|
||||
d3.selectAll(targets).on(zoomName, null);
|
||||
subject.on(mousedown, mousedowned).on(touchstart, touchstarted);
|
||||
dragRestore();
|
||||
zoomended(dispatch);
|
||||
|
@ -6332,41 +6335,30 @@
|
|||
var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity;
|
||||
d3.layout.hierarchy = function() {
|
||||
var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue;
|
||||
function recurse(node, depth, nodes) {
|
||||
var childs = children.call(hierarchy, node, depth);
|
||||
node.depth = depth;
|
||||
nodes.push(node);
|
||||
if (childs && (n = childs.length)) {
|
||||
var i = -1, n, c = node.children = new Array(n), v = 0, j = depth + 1, d;
|
||||
while (++i < n) {
|
||||
d = c[i] = recurse(childs[i], j, nodes);
|
||||
d.parent = node;
|
||||
v += d.value;
|
||||
}
|
||||
if (sort) c.sort(sort);
|
||||
if (value) node.value = v;
|
||||
} else {
|
||||
delete node.children;
|
||||
if (value) {
|
||||
node.value = +value.call(hierarchy, node, depth) || 0;
|
||||
function hierarchy(root) {
|
||||
var stack = [ root ], nodes = [], node;
|
||||
root.depth = 0;
|
||||
while ((node = stack.pop()) != null) {
|
||||
nodes.push(node);
|
||||
if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) {
|
||||
var n, childs, child;
|
||||
while (--n >= 0) {
|
||||
stack.push(child = childs[n]);
|
||||
child.parent = node;
|
||||
child.depth = node.depth + 1;
|
||||
}
|
||||
if (value) node.value = 0;
|
||||
node.children = childs;
|
||||
} else {
|
||||
if (value) node.value = +value.call(hierarchy, node, node.depth) || 0;
|
||||
delete node.children;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
function revalue(node, depth) {
|
||||
var children = node.children, v = 0;
|
||||
if (children && (n = children.length)) {
|
||||
var i = -1, n, j = depth + 1;
|
||||
while (++i < n) v += revalue(children[i], j);
|
||||
} else if (value) {
|
||||
v = +value.call(hierarchy, node, depth) || 0;
|
||||
}
|
||||
if (value) node.value = v;
|
||||
return v;
|
||||
}
|
||||
function hierarchy(d) {
|
||||
var nodes = [];
|
||||
recurse(d, 0, nodes);
|
||||
d3_layout_hierarchyVisitAfter(root, function(node) {
|
||||
var childs, parent;
|
||||
if (sort && (childs = node.children)) childs.sort(sort);
|
||||
if (value && (parent = node.parent)) parent.value += node.value;
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
hierarchy.sort = function(x) {
|
||||
|
@ -6385,7 +6377,11 @@
|
|||
return hierarchy;
|
||||
};
|
||||
hierarchy.revalue = function(root) {
|
||||
revalue(root, 0);
|
||||
if (value) d3_layout_hierarchyVisitAfter(root, function(node) {
|
||||
var parent;
|
||||
node.value = node.children ? 0 : +value.call(hierarchy, node, node.depth) || 0;
|
||||
if (parent = node.parent) parent.value += node.value;
|
||||
});
|
||||
return root;
|
||||
};
|
||||
return hierarchy;
|
||||
|
@ -6396,6 +6392,29 @@
|
|||
object.links = d3_layout_hierarchyLinks;
|
||||
return object;
|
||||
}
|
||||
function d3_layout_hierarchyVisitBefore(node, callback) {
|
||||
var nodes = [ node ];
|
||||
while ((node = nodes.pop()) != null) {
|
||||
callback(node);
|
||||
if ((children = node.children) && (n = children.length)) {
|
||||
var n, children;
|
||||
while (--n >= 0) nodes.push(children[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
function d3_layout_hierarchyVisitAfter(node, callback) {
|
||||
var nodes = [ node ], nodes2 = [];
|
||||
while ((node = nodes.pop()) != null) {
|
||||
nodes2.push(node);
|
||||
if ((children = node.children) && (n = children.length)) {
|
||||
var i = -1, n, children;
|
||||
while (++i < n) nodes.push(children[i]);
|
||||
}
|
||||
}
|
||||
while ((node = nodes2.pop()) != null) {
|
||||
callback(node);
|
||||
}
|
||||
}
|
||||
function d3_layout_hierarchyChildren(d) {
|
||||
return d.children;
|
||||
}
|
||||
|
@ -6711,185 +6730,6 @@
|
|||
function d3_layout_histogramRange(values) {
|
||||
return [ d3.min(values), d3.max(values) ];
|
||||
}
|
||||
d3.layout.tree = function() {
|
||||
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false;
|
||||
function tree(d, i) {
|
||||
var nodes = hierarchy.call(this, d, i), root = nodes[0];
|
||||
function firstWalk(node, previousSibling) {
|
||||
var children = node.children, layout = node._tree;
|
||||
if (children && (n = children.length)) {
|
||||
var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1;
|
||||
while (++i < n) {
|
||||
child = children[i];
|
||||
firstWalk(child, previousChild);
|
||||
ancestor = apportion(child, previousChild, ancestor);
|
||||
previousChild = child;
|
||||
}
|
||||
d3_layout_treeShift(node);
|
||||
var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim);
|
||||
if (previousSibling) {
|
||||
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
|
||||
layout.mod = layout.prelim - midpoint;
|
||||
} else {
|
||||
layout.prelim = midpoint;
|
||||
}
|
||||
} else {
|
||||
if (previousSibling) {
|
||||
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
function secondWalk(node, x) {
|
||||
node.x = node._tree.prelim + x;
|
||||
var children = node.children;
|
||||
if (children && (n = children.length)) {
|
||||
var i = -1, n;
|
||||
x += node._tree.mod;
|
||||
while (++i < n) {
|
||||
secondWalk(children[i], x);
|
||||
}
|
||||
}
|
||||
}
|
||||
function apportion(node, previousSibling, ancestor) {
|
||||
if (previousSibling) {
|
||||
var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift;
|
||||
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
|
||||
vom = d3_layout_treeLeft(vom);
|
||||
vop = d3_layout_treeRight(vop);
|
||||
vop._tree.ancestor = node;
|
||||
shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip);
|
||||
if (shift > 0) {
|
||||
d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift);
|
||||
sip += shift;
|
||||
sop += shift;
|
||||
}
|
||||
sim += vim._tree.mod;
|
||||
sip += vip._tree.mod;
|
||||
som += vom._tree.mod;
|
||||
sop += vop._tree.mod;
|
||||
}
|
||||
if (vim && !d3_layout_treeRight(vop)) {
|
||||
vop._tree.thread = vim;
|
||||
vop._tree.mod += sim - sop;
|
||||
}
|
||||
if (vip && !d3_layout_treeLeft(vom)) {
|
||||
vom._tree.thread = vip;
|
||||
vom._tree.mod += sip - som;
|
||||
ancestor = node;
|
||||
}
|
||||
}
|
||||
return ancestor;
|
||||
}
|
||||
d3_layout_treeVisitAfter(root, function(node, previousSibling) {
|
||||
node._tree = {
|
||||
ancestor: node,
|
||||
prelim: 0,
|
||||
mod: 0,
|
||||
change: 0,
|
||||
shift: 0,
|
||||
number: previousSibling ? previousSibling._tree.number + 1 : 0
|
||||
};
|
||||
});
|
||||
firstWalk(root);
|
||||
secondWalk(root, -root._tree.prelim);
|
||||
var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1;
|
||||
d3_layout_treeVisitAfter(root, nodeSize ? function(node) {
|
||||
node.x *= size[0];
|
||||
node.y = node.depth * size[1];
|
||||
delete node._tree;
|
||||
} : function(node) {
|
||||
node.x = (node.x - x0) / (x1 - x0) * size[0];
|
||||
node.y = node.depth / y1 * size[1];
|
||||
delete node._tree;
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
tree.separation = function(x) {
|
||||
if (!arguments.length) return separation;
|
||||
separation = x;
|
||||
return tree;
|
||||
};
|
||||
tree.size = function(x) {
|
||||
if (!arguments.length) return nodeSize ? null : size;
|
||||
nodeSize = (size = x) == null;
|
||||
return tree;
|
||||
};
|
||||
tree.nodeSize = function(x) {
|
||||
if (!arguments.length) return nodeSize ? size : null;
|
||||
nodeSize = (size = x) != null;
|
||||
return tree;
|
||||
};
|
||||
return d3_layout_hierarchyRebind(tree, hierarchy);
|
||||
};
|
||||
function d3_layout_treeSeparation(a, b) {
|
||||
return a.parent == b.parent ? 1 : 2;
|
||||
}
|
||||
function d3_layout_treeLeft(node) {
|
||||
var children = node.children;
|
||||
return children && children.length ? children[0] : node._tree.thread;
|
||||
}
|
||||
function d3_layout_treeRight(node) {
|
||||
var children = node.children, n;
|
||||
return children && (n = children.length) ? children[n - 1] : node._tree.thread;
|
||||
}
|
||||
function d3_layout_treeSearch(node, compare) {
|
||||
var children = node.children;
|
||||
if (children && (n = children.length)) {
|
||||
var child, n, i = -1;
|
||||
while (++i < n) {
|
||||
if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
|
||||
node = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
function d3_layout_treeRightmost(a, b) {
|
||||
return a.x - b.x;
|
||||
}
|
||||
function d3_layout_treeLeftmost(a, b) {
|
||||
return b.x - a.x;
|
||||
}
|
||||
function d3_layout_treeDeepest(a, b) {
|
||||
return a.depth - b.depth;
|
||||
}
|
||||
function d3_layout_treeVisitAfter(node, callback) {
|
||||
function visit(node, previousSibling) {
|
||||
var children = node.children;
|
||||
if (children && (n = children.length)) {
|
||||
var child, previousChild = null, i = -1, n;
|
||||
while (++i < n) {
|
||||
child = children[i];
|
||||
visit(child, previousChild);
|
||||
previousChild = child;
|
||||
}
|
||||
}
|
||||
callback(node, previousSibling);
|
||||
}
|
||||
visit(node, null);
|
||||
}
|
||||
function d3_layout_treeShift(node) {
|
||||
var shift = 0, change = 0, children = node.children, i = children.length, child;
|
||||
while (--i >= 0) {
|
||||
child = children[i]._tree;
|
||||
child.prelim += shift;
|
||||
child.mod += shift;
|
||||
shift += child.shift + (change += child.change);
|
||||
}
|
||||
}
|
||||
function d3_layout_treeMove(ancestor, node, shift) {
|
||||
ancestor = ancestor._tree;
|
||||
node = node._tree;
|
||||
var change = shift / (node.number - ancestor.number);
|
||||
ancestor.change += change;
|
||||
node.change -= change;
|
||||
node.shift += shift;
|
||||
node.prelim += shift;
|
||||
node.mod += shift;
|
||||
}
|
||||
function d3_layout_treeAncestor(vim, node, ancestor) {
|
||||
return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor;
|
||||
}
|
||||
d3.layout.pack = function() {
|
||||
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius;
|
||||
function pack(d, i) {
|
||||
|
@ -6897,17 +6737,17 @@
|
|||
return radius;
|
||||
};
|
||||
root.x = root.y = 0;
|
||||
d3_layout_treeVisitAfter(root, function(d) {
|
||||
d3_layout_hierarchyVisitAfter(root, function(d) {
|
||||
d.r = +r(d.value);
|
||||
});
|
||||
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
|
||||
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
|
||||
if (padding) {
|
||||
var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2;
|
||||
d3_layout_treeVisitAfter(root, function(d) {
|
||||
d3_layout_hierarchyVisitAfter(root, function(d) {
|
||||
d.r += dr;
|
||||
});
|
||||
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
|
||||
d3_layout_treeVisitAfter(root, function(d) {
|
||||
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
|
||||
d3_layout_hierarchyVisitAfter(root, function(d) {
|
||||
d.r -= dr;
|
||||
});
|
||||
}
|
||||
|
@ -7044,11 +6884,158 @@
|
|||
c.y = a.y;
|
||||
}
|
||||
}
|
||||
d3.layout.tree = function() {
|
||||
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null;
|
||||
function tree(d, i) {
|
||||
var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0);
|
||||
d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z;
|
||||
d3_layout_hierarchyVisitBefore(root1, secondWalk);
|
||||
if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else {
|
||||
var left = root0, right = root0, bottom = root0;
|
||||
d3_layout_hierarchyVisitBefore(root0, function(node) {
|
||||
if (node.x < left.x) left = node;
|
||||
if (node.x > right.x) right = node;
|
||||
if (node.depth > bottom.depth) bottom = node;
|
||||
});
|
||||
var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1);
|
||||
d3_layout_hierarchyVisitBefore(root0, function(node) {
|
||||
node.x = (node.x + tx) * kx;
|
||||
node.y = node.depth * ky;
|
||||
});
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
function wrapTree(root0) {
|
||||
var root1 = {
|
||||
A: null,
|
||||
children: [ root0 ]
|
||||
}, queue = [ root1 ], node1;
|
||||
while ((node1 = queue.pop()) != null) {
|
||||
for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) {
|
||||
queue.push((children[i] = child = {
|
||||
_: children[i],
|
||||
parent: node1,
|
||||
children: (child = children[i].children) && child.slice() || [],
|
||||
A: null,
|
||||
a: null,
|
||||
z: 0,
|
||||
m: 0,
|
||||
c: 0,
|
||||
s: 0,
|
||||
t: null,
|
||||
i: i
|
||||
}).a = child);
|
||||
}
|
||||
}
|
||||
return root1.children[0];
|
||||
}
|
||||
function firstWalk(v) {
|
||||
var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null;
|
||||
if (children.length) {
|
||||
d3_layout_treeShift(v);
|
||||
var midpoint = (children[0].z + children[children.length - 1].z) / 2;
|
||||
if (w) {
|
||||
v.z = w.z + separation(v._, w._);
|
||||
v.m = v.z - midpoint;
|
||||
} else {
|
||||
v.z = midpoint;
|
||||
}
|
||||
} else if (w) {
|
||||
v.z = w.z + separation(v._, w._);
|
||||
}
|
||||
v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
|
||||
}
|
||||
function secondWalk(v) {
|
||||
v._.x = v.z + v.parent.m;
|
||||
v.m += v.parent.m;
|
||||
}
|
||||
function apportion(v, w, ancestor) {
|
||||
if (w) {
|
||||
var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift;
|
||||
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
|
||||
vom = d3_layout_treeLeft(vom);
|
||||
vop = d3_layout_treeRight(vop);
|
||||
vop.a = v;
|
||||
shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
|
||||
if (shift > 0) {
|
||||
d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift);
|
||||
sip += shift;
|
||||
sop += shift;
|
||||
}
|
||||
sim += vim.m;
|
||||
sip += vip.m;
|
||||
som += vom.m;
|
||||
sop += vop.m;
|
||||
}
|
||||
if (vim && !d3_layout_treeRight(vop)) {
|
||||
vop.t = vim;
|
||||
vop.m += sim - sop;
|
||||
}
|
||||
if (vip && !d3_layout_treeLeft(vom)) {
|
||||
vom.t = vip;
|
||||
vom.m += sip - som;
|
||||
ancestor = v;
|
||||
}
|
||||
}
|
||||
return ancestor;
|
||||
}
|
||||
function sizeNode(node) {
|
||||
node.x *= size[0];
|
||||
node.y = node.depth * size[1];
|
||||
}
|
||||
tree.separation = function(x) {
|
||||
if (!arguments.length) return separation;
|
||||
separation = x;
|
||||
return tree;
|
||||
};
|
||||
tree.size = function(x) {
|
||||
if (!arguments.length) return nodeSize ? null : size;
|
||||
nodeSize = (size = x) == null ? sizeNode : null;
|
||||
return tree;
|
||||
};
|
||||
tree.nodeSize = function(x) {
|
||||
if (!arguments.length) return nodeSize ? size : null;
|
||||
nodeSize = (size = x) == null ? null : sizeNode;
|
||||
return tree;
|
||||
};
|
||||
return d3_layout_hierarchyRebind(tree, hierarchy);
|
||||
};
|
||||
function d3_layout_treeSeparation(a, b) {
|
||||
return a.parent == b.parent ? 1 : 2;
|
||||
}
|
||||
function d3_layout_treeLeft(v) {
|
||||
var children = v.children;
|
||||
return children.length ? children[0] : v.t;
|
||||
}
|
||||
function d3_layout_treeRight(v) {
|
||||
var children = v.children, n;
|
||||
return (n = children.length) ? children[n - 1] : v.t;
|
||||
}
|
||||
function d3_layout_treeMove(wm, wp, shift) {
|
||||
var change = shift / (wp.i - wm.i);
|
||||
wp.c -= change;
|
||||
wp.s += shift;
|
||||
wm.c += change;
|
||||
wp.z += shift;
|
||||
wp.m += shift;
|
||||
}
|
||||
function d3_layout_treeShift(v) {
|
||||
var shift = 0, change = 0, children = v.children, i = children.length, w;
|
||||
while (--i >= 0) {
|
||||
w = children[i];
|
||||
w.z += shift;
|
||||
w.m += shift;
|
||||
shift += w.s + (change += w.c);
|
||||
}
|
||||
}
|
||||
function d3_layout_treeAncestor(vim, v, ancestor) {
|
||||
return vim.a.parent === v.parent ? vim.a : ancestor;
|
||||
}
|
||||
d3.layout.cluster = function() {
|
||||
var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false;
|
||||
function cluster(d, i) {
|
||||
var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0;
|
||||
d3_layout_treeVisitAfter(root, function(node) {
|
||||
d3_layout_hierarchyVisitAfter(root, function(node) {
|
||||
var children = node.children;
|
||||
if (children && children.length) {
|
||||
node.x = d3_layout_clusterX(children);
|
||||
|
@ -7060,7 +7047,7 @@
|
|||
}
|
||||
});
|
||||
var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2;
|
||||
d3_layout_treeVisitAfter(root, nodeSize ? function(node) {
|
||||
d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) {
|
||||
node.x = (node.x - root.x) * size[0];
|
||||
node.y = (root.y - node.y) * size[1];
|
||||
} : function(node) {
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "d3",
|
||||
"version": "3.4.6",
|
||||
"version": "3.4.7",
|
||||
"description": "A small, free JavaScript library for manipulating documents based on data.",
|
||||
"keywords": [
|
||||
"dom",
|
||||
|
|
|
@ -190,7 +190,7 @@ d3.behavior.zoom = function() {
|
|||
zoomName = ".zoom-" + d3.event.changedTouches[0].identifier,
|
||||
touchmove = "touchmove" + zoomName,
|
||||
touchend = "touchend" + zoomName,
|
||||
target = d3.select(d3.event.target).on(touchmove, moved).on(touchend, ended),
|
||||
targets = [],
|
||||
subject = d3.select(that).on(mousedown, null).on(touchstart, started), // prevent duplicate events
|
||||
dragRestore = d3_event_dragSuppress();
|
||||
|
||||
|
@ -210,7 +210,13 @@ d3.behavior.zoom = function() {
|
|||
|
||||
// Temporarily override touchstart while gesture is active.
|
||||
function started() {
|
||||
// Only track touches started on the target element.
|
||||
|
||||
// Listen for touchmove and touchend on the target of touchstart.
|
||||
var target = d3.event.target;
|
||||
d3.select(target).on(touchmove, moved).on(touchend, ended);
|
||||
targets.push(target);
|
||||
|
||||
// Only track touches started on the same subject element.
|
||||
var changed = d3.event.changedTouches;
|
||||
for (var i = 0, n = changed.length; i < n; ++i) {
|
||||
locations0[changed[i].identifier] = null;
|
||||
|
@ -275,7 +281,7 @@ d3.behavior.zoom = function() {
|
|||
}
|
||||
}
|
||||
// Otherwise, remove touchmove and touchend listeners.
|
||||
target.on(zoomName, null);
|
||||
d3.selectAll(targets).on(zoomName, null);
|
||||
subject.on(mousedown, mousedowned).on(touchstart, touchstarted);
|
||||
dragRestore();
|
||||
zoomended(dispatch);
|
||||
|
|
|
@ -18,7 +18,7 @@ d3.layout.cluster = function() {
|
|||
x = 0;
|
||||
|
||||
// First walk, computing the initial x & y values.
|
||||
d3_layout_treeVisitAfter(root, function(node) {
|
||||
d3_layout_hierarchyVisitAfter(root, function(node) {
|
||||
var children = node.children;
|
||||
if (children && children.length) {
|
||||
node.x = d3_layout_clusterX(children);
|
||||
|
@ -37,7 +37,7 @@ d3.layout.cluster = function() {
|
|||
x1 = right.x + separation(right, left) / 2;
|
||||
|
||||
// Second walk, normalizing x & y to the desired size.
|
||||
d3_layout_treeVisitAfter(root, nodeSize ? function(node) {
|
||||
d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) {
|
||||
node.x = (node.x - root.x) * size[0];
|
||||
node.y = (root.y - node.y) * size[1];
|
||||
} : function(node) {
|
||||
|
|
|
@ -7,54 +7,36 @@ d3.layout.hierarchy = function() {
|
|||
children = d3_layout_hierarchyChildren,
|
||||
value = d3_layout_hierarchyValue;
|
||||
|
||||
// Recursively compute the node depth and value.
|
||||
// Also converts to a standard hierarchy structure.
|
||||
function recurse(node, depth, nodes) {
|
||||
var childs = children.call(hierarchy, node, depth);
|
||||
node.depth = depth;
|
||||
nodes.push(node);
|
||||
if (childs && (n = childs.length)) {
|
||||
var i = -1,
|
||||
n,
|
||||
c = node.children = new Array(n),
|
||||
v = 0,
|
||||
j = depth + 1,
|
||||
d;
|
||||
while (++i < n) {
|
||||
d = c[i] = recurse(childs[i], j, nodes);
|
||||
d.parent = node;
|
||||
v += d.value;
|
||||
}
|
||||
if (sort) c.sort(sort);
|
||||
if (value) node.value = v;
|
||||
} else {
|
||||
delete node.children;
|
||||
if (value) {
|
||||
node.value = +value.call(hierarchy, node, depth) || 0;
|
||||
function hierarchy(root) {
|
||||
var stack = [root],
|
||||
nodes = [],
|
||||
node;
|
||||
|
||||
root.depth = 0;
|
||||
|
||||
while ((node = stack.pop()) != null) {
|
||||
nodes.push(node);
|
||||
if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) {
|
||||
var n, childs, child;
|
||||
while (--n >= 0) {
|
||||
stack.push(child = childs[n]);
|
||||
child.parent = node;
|
||||
child.depth = node.depth + 1;
|
||||
}
|
||||
if (value) node.value = 0;
|
||||
node.children = childs;
|
||||
} else {
|
||||
if (value) node.value = +value.call(hierarchy, node, node.depth) || 0;
|
||||
delete node.children;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Recursively re-evaluates the node value.
|
||||
function revalue(node, depth) {
|
||||
var children = node.children,
|
||||
v = 0;
|
||||
if (children && (n = children.length)) {
|
||||
var i = -1,
|
||||
n,
|
||||
j = depth + 1;
|
||||
while (++i < n) v += revalue(children[i], j);
|
||||
} else if (value) {
|
||||
v = +value.call(hierarchy, node, depth) || 0;
|
||||
}
|
||||
if (value) node.value = v;
|
||||
return v;
|
||||
}
|
||||
d3_layout_hierarchyVisitAfter(root, function(node) {
|
||||
var childs, parent;
|
||||
if (sort && (childs = node.children)) childs.sort(sort);
|
||||
if (value && (parent = node.parent)) parent.value += node.value;
|
||||
});
|
||||
|
||||
function hierarchy(d) {
|
||||
var nodes = [];
|
||||
recurse(d, 0, nodes);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
@ -78,7 +60,11 @@ d3.layout.hierarchy = function() {
|
|||
|
||||
// Re-evaluates the `value` property for the specified hierarchy.
|
||||
hierarchy.revalue = function(root) {
|
||||
revalue(root, 0);
|
||||
if (value) d3_layout_hierarchyVisitAfter(root, function(node) {
|
||||
var parent;
|
||||
node.value = node.children ? 0 : +value.call(hierarchy, node, node.depth) || 0;
|
||||
if (parent = node.parent) parent.value += node.value;
|
||||
});
|
||||
return root;
|
||||
};
|
||||
|
||||
|
@ -96,6 +82,33 @@ function d3_layout_hierarchyRebind(object, hierarchy) {
|
|||
return object;
|
||||
}
|
||||
|
||||
// Pre-order traversal.
|
||||
function d3_layout_hierarchyVisitBefore(node, callback) {
|
||||
var nodes = [node];
|
||||
while ((node = nodes.pop()) != null) {
|
||||
callback(node);
|
||||
if ((children = node.children) && (n = children.length)) {
|
||||
var n, children;
|
||||
while (--n >= 0) nodes.push(children[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Post-order traversal.
|
||||
function d3_layout_hierarchyVisitAfter(node, callback) {
|
||||
var nodes = [node], nodes2 = [];
|
||||
while ((node = nodes.pop()) != null) {
|
||||
nodes2.push(node);
|
||||
if ((children = node.children) && (n = children.length)) {
|
||||
var i = -1, n, children;
|
||||
while (++i < n) nodes.push(children[i]);
|
||||
}
|
||||
}
|
||||
while ((node = nodes2.pop()) != null) {
|
||||
callback(node);
|
||||
}
|
||||
}
|
||||
|
||||
function d3_layout_hierarchyChildren(d) {
|
||||
return d.children;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import "layout";
|
||||
import "hierarchy";
|
||||
import "tree";
|
||||
|
||||
d3.layout.pack = function() {
|
||||
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
|
||||
|
@ -17,15 +16,15 @@ d3.layout.pack = function() {
|
|||
|
||||
// Recursively compute the layout.
|
||||
root.x = root.y = 0;
|
||||
d3_layout_treeVisitAfter(root, function(d) { d.r = +r(d.value); });
|
||||
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
|
||||
d3_layout_hierarchyVisitAfter(root, function(d) { d.r = +r(d.value); });
|
||||
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
|
||||
|
||||
// When padding, recompute the layout using scaled padding.
|
||||
if (padding) {
|
||||
var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2;
|
||||
d3_layout_treeVisitAfter(root, function(d) { d.r += dr; });
|
||||
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
|
||||
d3_layout_treeVisitAfter(root, function(d) { d.r -= dr; });
|
||||
d3_layout_hierarchyVisitAfter(root, function(d) { d.r += dr; });
|
||||
d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings);
|
||||
d3_layout_hierarchyVisitAfter(root, function(d) { d.r -= dr; });
|
||||
}
|
||||
|
||||
// Translate and scale the layout to fit the requested size.
|
||||
|
|
|
@ -6,133 +6,156 @@ d3.layout.tree = function() {
|
|||
var hierarchy = d3.layout.hierarchy().sort(null).value(null),
|
||||
separation = d3_layout_treeSeparation,
|
||||
size = [1, 1], // width, height
|
||||
nodeSize = false;
|
||||
nodeSize = null;
|
||||
|
||||
function tree(d, i) {
|
||||
var nodes = hierarchy.call(this, d, i),
|
||||
root = nodes[0];
|
||||
|
||||
function firstWalk(node, previousSibling) {
|
||||
var children = node.children,
|
||||
layout = node._tree;
|
||||
if (children && (n = children.length)) {
|
||||
var n,
|
||||
firstChild = children[0],
|
||||
previousChild,
|
||||
ancestor = firstChild,
|
||||
child,
|
||||
i = -1;
|
||||
while (++i < n) {
|
||||
child = children[i];
|
||||
firstWalk(child, previousChild);
|
||||
ancestor = apportion(child, previousChild, ancestor);
|
||||
previousChild = child;
|
||||
}
|
||||
d3_layout_treeShift(node);
|
||||
var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim);
|
||||
if (previousSibling) {
|
||||
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
|
||||
layout.mod = layout.prelim - midpoint;
|
||||
} else {
|
||||
layout.prelim = midpoint;
|
||||
}
|
||||
} else {
|
||||
if (previousSibling) {
|
||||
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function secondWalk(node, x) {
|
||||
node.x = node._tree.prelim + x;
|
||||
var children = node.children;
|
||||
if (children && (n = children.length)) {
|
||||
var i = -1,
|
||||
n;
|
||||
x += node._tree.mod;
|
||||
while (++i < n) {
|
||||
secondWalk(children[i], x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function apportion(node, previousSibling, ancestor) {
|
||||
if (previousSibling) {
|
||||
var vip = node,
|
||||
vop = node,
|
||||
vim = previousSibling,
|
||||
vom = node.parent.children[0],
|
||||
sip = vip._tree.mod,
|
||||
sop = vop._tree.mod,
|
||||
sim = vim._tree.mod,
|
||||
som = vom._tree.mod,
|
||||
shift;
|
||||
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
|
||||
vom = d3_layout_treeLeft(vom);
|
||||
vop = d3_layout_treeRight(vop);
|
||||
vop._tree.ancestor = node;
|
||||
shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip);
|
||||
if (shift > 0) {
|
||||
d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift);
|
||||
sip += shift;
|
||||
sop += shift;
|
||||
}
|
||||
sim += vim._tree.mod;
|
||||
sip += vip._tree.mod;
|
||||
som += vom._tree.mod;
|
||||
sop += vop._tree.mod;
|
||||
}
|
||||
if (vim && !d3_layout_treeRight(vop)) {
|
||||
vop._tree.thread = vim;
|
||||
vop._tree.mod += sim - sop;
|
||||
}
|
||||
if (vip && !d3_layout_treeLeft(vom)) {
|
||||
vom._tree.thread = vip;
|
||||
vom._tree.mod += sip - som;
|
||||
ancestor = node;
|
||||
}
|
||||
}
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
// Initialize temporary layout variables.
|
||||
d3_layout_treeVisitAfter(root, function(node, previousSibling) {
|
||||
node._tree = {
|
||||
ancestor: node,
|
||||
prelim: 0,
|
||||
mod: 0,
|
||||
change: 0,
|
||||
shift: 0,
|
||||
number: previousSibling ? previousSibling._tree.number + 1 : 0
|
||||
};
|
||||
});
|
||||
root0 = nodes[0],
|
||||
root1 = wrapTree(root0);
|
||||
|
||||
// Compute the layout using Buchheim et al.'s algorithm.
|
||||
firstWalk(root);
|
||||
secondWalk(root, -root._tree.prelim);
|
||||
d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z;
|
||||
d3_layout_hierarchyVisitBefore(root1, secondWalk);
|
||||
|
||||
// If a fixed node size is specified, scale x and y.
|
||||
if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode);
|
||||
|
||||
// If a fixed tree size is specified, scale x and y based on the extent.
|
||||
// Compute the left-most, right-most, and depth-most nodes for extents.
|
||||
var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost),
|
||||
right = d3_layout_treeSearch(root, d3_layout_treeRightmost),
|
||||
deep = d3_layout_treeSearch(root, d3_layout_treeDeepest),
|
||||
x0 = left.x - separation(left, right) / 2,
|
||||
x1 = right.x + separation(right, left) / 2,
|
||||
y1 = deep.depth || 1;
|
||||
|
||||
// Clear temporary layout variables; transform x and y.
|
||||
d3_layout_treeVisitAfter(root, nodeSize ? function(node) {
|
||||
node.x *= size[0];
|
||||
node.y = node.depth * size[1];
|
||||
delete node._tree;
|
||||
} : function(node) {
|
||||
node.x = (node.x - x0) / (x1 - x0) * size[0];
|
||||
node.y = node.depth / y1 * size[1];
|
||||
delete node._tree;
|
||||
});
|
||||
else {
|
||||
var left = root0,
|
||||
right = root0,
|
||||
bottom = root0;
|
||||
d3_layout_hierarchyVisitBefore(root0, function(node) {
|
||||
if (node.x < left.x) left = node;
|
||||
if (node.x > right.x) right = node;
|
||||
if (node.depth > bottom.depth) bottom = node;
|
||||
});
|
||||
var tx = separation(left, right) / 2 - left.x,
|
||||
kx = size[0] / (right.x + separation(right, left) / 2 + tx),
|
||||
ky = size[1] / (bottom.depth || 1);
|
||||
d3_layout_hierarchyVisitBefore(root0, function(node) {
|
||||
node.x = (node.x + tx) * kx;
|
||||
node.y = node.depth * ky;
|
||||
});
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
function wrapTree(root0) {
|
||||
var root1 = {A: null, children: [root0]},
|
||||
queue = [root1],
|
||||
node1;
|
||||
|
||||
while ((node1 = queue.pop()) != null) {
|
||||
for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) {
|
||||
queue.push((children[i] = child = {
|
||||
_: children[i], // source node
|
||||
parent: node1,
|
||||
children: (child = children[i].children) && child.slice() || [],
|
||||
A: null, // default ancestor
|
||||
a: null, // ancestor
|
||||
z: 0, // prelim
|
||||
m: 0, // mod
|
||||
c: 0, // change
|
||||
s: 0, // shift
|
||||
t: null, // thread
|
||||
i: i // number
|
||||
}).a = child);
|
||||
}
|
||||
}
|
||||
|
||||
return root1.children[0];
|
||||
}
|
||||
|
||||
// FIRST WALK
|
||||
// Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
|
||||
// applied recursively to the children of v, as well as the function
|
||||
// APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
|
||||
// node v is placed to the midpoint of its outermost children.
|
||||
function firstWalk(v) {
|
||||
var children = v.children,
|
||||
siblings = v.parent.children,
|
||||
w = v.i ? siblings[v.i - 1] : null;
|
||||
if (children.length) {
|
||||
d3_layout_treeShift(v);
|
||||
var midpoint = (children[0].z + children[children.length - 1].z) / 2;
|
||||
if (w) {
|
||||
v.z = w.z + separation(v._, w._);
|
||||
v.m = v.z - midpoint;
|
||||
} else {
|
||||
v.z = midpoint;
|
||||
}
|
||||
} else if (w) {
|
||||
v.z = w.z + separation(v._, w._);
|
||||
}
|
||||
v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
|
||||
}
|
||||
|
||||
// SECOND WALK
|
||||
// Computes all real x-coordinates by summing up the modifiers recursively.
|
||||
function secondWalk(v) {
|
||||
v._.x = v.z + v.parent.m;
|
||||
v.m += v.parent.m;
|
||||
}
|
||||
|
||||
// APPORTION
|
||||
// The core of the algorithm. Here, a new subtree is combined with the
|
||||
// previous subtrees. Threads are used to traverse the inside and outside
|
||||
// contours of the left and right subtree up to the highest common level. The
|
||||
// vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
|
||||
// superscript o means outside and i means inside, the subscript - means left
|
||||
// subtree and + means right subtree. For summing up the modifiers along the
|
||||
// contour, we use respective variables si+, si-, so-, and so+. Whenever two
|
||||
// nodes of the inside contours conflict, we compute the left one of the
|
||||
// greatest uncommon ancestors using the function ANCESTOR and call MOVE
|
||||
// SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
|
||||
// Finally, we add a new thread (if necessary).
|
||||
function apportion(v, w, ancestor) {
|
||||
if (w) {
|
||||
var vip = v,
|
||||
vop = v,
|
||||
vim = w,
|
||||
vom = vip.parent.children[0],
|
||||
sip = vip.m,
|
||||
sop = vop.m,
|
||||
sim = vim.m,
|
||||
som = vom.m,
|
||||
shift;
|
||||
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
|
||||
vom = d3_layout_treeLeft(vom);
|
||||
vop = d3_layout_treeRight(vop);
|
||||
vop.a = v;
|
||||
shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
|
||||
if (shift > 0) {
|
||||
d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift);
|
||||
sip += shift;
|
||||
sop += shift;
|
||||
}
|
||||
sim += vim.m;
|
||||
sip += vip.m;
|
||||
som += vom.m;
|
||||
sop += vop.m;
|
||||
}
|
||||
if (vim && !d3_layout_treeRight(vop)) {
|
||||
vop.t = vim;
|
||||
vop.m += sim - sop;
|
||||
}
|
||||
if (vip && !d3_layout_treeLeft(vom)) {
|
||||
vom.t = vip;
|
||||
vom.m += sip - som;
|
||||
ancestor = v;
|
||||
}
|
||||
}
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
function sizeNode(node) {
|
||||
node.x *= size[0];
|
||||
node.y = node.depth * size[1];
|
||||
}
|
||||
|
||||
tree.separation = function(x) {
|
||||
if (!arguments.length) return separation;
|
||||
separation = x;
|
||||
|
@ -141,13 +164,13 @@ d3.layout.tree = function() {
|
|||
|
||||
tree.size = function(x) {
|
||||
if (!arguments.length) return nodeSize ? null : size;
|
||||
nodeSize = (size = x) == null;
|
||||
nodeSize = (size = x) == null ? sizeNode : null;
|
||||
return tree;
|
||||
};
|
||||
|
||||
tree.nodeSize = function(x) {
|
||||
if (!arguments.length) return nodeSize ? size : null;
|
||||
nodeSize = (size = x) != null;
|
||||
nodeSize = (size = x) == null ? null : sizeNode;
|
||||
return tree;
|
||||
};
|
||||
|
||||
|
@ -162,90 +185,56 @@ function d3_layout_treeSeparation(a, b) {
|
|||
// return (a.parent == b.parent ? 1 : 2) / a.depth;
|
||||
// }
|
||||
|
||||
function d3_layout_treeLeft(node) {
|
||||
var children = node.children;
|
||||
return children && children.length ? children[0] : node._tree.thread;
|
||||
// NEXT LEFT
|
||||
// This function is used to traverse the left contour of a subtree (or
|
||||
// subforest). It returns the successor of v on this contour. This successor is
|
||||
// either given by the leftmost child of v or by the thread of v. The function
|
||||
// returns null if and only if v is on the highest level of its subtree.
|
||||
function d3_layout_treeLeft(v) {
|
||||
var children = v.children;
|
||||
return children.length ? children[0] : v.t;
|
||||
}
|
||||
|
||||
function d3_layout_treeRight(node) {
|
||||
var children = node.children,
|
||||
n;
|
||||
return children && (n = children.length) ? children[n - 1] : node._tree.thread;
|
||||
// NEXT RIGHT
|
||||
// This function works analogously to NEXT LEFT.
|
||||
function d3_layout_treeRight(v) {
|
||||
var children = v.children, n;
|
||||
return (n = children.length) ? children[n - 1] : v.t;
|
||||
}
|
||||
|
||||
function d3_layout_treeSearch(node, compare) {
|
||||
var children = node.children;
|
||||
if (children && (n = children.length)) {
|
||||
var child,
|
||||
n,
|
||||
i = -1;
|
||||
while (++i < n) {
|
||||
if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
|
||||
node = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
// MOVE SUBTREE
|
||||
// Shifts the current subtree rooted at w+. This is done by increasing
|
||||
// prelim(w+) and mod(w+) by shift.
|
||||
function d3_layout_treeMove(wm, wp, shift) {
|
||||
var change = shift / (wp.i - wm.i);
|
||||
wp.c -= change;
|
||||
wp.s += shift;
|
||||
wm.c += change;
|
||||
wp.z += shift;
|
||||
wp.m += shift;
|
||||
}
|
||||
|
||||
function d3_layout_treeRightmost(a, b) {
|
||||
return a.x - b.x;
|
||||
}
|
||||
|
||||
function d3_layout_treeLeftmost(a, b) {
|
||||
return b.x - a.x;
|
||||
}
|
||||
|
||||
function d3_layout_treeDeepest(a, b) {
|
||||
return a.depth - b.depth;
|
||||
}
|
||||
|
||||
function d3_layout_treeVisitAfter(node, callback) {
|
||||
function visit(node, previousSibling) {
|
||||
var children = node.children;
|
||||
if (children && (n = children.length)) {
|
||||
var child,
|
||||
previousChild = null,
|
||||
i = -1,
|
||||
n;
|
||||
while (++i < n) {
|
||||
child = children[i];
|
||||
visit(child, previousChild);
|
||||
previousChild = child;
|
||||
}
|
||||
}
|
||||
callback(node, previousSibling);
|
||||
}
|
||||
visit(node, null);
|
||||
}
|
||||
|
||||
function d3_layout_treeShift(node) {
|
||||
// EXECUTE SHIFTS
|
||||
// All other shifts, applied to the smaller subtrees between w- and w+, are
|
||||
// performed by this function. To prepare the shifts, we have to adjust
|
||||
// change(w+), shift(w+), and change(w-).
|
||||
function d3_layout_treeShift(v) {
|
||||
var shift = 0,
|
||||
change = 0,
|
||||
children = node.children,
|
||||
children = v.children,
|
||||
i = children.length,
|
||||
child;
|
||||
w;
|
||||
while (--i >= 0) {
|
||||
child = children[i]._tree;
|
||||
child.prelim += shift;
|
||||
child.mod += shift;
|
||||
shift += child.shift + (change += child.change);
|
||||
w = children[i];
|
||||
w.z += shift;
|
||||
w.m += shift;
|
||||
shift += w.s + (change += w.c);
|
||||
}
|
||||
}
|
||||
|
||||
function d3_layout_treeMove(ancestor, node, shift) {
|
||||
ancestor = ancestor._tree;
|
||||
node = node._tree;
|
||||
var change = shift / (node.number - ancestor.number);
|
||||
ancestor.change += change;
|
||||
node.change -= change;
|
||||
node.shift += shift;
|
||||
node.prelim += shift;
|
||||
node.mod += shift;
|
||||
}
|
||||
|
||||
function d3_layout_treeAncestor(vim, node, ancestor) {
|
||||
return vim._tree.ancestor.parent == node.parent
|
||||
? vim._tree.ancestor
|
||||
: ancestor;
|
||||
// ANCESTOR
|
||||
// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
|
||||
// returns the specified (default) ancestor.
|
||||
function d3_layout_treeAncestor(vim, v, ancestor) {
|
||||
return vim.a.parent === v.parent ? vim.a : ancestor;
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
!function(){
|
||||
var d3 = {version: "3.4.6"}; // semver
|
||||
var d3 = {version: "3.4.7"}; // semver
|
||||
|
|
|
@ -7,6 +7,22 @@ var suite = vows.describe("d3.layout.tree");
|
|||
suite.addBatch({
|
||||
"tree": {
|
||||
topic: load("layout/tree").expression("d3.layout.tree"),
|
||||
"computes a simple tree layout": function(tree) {
|
||||
var t = tree();
|
||||
assert.deepEqual(t.nodes({
|
||||
name: "1",
|
||||
children: [
|
||||
{name: "1-1"},
|
||||
{name: "1-2"},
|
||||
{name: "1-3"}
|
||||
]
|
||||
}).map(layout), [
|
||||
{name: "1", depth: 0, x: 0.5, y: 0},
|
||||
{name: "1-1", depth: 1, x: 0.16666666666666666, y: 1},
|
||||
{name: "1-2", depth: 1, x: 0.5, y: 1},
|
||||
{name: "1-3", depth: 1, x: 0.8333333333333333, y: 1}
|
||||
]);
|
||||
},
|
||||
"can handle an empty children array": function(tree) {
|
||||
var t = tree();
|
||||
assert.deepEqual(t.nodes({children: []}).map(layout), [
|
||||
|
@ -27,7 +43,7 @@ suite.addBatch({
|
|||
},
|
||||
"can handle a single node": function(tree) {
|
||||
var t = tree();
|
||||
assert.deepEqual(t.nodes({value: 0}).map(layout), [
|
||||
assert.deepEqual(t.nodes({}).map(layout), [
|
||||
{depth: 0, x: 0.5, y: 0}
|
||||
]);
|
||||
}
|
||||
|
@ -35,11 +51,9 @@ suite.addBatch({
|
|||
});
|
||||
|
||||
function layout(node) {
|
||||
return {
|
||||
depth: node.depth,
|
||||
x: node.x,
|
||||
y: node.y
|
||||
};
|
||||
delete node.children;
|
||||
delete node.parent;
|
||||
return node;
|
||||
}
|
||||
|
||||
suite.export(module);
|
||||
|
|
Загрузка…
Ссылка в новой задаче