我正在构建一个dc.js / d3.js仪表板,其中我经常需要制作包含每个键的数量和每个键的总值的百分比的交叉过滤器组。这就是为什么我想制作通用的reduceAdd,reduceRemove和reduceInitial函数。我管理了前2个,但我不了解reduceInitial行为:
function reduceAdd(dim,grouping,col) {
var keys = getKeys(dim); // get the keys name in an array of string
return function(p,v) {
p.total += parseInt(v[col]); // get the running total
for (var i = 0; i < keys.length; i++) {
if(v[grouping] == keys[i]) {p[keys[i]] += +v[col];}
p[keys[i]+"perc"] = p[keys[i]]/p.total; // calculate a percentage for ech key
}
return p;
}
}
function reduceRemove(dim,grouping,col) {
var keys = getKeys(dim);
return function(p,v) {
p.total -= parseInt(v[col]);
for (var i = 0; i < keys.length; i++) {
if(v[grouping] == keys[i]) {p[keys[i]] -= +v[col];}
p[keys[i]+"perc"] = p[keys[i]]/p.total;
}
return p;
}
}
这是非通用的function reduceInitFC() {
return {total:0, LILOU:0, MARIUS:0,ORIANE:0,LILOUperc:0,MARIUSperc:0,ORIANEperc:0};
}
这就是我的尝试:
function reduceInit(dim) {
var keys = getKeys(dim);
var initArray= {};
initArray["total"] = 0;
for (var i = 0; i < keys.length; i++) {
initArray[keys[i]] = 0;
initArray[keys[i]+"perc"] = 0;
}
console.log(initArray); // (1)
console.log({total:0, LILOU:0, MARIUS:0,ORIANE:0,LILOUperc:0,MARIUSperc:0,ORIANEperc:0});
return function() {
return initArray;
}
}
结果是: (1)输出每两次迭代为所有键提供0,为其他迭代提供一些非零值 当我使用这个函数时,组中的结果值与键不一致,实际情况并非如此,而不是我手写零值时的情况。
如果有人可以提供帮助,那将是非常友好和有用的。
最佳, 西奥
答案 0 :(得分:0)
我认为你的reduceInit看起来不错,但我认为通过reduce可以实现这一点。 reduce会逐步计算总计 - 并且在组遍历维度中的所有行之前不会有意义。因此,在完成reduce之前,不能计算每个键的百分比。 (同样,虽然reduce可用于计算单个键值的平均值,但它们不能用于所有键的平均值,因为这取决于减少的总数。)(更新,也请参阅此答案的评论)
但是,由于您已经减少了键/类别的总数和总数,因此您可以计算图表的valueAccessor中的百分比。
function valueAccessor(d){
return d.value[keyName] / d.value.total
}