Мы можем использовать фальшивую группу для накопления значений способом, необходимым для базовой и конечной величины:
function waterfall_group(group, endkey, acc) {
acc = acc || (x => x);
return {
all: () => {
let cumulate = 0;
let all = group.all().map(({key,value}) => {
value = acc(value)
const kv = {
key,
value: {
baseline: cumulate,
data: value
}
};
cumulate += value;
return kv;
});
return all.concat([{key: endkey, value: {baseline: 0, data: cumulate}}]);
}
};
}
Эта функция берет ключ для итоговой "итоговой суммы" "bar и функция доступа, необходимая здесь, потому что reductio оборачивает значения в дополнительный объект.
Возвращает группу со значениями {baseline,data}
, где baseline
- фиктивное значение, необходимое для невидимого стека, и data
- это значение для бара.
Создайте поддельную группу, такую как
var waterfall_group = waterfall_group(grp, 'x5', x => x.sum);
и передайте ее .group()
и .stack()
с аксессорами, чтобы получить вспомогательные значения:
waterfallChart
.group(waterfall_group, 'baseline', kv => kv.value.baseline)
.stack(waterfall_group, 'data', kv => kv.value.data)
Я также изменил код раскраски, чтобы получить новый формат данных:
chart.selectAll("svg g g.chart-body g.stack._1 rect.bar")
.style("fill", function(d){if (d.data.value.data >0) return '#ff7c19'; else return '#7c7c7c';});
Чтобы проверить это, я добавил еще одно поле "категория" и диаграмму ap ie. Обратите внимание, что диаграмма водопада может попасть в некоторые странные состояния с отрицательными и нулевыми значениями (например, нажмите «C»), но они выглядят правильно.
Вилка вашей скрипки .
Обратите внимание, что поскольку последний элемент (x5 здесь) является чисто синтетическим c и не связан с какими-либо базовыми данными, фильтрация при нажатии на этот элемент вызовет другие графики, чтобы убрать. Я не уверен, как отключить клики на одном конкретном элементе.