Reputation: 4078
I am using d3.nest to create Hierarchical data from json of the following format:
[
{
'account_name':'abc123',
'fiscal_quarter':'q1',
'fiscal_period':'q1p1',
'fiscal_week_period':'q1p1w1',
'total':50.0
},
......
]
What I need to do is create nested data that has rollups at each level e.g
{
key:'account_name',
total:sum of all values in tree,
values:array of children
}
Is it possible to have non-leaf nodes with values,instead of just child nodes, or as an equivalent case, walk a nested data set and calculate values at each node?
Upvotes: 1
Views: 690
Reputation: 25283
You are right, d3's nest.rollup
handles only leaf groups. So you need to write a recursive function to traverse nest's entry tree and calculate agregates. Here's example for sum:
var topChildren = d3.nest()
.key(function(item)
{
return item['fiscal_quarter'];
})
.key(function(item)
{
return item['fiscal_period'];
})
.entries(data);
var root = {'values': topChildren, 'key': null};
function rollup(node)
{
node['sum'] = node['values'].reduce(function(result, item)
{
return result + (item['values'] ? rollup(item) : item['total']);
}, 0);
return node['sum'];
}
rollup(root);
console.log(root);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script>
var data = [
{
'account_name':'abc123',
'fiscal_quarter':'q1',
'fiscal_period':'q1p1',
'fiscal_week_period':'q1p1w1',
'total':50.0
},
{
'account_name':'abc234',
'fiscal_quarter':'q2',
'fiscal_period':'q2p3',
'fiscal_week_period':'q2p3w1',
'total':60.0
},
{
'account_name':'abc345',
'fiscal_quarter':'q2',
'fiscal_period':'q2p4',
'fiscal_week_period':'q1p4w1',
'total':70.0
},
{
'account_name':'abc456',
'fiscal_quarter':'q3',
'fiscal_period':'q3p1',
'fiscal_week_period':'q3p1w1',
'total':80.0
},
{
'account_name':'abc456',
'fiscal_quarter':'q3',
'fiscal_period':'q3p2',
'fiscal_week_period':'q3p2w1',
'total':90.0
}
];
</script>
Side note. +
operator takes precedence over ternary operator, so you need parentheses to change the priority. It works without an error otherwise, but just with incorrect result. If you want to challenge yourself to understand one (weak typing, which shouldn't be confused with dynamic typing) of JavaScript's design shortcomings, remove parentheses and try to understand why it works this way. I just have done, forgetting about operator precedence :-/
Upvotes: 2