-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accept iterables as children. #140
Comments
Ha I'm exactly at this point |
Related #135, I often find I want to create the simple JSON data structure instead of a d3.hierarchy instance. |
Here's my current solution
|
Here is my proposal to fix this and #135, d3.children: function children(values, ...keys) {
return {
children: (function node(value, depth) {
return depth >= keys.length ? value
: Array.from(value, ([key, value]) => ({key, children: node(value, depth + 1)}));
})(group(values, ...keys), 0)
};
} |
This also makes me wonder whether we still need a replacement for d3.nest that supports sorting of keys and values… |
I've tried your code and had to rename |
That’s expected, but the input format used by that treemap example isn’t really a standard, and the name “key” felt more appropriate. (Perhaps it should be key/values instead of name/children, but then the name d3.nest would be more appropriate than d3.children.) |
I rewrote https://observablehq.com/d/8d4ce02fcb6c6715 so that the name of each node is computed after the groupby/children operation. Using d3.hierarchy to traverse the json and update the properties. |
In this case I also needed a reduce operation, so rollup instead of group:
|
Yeah. That’s tricky. We have the existing d3.group and d3.rollup primitives, so this works well: rollup = d3.rollup(
raw.filter(d => d.year === "2014").filter(d => d.age === "26+"),
v => d3.sum(v, d => d.use),
d => d.drug,
d => d.state
) Maybe we just need a way to turn that into {name, children} objects? Kind of like array.map but applying recursively to map entries… I mean, this works: ({
children: Array.from(rollup, ([name, children]) => {
return {
name,
children: Array.from(children, ([name, value]) => {
return {name, value};
})
};
})
}) |
Here’s a way to pass the result of d3.rollup to d3.hierarchy: root = d3.hierarchy([, rollup], ([, value]) => value instanceof Map && Array.from(value)) The data for each node is [key, value], where the root key is undefined, the non-leaf value is a Map, and the leaf value is a number (the result of the previous d3.sum). So, you can node.sum as: root.sum(([, value]) => value) |
So, in other words, if d3.hierarchy allowed children to be an iterable and not just an array, and automatically ignored children that are not iterable, you would say: root = d3.hierarchy([, rollup], ([, value]) => value) |
It’d be nice to make d3.hierarchy compatible with the new d3.group in d3-array.
The text was updated successfully, but these errors were encountered: