Skip to content

Commit 79a3c0d

Browse files
committed
Merge remote-tracking branch 'origin/pack-padding' into 2.10.0
2 parents 7ac1ae7 + 47adcf5 commit 79a3c0d

5 files changed

Lines changed: 76 additions & 59 deletions

File tree

d3.v2.js

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4410,21 +4410,40 @@
44104410
}
44114411
var d3_layout_hierarchyInline = false;
44124412
d3.layout.pack = function() {
4413-
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), size = [ 1, 1 ];
4413+
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ];
44144414
function pack(d, i) {
44154415
var nodes = hierarchy.call(this, d, i), root = nodes[0];
44164416
root.x = 0;
44174417
root.y = 0;
4418-
d3_layout_packTree(root);
4419-
var w = size[0], h = size[1], k = 1 / Math.max(2 * root.r / w, 2 * root.r / h);
4420-
d3_layout_packTransform(root, w / 2, h / 2, k);
4418+
d3_layout_treeVisitAfter(root, function(d) {
4419+
d.r = Math.sqrt(d.value);
4420+
});
4421+
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
4422+
var w = size[0], h = size[1], k = Math.max(2 * root.r / w, 2 * root.r / h);
4423+
if (padding > 0) {
4424+
var dr = padding * k / 2;
4425+
d3_layout_treeVisitAfter(root, function(d) {
4426+
d.r += dr;
4427+
});
4428+
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
4429+
d3_layout_treeVisitAfter(root, function(d) {
4430+
d.r -= dr;
4431+
});
4432+
k = Math.max(2 * root.r / w, 2 * root.r / h);
4433+
}
4434+
d3_layout_packTransform(root, w / 2, h / 2, 1 / k);
44214435
return nodes;
44224436
}
44234437
pack.size = function(x) {
44244438
if (!arguments.length) return size;
44254439
size = x;
44264440
return pack;
44274441
};
4442+
pack.padding = function(_) {
4443+
if (!arguments.length) return padding;
4444+
padding = +_;
4445+
return pack;
4446+
};
44284447
return d3_layout_hierarchyRebind(pack, hierarchy);
44294448
};
44304449
function d3_layout_packSort(a, b) {
@@ -4445,8 +4464,9 @@
44454464
var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r;
44464465
return dr * dr - dx * dx - dy * dy > .001;
44474466
}
4448-
function d3_layout_packCircle(nodes) {
4449-
var xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, n = nodes.length, a, b, c, j, k;
4467+
function d3_layout_packSiblings(node) {
4468+
if (!(nodes = node.children) || !(n = nodes.length)) return;
4469+
var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n;
44504470
function bound(node) {
44514471
xMin = Math.min(node.x - node.r, xMin);
44524472
xMax = Math.max(node.x + node.r, xMax);
@@ -4471,7 +4491,7 @@
44714491
a._pack_prev = c;
44724492
d3_layout_packInsert(c, b);
44734493
b = a._pack_next;
4474-
for (var i = 3; i < n; i++) {
4494+
for (i = 3; i < n; i++) {
44754495
d3_layout_packPlace(a, b, c = nodes[i]);
44764496
var isect = 0, s1 = 1, s2 = 1;
44774497
for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
@@ -4499,14 +4519,14 @@
44994519
}
45004520
}
45014521
var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0;
4502-
for (var i = 0; i < n; i++) {
4503-
var node = nodes[i];
4504-
node.x -= cx;
4505-
node.y -= cy;
4506-
cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y));
4522+
for (i = 0; i < n; i++) {
4523+
c = nodes[i];
4524+
c.x -= cx;
4525+
c.y -= cy;
4526+
cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
45074527
}
4528+
node.r = cr;
45084529
nodes.forEach(d3_layout_packUnlink);
4509-
return cr;
45104530
}
45114531
function d3_layout_packLink(node) {
45124532
node._pack_next = node._pack_prev = node;
@@ -4515,15 +4535,6 @@
45154535
delete node._pack_next;
45164536
delete node._pack_prev;
45174537
}
4518-
function d3_layout_packTree(node) {
4519-
var children = node.children;
4520-
if (children && children.length) {
4521-
children.forEach(d3_layout_packTree);
4522-
node.r = d3_layout_packCircle(children);
4523-
} else {
4524-
node.r = Math.sqrt(node.value);
4525-
}
4526-
}
45274538
function d3_layout_packTransform(node, x, y, k) {
45284539
var children = node.children;
45294540
node.x = x += k * node.x;

d3.v2.min.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/bubble/bubble.css

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
circle {
2-
stroke: #fff;
3-
stroke-width: 1.5px;
4-
}
5-
61
text {
72
font: 10px sans-serif;
83
}

examples/bubble/bubble.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ var r = 960,
44

55
var bubble = d3.layout.pack()
66
.sort(null)
7-
.size([r, r]);
7+
.size([r, r])
8+
.padding(1.5);
89

910
var vis = d3.select("#chart").append("svg")
1011
.attr("width", r)

src/layout/pack.js

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
d3.layout.pack = function() {
22
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
3+
padding = 0,
34
size = [1, 1];
45

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

14-
// Scale the layout to fit the requested size.
16+
// Compute the scale factor the initial layout.
1517
var w = size[0],
1618
h = size[1],
17-
k = 1 / Math.max(2 * root.r / w, 2 * root.r / h);
18-
d3_layout_packTransform(root, w / 2, h / 2, k);
19+
k = Math.max(2 * root.r / w, 2 * root.r / h);
20+
21+
// When padding, recompute the layout using scaled padding.
22+
if (padding > 0) {
23+
var dr = padding * k / 2;
24+
d3_layout_treeVisitAfter(root, function(d) { d.r += dr; });
25+
d3_layout_treeVisitAfter(root, d3_layout_packSiblings);
26+
d3_layout_treeVisitAfter(root, function(d) { d.r -= dr; });
27+
k = Math.max(2 * root.r / w, 2 * root.r / h);
28+
}
29+
30+
// Scale the layout to fit the requested size.
31+
d3_layout_packTransform(root, w / 2, h / 2, 1 / k);
1932

2033
return nodes;
2134
}
@@ -26,6 +39,12 @@ d3.layout.pack = function() {
2639
return pack;
2740
};
2841

42+
pack.padding = function(_) {
43+
if (!arguments.length) return padding;
44+
padding = +_;
45+
return pack;
46+
};
47+
2948
return d3_layout_hierarchyRebind(pack, hierarchy);
3049
};
3150

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

56-
function d3_layout_packCircle(nodes) {
57-
var xMin = Infinity,
75+
function d3_layout_packSiblings(node) {
76+
if (!(nodes = node.children) || !(n = nodes.length)) return;
77+
78+
var nodes,
79+
xMin = Infinity,
5880
xMax = -Infinity,
5981
yMin = Infinity,
6082
yMax = -Infinity,
61-
n = nodes.length,
62-
a, b, c, j, k;
83+
a, b, c, i, j, k, n;
6384

6485
function bound(node) {
6586
xMin = Math.min(node.x - node.r, xMin);
@@ -95,7 +116,7 @@ function d3_layout_packCircle(nodes) {
95116
b = a._pack_next;
96117

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

101122
// Search for the closest intersection.
@@ -128,21 +149,20 @@ function d3_layout_packCircle(nodes) {
128149
}
129150
}
130151

131-
// Re-center the circles and return the encompassing radius.
152+
// Re-center the circles and compute the encompassing radius.
132153
var cx = (xMin + xMax) / 2,
133154
cy = (yMin + yMax) / 2,
134155
cr = 0;
135-
for (var i = 0; i < n; i++) {
136-
var node = nodes[i];
137-
node.x -= cx;
138-
node.y -= cy;
139-
cr = Math.max(cr, node.r + Math.sqrt(node.x * node.x + node.y * node.y));
156+
for (i = 0; i < n; i++) {
157+
c = nodes[i];
158+
c.x -= cx;
159+
c.y -= cy;
160+
cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y));
140161
}
162+
node.r = cr;
141163

142164
// Remove node links.
143165
nodes.forEach(d3_layout_packUnlink);
144-
145-
return cr;
146166
}
147167

148168
function d3_layout_packLink(node) {
@@ -154,16 +174,6 @@ function d3_layout_packUnlink(node) {
154174
delete node._pack_prev;
155175
}
156176

157-
function d3_layout_packTree(node) {
158-
var children = node.children;
159-
if (children && children.length) {
160-
children.forEach(d3_layout_packTree);
161-
node.r = d3_layout_packCircle(children);
162-
} else {
163-
node.r = Math.sqrt(node.value);
164-
}
165-
}
166-
167177
function d3_layout_packTransform(node, x, y, k) {
168178
var children = node.children;
169179
node.x = (x += k * node.x);

0 commit comments

Comments
 (0)