|
|
function defaultSeparation(a, b) { return a.parent === b.parent ? 1 : 2;}
function meanX(children) { return children.reduce(meanXReduce, 0) / children.length;}
function meanXReduce(x, c) { return x + c.x;}
function maxY(children) { return 1 + children.reduce(maxYReduce, 0);}
function maxYReduce(y, c) { return Math.max(y, c.y);}
function leafLeft(node) { var children; while (children = node.children) node = children[0]; return node;}
function leafRight(node) { var children; while (children = node.children) node = children[children.length - 1]; return node;}
export default function() { var separation = defaultSeparation, dx = 1, dy = 1, nodeSize = false;
function cluster(root) { var previousNode, x = 0;
// First walk, computing the initial x & y values.
root.eachAfter(function(node) { var children = node.children; if (children) { node.x = meanX(children); node.y = maxY(children); } else { node.x = previousNode ? x += separation(node, previousNode) : 0; node.y = 0; previousNode = node; } });
var left = leafLeft(root), right = leafRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2;
// Second walk, normalizing x & y to the desired size.
return root.eachAfter(nodeSize ? function(node) { node.x = (node.x - root.x) * dx; node.y = (root.y - node.y) * dy; } : function(node) { node.x = (node.x - x0) / (x1 - x0) * dx; node.y = (1 - (root.y ? node.y / root.y : 1)) * dy; }); }
cluster.separation = function(x) { return arguments.length ? (separation = x, cluster) : separation; };
cluster.size = function(x) { return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]); };
cluster.nodeSize = function(x) { return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null); };
return cluster;}
|