如何在d3.js中走一棵树

时间:2014-12-10 22:32:21

标签: javascript d3.js

我正在使用d3.nest从以下格式的json创建分层数据:

[
 {
   'account_name':'abc123',
   'fiscal_quarter':'q1',
   'fiscal_period':'q1p1',
   'fiscal_week_period':'q1p1w1',
   'total':50.0
 },
 ......
]

我需要做的是创建在每个级别都有汇总的嵌套数据,例如

{
  key:'account_name',
  total:sum of all values in tree,
  values:array of children
}

是否可以使非叶子节点具有值,而不仅仅是子节点,或者作为等效情况,遍历嵌套数据集并计算每个节点的值?

1 个答案:

答案 0 :(得分:2)

你是对的,d3的nest.rollup只处理叶组。所以你需要编写一个递归函数来遍历nest的入口树并计算agregates。这是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>

旁注。 +运算符优先于三元运算符,因此需要使用括号来更改优先级。否则它没有错误,但结果不正确。如果你想挑战自己去理解JavaScript的设计缺点(弱打字,不应该与动态打字混淆),请删除括号并尝试理解它为什么会这样运作。我刚刚完成,忘记了运算符优先级: - /