Ответ 1
из документов:
nest.rollup(функция)
Определяет функцию сворачивания, которая должна применяться к каждой группе листаэлементы. Возвращаемое значение функции rollup заменит массив значений листа в ассоциативном массиве, возвращаемом оператора карты или атрибута значений для каждой записи, возвращаемой записей.
Как вы видите, rollup работает с листовыми элементами. Вы можете обойти это, если данные вложены на несколько уровней:
function nest(keys, data, rollupFunc) {
var nst = d3.nest();
keys.forEach(function(key) {
nst.key(function(d) { return d[key]; });
});
if (rollupFunc) {
nst.rollup(rollupFunc);
}
return nst.entries(data);
}
var rollupFunction = function(d) {
return {
"total_hours": d3.sum(d, function(dd) { return dd["hours"]})
}
}
var rez1 = nest(["project", "resource"], actuals);
var rez2 = nest(["project"], actuals, rollupFunction);
var rez3 = nest(["project", "resource"], actuals, rollupFunction);
Но это очень неэффективно для больших наборов данных. В противном случае я бы предложил использовать функцию nest()
для создания всех промежуточных уровней. Затем вы можете суммировать общие часы с помощью собственной рекурсивной функции. Псевдокод:
function aggregate(node) {
if (node has property total_hours) {
return total_hours
}
sum = 0
foreach child in data.values {
sum += aggregate(child)
}
node.total_hours = sum
return node.total_hours
}