Ваша скрипка на dc.js версии 1.7, которой более пяти лет, и я не могу обернуть голову вокруг. : - /
Я преобразовал его в dc.js версии 2, в которой также используется D3 v3.
dc.js не очень хорош для отображения необработанных данных, он больше относится к агрегированным данным. Но в этом случае может иметь смысл создать стек для каждого activity_group
;таким образом, ему будет автоматически назначен свой собственный цвет.
Используя ES6, мы можем получить список всех activity_group
следующим образом:
const stacks = [...new Set(data.map(row => row.activity_group))];
Теперь давайте агрегируем данные по стеку:
var groupActivity = dimByActivity.group().reduce(
function reduceAdd(p, v) {
p[v.activity_group] += v.time_taken;
return p;
},
function reduceRemove(p, v) {
p[v.activity_group] -= v.time_taken;
return p;
},
function reduceInitial() {
return Object.fromEntries(stacks.map(stack => [stack,0]));
});
Это практически то же самое, что и пример с накоплением , за исключением того, что у нас есть стек на activity_group
.
Обратите внимание, что мы создаем все стеки вкаждый бин, просто оставляя их ноль, где они не существуют. Это связано с тем, что dc.js ожидает одинаковые стеки для каждого значения X - иначе он не будет работать.
Как и в примере с столбцами стеков, мы программно добавим стеки к диаграмме, имея в виду, чтонам нужно использовать .group()
для первого стека:
function sel_stack(valueKey) {
return function(d) {
return d.value[valueKey];
};
}
// ...
stacks.forEach(function(stack, i) {
if(i===0)
chanUtil.group(groupActivity, stack, sel_stack(stack));
else
chanUtil.stack(groupActivity, stack, sel_stack(stack));
})
Вот вывод. Я немного испортил поля и высоту, чтобы легенда не перекрывалась, и, вероятно, есть более разумные способы справиться с этим:
Вилка вашей скрипки .
Как я уже говорил, это заставляет dc.js делать то, чего он не хочет, так что YMMV!