Skip to content

Commit

Permalink
Fix #31 - compute height by default.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Apr 1, 2016
1 parent ae69818 commit 8b4c396
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 9 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ A reference to the data associated with this node, as specified to the [construc

<a name="node_depth" href="#node_depth">#</a> <i>node</i>.<b>depth</b>

The depth of the node: zero for the root node, and increasing by one for each subsequent generation.
The depth of the node: zero for the root node, and increasing by one for each descendant generation.

<a name="node_height" href="#node_height">#</a> <i>node</i>.<b>height</b>

The height of the node: zero for any leaf node, and increasing by one for each ancestor generation.

<a name="node_parent" href="#node_parent">#</a> <i>node</i>.<b>parent</b>

Expand Down Expand Up @@ -140,7 +144,6 @@ Similarly, to sort nodes by descending height (greatest distance from any descen
```js
root
.sum(function(d) { return d.value; })
.eachBefore(function(d) { var h = 0; do d.height = h; while ((d = d.parent) && (d.height < ++h)); })
.sort(function(a, b) { return b.height - a.height || b.value - a.value; });
```

Expand Down Expand Up @@ -495,6 +498,7 @@ This returns:
{
"id": "Eve",
"depth": 0,
"height": 2,
"data": {
"id": "Eve",
"parentId": ""
Expand All @@ -503,6 +507,7 @@ This returns:
{
"id": "Cain",
"depth": 1,
"height": 0,
"parent": [Circular],
"data": {
"id": "Cain",
Expand All @@ -512,6 +517,7 @@ This returns:
{
"id": "Seth",
"depth": 1,
"height": 1,
"parent": [Circular],
"data": {
"id": "Seth",
Expand All @@ -521,6 +527,7 @@ This returns:
{
"id": "Enos",
"depth": 2,
"height": 0,
"parent": [Circular],
"data": {
"id": "Enos",
Expand All @@ -530,6 +537,7 @@ This returns:
{
"id": "Noam",
"depth": 2,
"height": 0,
"parent": [Circular],
"data": {
"id": "Noam",
Expand All @@ -541,6 +549,7 @@ This returns:
{
"id": "Abel",
"depth": 1,
"height": 0,
"parent": [Circular],
"data": {
"id": "Abel",
Expand All @@ -550,6 +559,7 @@ This returns:
{
"id": "Awan",
"depth": 1,
"height": 1,
"parent": [Circular],
"data": {
"id": "Awan",
Expand All @@ -559,6 +569,7 @@ This returns:
{
"id": "Enoch",
"depth": 2,
"height": 0,
"parent": [Circular],
"data": {
"id": "Enoch",
Expand All @@ -570,6 +581,7 @@ This returns:
{
"id": "Azura",
"depth": 1,
"height": 0,
"parent": [Circular],
"data": {
"id": "Azura",
Expand Down
19 changes: 14 additions & 5 deletions src/hierarchy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,27 @@ export default function hierarchy(data) {
}
}

return root;
return root.eachBefore(computeHeight);
}

function node_copy() {
return hierarchy(this).eachBefore(function(node) {
node.data = node.data.data;
});
return hierarchy(this).eachBefore(copyData);
}

function copyData(node) {
node.data = node.data.data;
}

export function computeHeight(node) {
var height = 0;
do node.height = height;
while ((node = node.parent) && (node.height < ++height));
}

export function Node(data) {
this.data = data;
this.depth = 0;
this.depth =
this.height = 0;
this.parent = null;
}

Expand Down
4 changes: 2 additions & 2 deletions src/stratify.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {required} from "./accessors";
import {Node} from "./hierarchy/index";
import {Node, computeHeight} from "./hierarchy/index";

var keyPrefix = "$", // Protect against keys like “__proto__”.
preroot = {depth: -1};
Expand Down Expand Up @@ -53,7 +53,7 @@ export default function() {

if (!root) throw new Error("no root");
root.parent = preroot;
root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; });
root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
root.parent = null;
if (n > 0) throw new Error("cycle");

Expand Down
32 changes: 32 additions & 0 deletions test/stratify-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,27 @@ tape("stratify(data) returns the root node", function(test) {
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 2,
data: {id: "a"},
children: [
{
id: "aa",
depth: 1,
height: 1,
data: {id: "aa", parentId: "a"},
children: [
{
id: "aaa",
depth: 2,
height: 0,
data: {id: "aaa", parentId: "aa"}
}
]
},
{
id: "ab",
depth: 1,
height: 0,
data: {id: "ab", parentId: "a"}
}
]
Expand All @@ -55,23 +59,27 @@ tape("stratify(data) does not require the data to be in topological order", func
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 2,
data: {id: "a"},
children: [
{
id: "aa",
depth: 1,
height: 1,
data: {id: "aa", parentId: "a"},
children: [
{
id: "aaa",
depth: 2,
height: 0,
data: {id: "aaa", parentId: "aa"}
}
]
},
{
id: "ab",
depth: 1,
height: 0,
data: {id: "ab", parentId: "a"}
}
]
Expand All @@ -90,21 +98,25 @@ tape("stratify(data) preserves the input order of siblings", function(test) {
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 2,
data: {id: "a"},
children: [
{
id: "ab",
depth: 1,
height: 0,
data: {id: "ab", parentId: "a"}
},
{
id: "aa",
depth: 1,
height: 1,
data: {id: "aa", parentId: "a"},
children: [
{
id: "aaa",
depth: 2,
height: 0,
data: {id: "aaa", parentId: "aa"}
}
]
Expand All @@ -125,23 +137,27 @@ tape("stratify(data) treats an empty parentId as the root", function(test) {
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 2,
data: {id: "a", parentId: ""},
children: [
{
id: "aa",
depth: 1,
height: 1,
data: {id: "aa", parentId: "a"},
children: [
{
id: "aaa",
depth: 2,
height: 0,
data: {id: "aaa", parentId: "aa"}
}
]
},
{
id: "ab",
depth: 1,
height: 0,
data: {id: "ab", parentId: "a"}
}
]
Expand All @@ -159,16 +175,19 @@ tape("stratify(data) does not treat a falsy but non-empty parentId as the root",
test.deepEqual(noparent(root), {
id: "0",
depth: 0,
height: 1,
data: {id: 0, parentId: null},
children: [
{
id: "1",
depth: 1,
height: 0,
data: {id: 1, parentId: 0}
},
{
id: "2",
depth: 1,
height: 0,
data: {id: 2, parentId: 0}
}
]
Expand Down Expand Up @@ -213,14 +232,17 @@ tape("stratify(data) allows the id to be undefined for leaf nodes", function(tes
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 1,
data: {id: "a"},
children: [
{
depth: 1,
height: 0,
data: {parentId: "a"}
},
{
depth: 1,
height: 0,
data: {parentId: "a"}
}
]
Expand All @@ -245,10 +267,12 @@ tape("stratify(data) allows the id to be undefined for leaf nodes", function(tes
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 1,
data: {id: "a"},
children: [
{
depth: 1,
height: 0,
data: o
}
]
Expand All @@ -269,23 +293,27 @@ tape("stratify.id(id) observes the specified id function", function(test) {
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 2,
data: {foo: "a"},
children: [
{
id: "aa",
depth: 1,
height: 1,
data: {foo: "aa", parentId: "a"},
children: [
{
id: "aaa",
depth: 2,
height: 0,
data: {foo: "aaa", parentId:"aa" }
}
]
},
{
id: "ab",
depth: 1,
height: 0,
data: {foo: "ab", parentId:"a" }
}
]
Expand Down Expand Up @@ -313,23 +341,27 @@ tape("stratify.parentId(id) observes the specified parent id function", function
test.deepEqual(noparent(root), {
id: "a",
depth: 0,
height: 2,
data: {id: "a"},
children: [
{
id: "aa",
depth: 1,
height: 1,
data: {id: "aa", foo: "a"},
children: [
{
id: "aaa",
depth: 2,
height: 0,
data: {id: "aaa", foo: "aa"}
}
]
},
{
id: "ab",
depth: 1,
height: 0,
data: {id: "ab", foo: "a"}
}
]
Expand Down
1 change: 1 addition & 0 deletions test/treemap/flare-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ function test(input, expected, tile) {
delete node.parent;
delete node.data;
delete node._squarify;
delete node.height;
if (node.children) node.children.forEach(visit);
})(actual);

Expand Down

0 comments on commit 8b4c396

Please sign in to comment.