2014-12-10 2 views
1

Я использую d3.nest создавать иерархические данные из JSON следующего формата:Как ходить дерево в d3.js

[ 
{ 
    '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 
} 

можно ли иметь не листовые узлы со значениями, а не только дочерними узлов, или как эквивалентными случае, ходить вложенный набор данных и вычисление значений в каждом узле?

ответ

2

Вы правы, d3's nest.rollup обрабатывает только группы листьев. Таким образом, вам нужно написать рекурсивную функцию, чтобы пересечь дерево записей гнезда и вычислить агрегированные объекты. Вот пример для суммы:

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, удалить круглые скобки и попытаться понять, почему он работает таким образом. Я только что сделал, забыв о приоритете оператора: -/

+0

Thankyou! Это спасло меня много времени, прорывая документацию. – sakurashinken

Смежные вопросы