我想显示一个条形图,其尺寸为天,并按不同的类别堆叠(即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));
答案 0 :(得分:1)
我在对your other question的回答中提到了这一点,但是为什么不在这里进行一些扩展。
In the dc.js FAQ,有一个用于自定义归约的标准模式,可一次减少多个值。
假设您有一个名为type
的字段,该字段确定该行中的值的类型,并且该值位于名为value
的字段中(在您的情况下为cat
和quantity
)。然后
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 + 1
是NaN
并且我们讨厌NaN。
在“删除”功能中我们不必格外小心,因为从箱中删除行的唯一方法是将其添加到箱中,因此{{1中必须有一个数字}}。
现在,每个bin都包含一个具有所有缩减值的对象,堆栈mixin包含p[v.type]
和.group()
有用的额外参数,这些参数使我们可以指定组/堆栈的名称,以及访问器。
例如,如果要从堆栈的对象中提取项目.stack()
和a
,则可以使用:
b
它是not as convenient as it could be,但是您可以使用这些技术来add stacks to a chart programmatically(请参阅源代码)。