dcjs 中按维度拆分的堆积条形图

Stackbar chart in dcjs split by dimension

我正在尝试在 dcjs 中创建堆栈条形图。 dcjs stack bar 的例子很清楚,stack 和 barchart 的巨大区别在于 stack 函数。 stack 函数采用与输入相同的组,它可以采用第三个参数作为函数,该函数决定它必须拆分哪个值。我宁愿要一个维度来分割整个条形图。

假设下面的数据点是这样的

data = [
  {activity:"A1",time_taken:10,activity_group:"Master A"},
  {activity:"A2",time_taken:20,activity_group:"Master B"},
  {activity:"A1",time_taken:30,activity_group:"Master C"},
  {activity:"A2",time_taken:15,activity_group:"Master D"}
]

我想让 activity 组在 x 轴上被它的 activity 代表在 y 轴上花费的时间分开,像这样:

我该如何实现?

您的 fiddle 使用的是 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]));
    });

这与 stacked bar example 基本相同,只是我们每个 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));
})

这是输出。为了让图例不重叠,我对边距和高度做了一些改动,可能有更聪明的方法来处理这个问题:

Fork of your fiddle.

正如我所说,这让 dc.js 做了它不想做的事情,所以 YMMV!