Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/pack-padding' into 2.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Aug 9, 2012
2 parents 7ac1ae7 + 47adcf5 commit 79a3c0d
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 59 deletions.
55 changes: 33 additions & 22 deletions d3.v2.js
Expand Up @@ -4410,21 +4410,40 @@
}
var d3_layout_hierarchyInline = false;
d3.layout.pack = function() {
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), size = [ 1, 1 ];
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ];
function pack(d, i) {
var nodes = hierarchy.call(this, d, i), root = nodes[0];
root.x = 0;
root.y = 0;
d3_layout_packTree(root);
var w = size[0], h = size[1], k = 1 / Math.max(2 * root.r / w, 2 * root.r / h);
d3_layout_packTransform(root, w / 2, h / 2, k);
d3_layout_treeVisitAfter(root, function(d) {
d.r = Math.sqrt(d.value);
});
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
var w = size[0], h = size[1], k = Math.max(2 * root.r / w, 2 * root.r / h);
if (padding > 0) {
var dr = padding * k / 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;
});
k = Math.max(2 * root.r / w, 2 * root.r / h);
}
d3_layout_packTransform(root, w / 2, h / 2, 1 / k);
return nodes;
}
pack.size = function(x) {
if (!arguments.length) return size;
size = x;
return pack;
};
pack.padding = function(_) {
if (!arguments.length) return padding;
padding = +_;
return pack;
};
return d3_layout_hierarchyRebind(pack, hierarchy);
};
function d3_layout_packSort(a, b) {
Expand All @@ -4445,8 +4464,9 @@
var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r;
return dr * dr - dx * dx - dy * dy > .001;
}
function d3_layout_packCircle(nodes) {
var xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, n = nodes.length, a, b, c, j, k;
function d3_layout_packSiblings(node) {
if (!(nodes = node.children) || !(n = nodes.length)) return;
var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n;
function bound(node) {
xMin = Math.min(node.x - node.r, xMin);
xMax = Math.max(node.x + node.r, xMax);
Expand All @@ -4471,7 +4491,7 @@
a._pack_prev = c;
d3_layout_packInsert(c, b);
b = a._pack_next;
for (var i = 3; i < n; i++) {
for (i = 3; i < n; i++) {
d3_layout_packPlace(a, b, c = nodes[i]);
var isect = 0, s1 = 1, s2 = 1;
for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
Expand Down Expand Up @@ -4499,14 +4519,14 @@
}
}
var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0;
for (var i = 0; i < n; i++) {
var node = nodes[i];
node.x -= cx;
node.y -= cy;
cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y));
for (i = 0; i < n; i++) {
c = nodes[i];
c.x -= cx;
c.y -= cy;
cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
}
node.r = cr;
nodes.forEach(d3_layout_packUnlink);
return cr;
}
function d3_layout_packLink(node) {
node._pack_next = node._pack_prev = node;
Expand All @@ -4515,15 +4535,6 @@
delete node._pack_next;
delete node._pack_prev;
}
function d3_layout_packTree(node) {
var children = node.children;
if (children && children.length) {
children.forEach(d3_layout_packTree);
node.r = d3_layout_packCircle(children);
} else {
node.r = Math.sqrt(node.value);
}
}
function d3_layout_packTransform(node, x, y, k) {
var children = node.children;
node.x = x += k * node.x;
Expand Down
8 changes: 4 additions & 4 deletions d3.v2.min.js

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions examples/bubble/bubble.css
@@ -1,8 +1,3 @@
circle {
stroke: #fff;
stroke-width: 1.5px;
}

text {
font: 10px sans-serif;
}
3 changes: 2 additions & 1 deletion examples/bubble/bubble.js
Expand Up @@ -4,7 +4,8 @@ var r = 960,

var bubble = d3.layout.pack()
.sort(null)
.size([r, r]);
.size([r, r])
.padding(1.5);

var vis = d3.select("#chart").append("svg")
.attr("width", r)
Expand Down
64 changes: 37 additions & 27 deletions src/layout/pack.js
@@ -1,5 +1,6 @@
d3.layout.pack = function() {
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
padding = 0,
size = [1, 1];

function pack(d, i) {
Expand All @@ -9,13 +10,25 @@ d3.layout.pack = function() {
// Recursively compute the layout.
root.x = 0;
root.y = 0;
d3_layout_packTree(root);
d3_layout_treeVisitAfter(root, function(d) { d.r = Math.sqrt(d.value); });
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);

// Scale the layout to fit the requested size.
// Compute the scale factor the initial layout.
var w = size[0],
h = size[1],
k = 1 / Math.max(2 * root.r / w, 2 * root.r / h);
d3_layout_packTransform(root, w / 2, h / 2, k);
k = Math.max(2 * root.r / w, 2 * root.r / h);

// When padding, recompute the layout using scaled padding.
if (padding > 0) {
var dr = padding * k / 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; });
k = Math.max(2 * root.r / w, 2 * root.r / h);
}

// Scale the layout to fit the requested size.
d3_layout_packTransform(root, w / 2, h / 2, 1 / k);

return nodes;
}
Expand All @@ -26,6 +39,12 @@ d3.layout.pack = function() {
return pack;
};

pack.padding = function(_) {
if (!arguments.length) return padding;
padding = +_;
return pack;
};

return d3_layout_hierarchyRebind(pack, hierarchy);
};

Expand Down Expand Up @@ -53,13 +72,15 @@ function d3_layout_packIntersects(a, b) {
return dr * dr - dx * dx - dy * dy > .001; // within epsilon
}

function d3_layout_packCircle(nodes) {
var xMin = Infinity,
function d3_layout_packSiblings(node) {
if (!(nodes = node.children) || !(n = nodes.length)) return;

var nodes,
xMin = Infinity,
xMax = -Infinity,
yMin = Infinity,
yMax = -Infinity,
n = nodes.length,
a, b, c, j, k;
a, b, c, i, j, k, n;

function bound(node) {
xMin = Math.min(node.x - node.r, xMin);
Expand Down Expand Up @@ -95,7 +116,7 @@ function d3_layout_packCircle(nodes) {
b = a._pack_next;

// Now iterate through the rest.
for (var i = 3; i < n; i++) {
for (i = 3; i < n; i++) {
d3_layout_packPlace(a, b, c = nodes[i]);

// Search for the closest intersection.
Expand Down Expand Up @@ -128,21 +149,20 @@ function d3_layout_packCircle(nodes) {
}
}

// Re-center the circles and return the encompassing radius.
// Re-center the circles and compute the encompassing radius.
var cx = (xMin + xMax) / 2,
cy = (yMin + yMax) / 2,
cr = 0;
for (var i = 0; i < n; i++) {
var node = nodes[i];
node.x -= cx;
node.y -= cy;
cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y));
for (i = 0; i < n; i++) {
c = nodes[i];
c.x -= cx;
c.y -= cy;
cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
}
node.r = cr;

// Remove node links.
nodes.forEach(d3_layout_packUnlink);

return cr;
}

function d3_layout_packLink(node) {
Expand All @@ -154,16 +174,6 @@ function d3_layout_packUnlink(node) {
delete node._pack_prev;
}

function d3_layout_packTree(node) {
var children = node.children;
if (children && children.length) {
children.forEach(d3_layout_packTree);
node.r = d3_layout_packCircle(children);
} else {
node.r = Math.sqrt(node.value);
}
}

function d3_layout_packTransform(node, x, y, k) {
var children = node.children;
node.x = (x += k * node.x);
Expand Down

0 comments on commit 79a3c0d

Please sign in to comment.