Dimension-1 和 Dimension-2 堆叠的条形图

Bar Chart on Dimension-1 and Stacked by Dimension-2

总结

我想显示一个条形图,其维度为天,并按不同的类别堆叠(即 x 轴 = 天,堆叠 = 类别 1)。我可以这样做 "manually" 因为我可以将 if-then 写为零或显示数量,但我想知道是否有系统的方法可以做到这一点。

JSFiddle https://jsfiddle.net/wostoj/rum53tn2/

详情

我有日期、数量和其他分类器的数据。为了这个问题的目的,我可以将其简化为:

data = [
 {day: 1, cat: 'a', quantity: 25},
 {day: 1, cat: 'b', quantity: 15},
 {day: 1, cat: 'b', quantity: 10},
 {day: 2, cat: 'a', quantity: 90},
 {day: 2, cat: 'a', quantity: 45},
 {day: 2, cat: 'b', quantity: 15},
]

我可以通过 day 设置一个显示总单位的条形图,我可以手动添加 'a' 和 'b' 的堆栈,如下所示。

var dayDim = xf.dimension(_ => _.day);
var bar = dc.barChart("#chart");
bar
  .dimension(dayDim)
  .group(dayDim.group().reduceSum(
    _ => _.cat === 'a' ? _.quantity : 0
   ))
  .stack(dayDim.group().reduceSum(
    _ => _.cat === 'b' ? _.quantity : 0
   ));

但是,当我的数据只有 2 个类别时,这很容易,但我想知道如何将其扩展到 10 个或未知数量的类别。我想我正在尝试做的伪代码是这样的

dc.barChart("#chart")
  .dimension(xf.dimension(_ => _.day))
  .stackDim(xf.dimension(_ => _.cat))
  .stackGroup(xf.dimension(_ => _.cat).group().reduceSum(_ => _.quantity));

我在对 的回答中提到了这一点,但为什么不在这里稍微展开一下。

In the dc.js FAQ 自定义缩减有一种标准模式,可以一次减少多个值。

假设您有一个名为 type 的字段,它确定行中的值类型,并且该值位于名为 value 的字段中(在您的例子中,这些是 catquantity)。然后

var group = dimension.group().reduce(
    function(p, v) { // add
        p[v.type] = (p[v.type] || 0) + v.value;
        return p;
    },
    function(p, v) { // remove
        p[v.type] -= v.value;
        return p;
    },
    function() { // initial
        return {};
    });

会将每个 bin 的所有行缩减为一个对象,其中键是类型,值是具有该类型的值的总和。

它的工作方式是,当 crossfilter 遇到一个新键时,它首先使用 "initial" 函数产生一个新值。这里的值是一个空对象。

然后,对于它遇到的落入标有该键的容器的每一行,它调用 "add" 函数。 p 是 bin 的前一个值,v 是当前行。因为我们从一个空白对象开始,所以我们必须确保初始化每个值; (p[v.type] || 0) 将确保我们从 0 而不是 undefined 开始,因为 undefined + 1NaN 而我们讨厌 NaN。

我们不必在 "remove" 函数中那么小心,因为从 bin 中删除行的唯一方法是它曾经被添加到其中,所以必须有一个数字在 p[v.type].

现在每个 bin 都包含一个包含所有减少值的对象,stack mixin 为 .group().stack() 提供了有用的额外参数,允许我们指定 group/stack,以及存取器。

例如,如果我们想从我们的堆栈的对象中提取项目 ab,我们可以使用:

.group(group, 'a', kv => kv.value.a)
.stack(group, 'b', kv => kv.value.b)

它是 not as convenient as it could be, but you can use these techniques to add stacks to a chart programmatically(查看来源)。