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));
})
这是输出。为了让图例不重叠,我对边距和高度做了一些改动,可能有更聪明的方法来处理这个问题:
正如我所说,这让 dc.js 做了它不想做的事情,所以 YMMV!
我正在尝试在 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));
})
这是输出。为了让图例不重叠,我对边距和高度做了一些改动,可能有更聪明的方法来处理这个问题:
正如我所说,这让 dc.js 做了它不想做的事情,所以 YMMV!