如何在 d3.js 中走一棵树

How to walk a tree in d3.js

本文关键字:一棵树 js d3      更新时间:2023-09-26

我正在使用 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
}

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

你是

对的,d3 的nest.rollup只处理叶组。因此,您需要编写一个递归函数来遍历 nest 的入口树并计算聚合。下面是总和的示例:

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设计的一个缺点(弱类型,不应该与动态类型混淆),去掉括号并尝试理解为什么它以这种方式工作。我刚刚做了,忘记了运算符优先级:-/