Skip to content

Commit

Permalink
Fix a bug with empty children arrays.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Sep 30, 2011
1 parent cd3d236 commit 6804a60
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 111 deletions.
2 changes: 1 addition & 1 deletion d3.js
Expand Up @@ -10,7 +10,7 @@ try {
d3_style_setProperty.call(this, name, value + "", priority);
};
}
d3 = {version: "2.3.1"}; // semver
d3 = {version: "2.3.2"}; // semver
var d3_array = d3_arraySlice; // conversion for NodeLists

function d3_arrayCopy(pseudoarray) {
Expand Down
113 changes: 60 additions & 53 deletions d3.layout.js
Expand Up @@ -560,9 +560,9 @@ d3.layout.partition = function() {
node.y = node.depth * dy;
node.dx = dx;
node.dy = dy;
if (children) {
if (children && (n = children.length)) {
var i = -1,
n = children.length,
n,
c,
d;
dx = node.value ? dx / node.value : 0;
Expand All @@ -576,9 +576,9 @@ d3.layout.partition = function() {
function depth(node) {
var children = node.children,
d = 0;
if (children) {
if (children && (n = children.length)) {
var i = -1,
n = children.length;
n;
while (++i < n) d = Math.max(d, depth(children[i]));
}
return 1 + d;
Expand Down Expand Up @@ -1477,9 +1477,9 @@ d3.layout.tree = function() {
function secondWalk(node, x) {
node.x = node._tree.prelim + x;
var children = node.children;
if (children) {
if (children && (n = children.length)) {
var i = -1,
n = children.length;
n;
x += node._tree.mod;
while (++i < n) {
secondWalk(children[i], x);
Expand Down Expand Up @@ -1584,18 +1584,21 @@ function d3_layout_treeSeparation(a, b) {
// }

function d3_layout_treeLeft(node) {
return node.children ? node.children[0] : node._tree.thread;
var children = node.children;
return children && children.length ? children[0] : node._tree.thread;
}

function d3_layout_treeRight(node) {
return node.children ? node.children[node.children.length - 1] : node._tree.thread;
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) {
if (children && (n = children.length)) {
var child,
n = children.length,
n,
i = -1;
while (++i < n) {
if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
Expand All @@ -1621,11 +1624,11 @@ function d3_layout_treeDeepest(a, b) {
function d3_layout_treeVisitAfter(node, callback) {
function visit(node, previousSibling) {
var children = node.children;
if (children) {
if (children && (n = children.length)) {
var child,
previousChild = null,
i = -1,
n = children.length;
n;
while (++i < n) {
child = children[i];
visit(child, previousChild);
Expand Down Expand Up @@ -1693,57 +1696,61 @@ d3.layout.treemap = function() {

// Recursively arranges the specified node's children into squarified rows.
function squarify(node) {
if (!node.children) return;
var rect = pad(node),
row = [],
children = node.children.slice(), // copy-on-write
child,
best = Infinity, // the best row score so far
score, // the current row score
u = Math.min(rect.dx, rect.dy), // initial orientation
n;
scale(children, rect.dx * rect.dy / node.value);
row.area = 0;
while ((n = children.length) > 0) {
row.push(child = children[n - 1]);
row.area += child.area;
if ((score = worst(row, u)) <= best) { // continue with this orientation
children.pop();
best = score;
} else { // abort, and try a different orientation
row.area -= row.pop().area;
position(row, u, rect, false);
u = Math.min(rect.dx, rect.dy);
var children = node.children;
if (children && children.length) {
var rect = pad(node),
row = [],
remaining = children.slice(), // copy-on-write
child,
best = Infinity, // the best row score so far
score, // the current row score
u = Math.min(rect.dx, rect.dy), // initial orientation
n;
scale(remaining, rect.dx * rect.dy / node.value);
row.area = 0;
while ((n = remaining.length) > 0) {
row.push(child = remaining[n - 1]);
row.area += child.area;
if ((score = worst(row, u)) <= best) { // continue with this orientation
remaining.pop();
best = score;
} else { // abort, and try a different orientation
row.area -= row.pop().area;
position(row, u, rect, false);
u = Math.min(rect.dx, rect.dy);
row.length = row.area = 0;
best = Infinity;
}
}
if (row.length) {
position(row, u, rect, true);
row.length = row.area = 0;
best = Infinity;
}
children.forEach(squarify);
}
if (row.length) {
position(row, u, rect, true);
row.length = row.area = 0;
}
node.children.forEach(squarify);
}

// Recursively resizes the specified node's children into existing rows.
// Preserves the existing layout!
function stickify(node) {
if (!node.children) return;
var rect = pad(node),
children = node.children.slice(), // copy-on-write
child,
row = [];
scale(children, rect.dx * rect.dy / node.value);
row.area = 0;
while (child = children.pop()) {
row.push(child);
row.area += child.area;
if (child.z != null) {
position(row, child.z ? rect.dx : rect.dy, rect, !children.length);
row.length = row.area = 0;
var children = node.children;
if (children && children.length) {
var rect = pad(node),
remaining = children.slice(), // copy-on-write
child,
row = [];
scale(remaining, rect.dx * rect.dy / node.value);
row.area = 0;
while (child = remaining.pop()) {
row.push(child);
row.area += child.area;
if (child.z != null) {
position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
row.length = row.area = 0;
}
}
children.forEach(stickify);
}
node.children.forEach(stickify);
}

// Computes the score for the specified row, as the worst aspect ratio.
Expand Down
2 changes: 1 addition & 1 deletion d3.layout.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion d3.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "d3",
"version": "2.3.1",
"version": "2.3.2",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
Expand Down
2 changes: 1 addition & 1 deletion src/core/core.js
@@ -1 +1 @@
d3 = {version: "2.3.1"}; // semver
d3 = {version: "2.3.2"}; // semver
8 changes: 4 additions & 4 deletions src/layout/partition.js
Expand Up @@ -8,9 +8,9 @@ d3.layout.partition = function() {
node.y = node.depth * dy;
node.dx = dx;
node.dy = dy;
if (children) {
if (children && (n = children.length)) {
var i = -1,
n = children.length,
n,
c,
d;
dx = node.value ? dx / node.value : 0;
Expand All @@ -24,9 +24,9 @@ d3.layout.partition = function() {
function depth(node) {
var children = node.children,
d = 0;
if (children) {
if (children && (n = children.length)) {
var i = -1,
n = children.length;
n;
while (++i < n) d = Math.max(d, depth(children[i]));
}
return 1 + d;
Expand Down
19 changes: 11 additions & 8 deletions src/layout/tree.js
Expand Up @@ -42,9 +42,9 @@ d3.layout.tree = function() {
function secondWalk(node, x) {
node.x = node._tree.prelim + x;
var children = node.children;
if (children) {
if (children && (n = children.length)) {
var i = -1,
n = children.length;
n;
x += node._tree.mod;
while (++i < n) {
secondWalk(children[i], x);
Expand Down Expand Up @@ -149,18 +149,21 @@ function d3_layout_treeSeparation(a, b) {
// }

function d3_layout_treeLeft(node) {
return node.children ? node.children[0] : node._tree.thread;
var children = node.children;
return children && children.length ? children[0] : node._tree.thread;
}

function d3_layout_treeRight(node) {
return node.children ? node.children[node.children.length - 1] : node._tree.thread;
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) {
if (children && (n = children.length)) {
var child,
n = children.length,
n,
i = -1;
while (++i < n) {
if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
Expand All @@ -186,11 +189,11 @@ function d3_layout_treeDeepest(a, b) {
function d3_layout_treeVisitAfter(node, callback) {
function visit(node, previousSibling) {
var children = node.children;
if (children) {
if (children && (n = children.length)) {
var child,
previousChild = null,
i = -1,
n = children.length;
n;
while (++i < n) {
child = children[i];
visit(child, previousChild);
Expand Down
86 changes: 45 additions & 41 deletions src/layout/treemap.js
Expand Up @@ -24,57 +24,61 @@ d3.layout.treemap = function() {

// Recursively arranges the specified node's children into squarified rows.
function squarify(node) {
if (!node.children) return;
var rect = pad(node),
row = [],
children = node.children.slice(), // copy-on-write
child,
best = Infinity, // the best row score so far
score, // the current row score
u = Math.min(rect.dx, rect.dy), // initial orientation
n;
scale(children, rect.dx * rect.dy / node.value);
row.area = 0;
while ((n = children.length) > 0) {
row.push(child = children[n - 1]);
row.area += child.area;
if ((score = worst(row, u)) <= best) { // continue with this orientation
children.pop();
best = score;
} else { // abort, and try a different orientation
row.area -= row.pop().area;
position(row, u, rect, false);
u = Math.min(rect.dx, rect.dy);
var children = node.children;
if (children && children.length) {
var rect = pad(node),
row = [],
remaining = children.slice(), // copy-on-write
child,
best = Infinity, // the best row score so far
score, // the current row score
u = Math.min(rect.dx, rect.dy), // initial orientation
n;
scale(remaining, rect.dx * rect.dy / node.value);
row.area = 0;
while ((n = remaining.length) > 0) {
row.push(child = remaining[n - 1]);
row.area += child.area;
if ((score = worst(row, u)) <= best) { // continue with this orientation
remaining.pop();
best = score;
} else { // abort, and try a different orientation
row.area -= row.pop().area;
position(row, u, rect, false);
u = Math.min(rect.dx, rect.dy);
row.length = row.area = 0;
best = Infinity;
}
}
if (row.length) {
position(row, u, rect, true);
row.length = row.area = 0;
best = Infinity;
}
children.forEach(squarify);
}
if (row.length) {
position(row, u, rect, true);
row.length = row.area = 0;
}
node.children.forEach(squarify);
}

// Recursively resizes the specified node's children into existing rows.
// Preserves the existing layout!
function stickify(node) {
if (!node.children) return;
var rect = pad(node),
children = node.children.slice(), // copy-on-write
child,
row = [];
scale(children, rect.dx * rect.dy / node.value);
row.area = 0;
while (child = children.pop()) {
row.push(child);
row.area += child.area;
if (child.z != null) {
position(row, child.z ? rect.dx : rect.dy, rect, !children.length);
row.length = row.area = 0;
var children = node.children;
if (children && children.length) {
var rect = pad(node),
remaining = children.slice(), // copy-on-write
child,
row = [];
scale(remaining, rect.dx * rect.dy / node.value);
row.area = 0;
while (child = remaining.pop()) {
row.push(child);
row.area += child.area;
if (child.z != null) {
position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length);
row.length = row.area = 0;
}
}
children.forEach(stickify);
}
node.children.forEach(stickify);
}

// Computes the score for the specified row, as the worst aspect ratio.
Expand Down

0 comments on commit 6804a60

Please sign in to comment.