首页 > 解决方案 > Stackbar chart in dcjs split by dimension

问题描述

I am trying to create a stack bar chart in dcjs. The dcjs stack bar examples are quite clear the huge difference from the barchart with that of stack is that the stack function. The stack function takes the same group as input and it can take third parameter as function which decides by which value it has to split. I rather want a dimension to be split the entire bar chart.

Lets say the following data point is something like this

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"}
]

I want to have activity group in x-axis split by its activity representing time taken on y-axis, like this:

goal

How do I achieve this ?

标签: d3.jsdc.js

解决方案


你的小提琴是在 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]));
    });

这与堆叠条形示例基本相同,只是我们有一个堆栈 per activity_group

请注意,我们在每个 bin 中创建所有堆栈,只是在它们不存在的地方将它们设为零。这是因为 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!


推荐阅读