维度1上的条形图,维度2上的条形图

时间:2018-07-02 18:43:58

标签: dc.js crossfilter

摘要

我想显示一个条形图,其尺寸为天,并按不同的类别堆叠(即x轴=天,堆叠=类别1)。我可以“手动”执行此操作,因为我可以将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));

1 个答案:

答案 0 :(得分:1)

我在对your other question的回答中提到了这一点,但是为什么不在这里进行一些扩展。

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的所有行都减少到一个对象,其中键是类型,值是该类型的值的总和。

此方法的工作方式是,当交叉过滤器遇到新键时,它首先使用“初始”函数来产生新值。这里的值是一个空对象。

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

在“删除”功能中我们不必格外小心,因为从箱中删除行的唯一方法是将其添加到箱中,因此{{1中必须有一个数字}}。

现在,每个bin都包含一个具有所有缩减值的对象,堆栈mixin包含p[v.type].group()有用的额外参数,这些参数使我们可以指定组/堆栈的名称,以及访问器。

例如,如果要从堆栈的对象中提取项目.stack()a,则可以使用:

b

它是not as convenient as it could be,但是您可以使用这些技术来add stacks to a chart programmatically(请参阅源代码)。