如何做一个复杂的crossfilter减少
我正在尝试使用自定义约简(reduceAdd,reduceRemove等)创建一个用于放入dc.js的变量,并且无法弄清楚如何对其进行编码。
我在这些reduce函数之外编写了函数,现在必须复制相同的reduce函数,以便对绘制的图形使用相同的函数。 为外部减函数编写的逻辑和代码如下所示
逻辑:对于每个可用的唯一contact_week(日期),查找week_number的最大值,然后总结TOTCOUNT变量和DECAY_CNT变量并计算百分比(DECAY_CNT / TOTCOUNT)。
以下是不使用交叉过滤器的原始代码:
//Decay % logic
var dates = d3.map(filter1,function(d) { return d.CONTACT_WEEK;}).keys() ;
console.log(dates);
var sum1,sum2 = 0;
for(var i=0; i<dates.length; i++)
{
data1 = filter1.filter(function(d) { return d.CONTACT_WEEK == dates[i] ;});
//console.log(data1);
var max = d3.max(data1, function(d) { return +d.WEEK_NUMBER ;});
//console.log(max);
data2 = data1.filter(function(d) { return d.WEEK_NUMBER == max ;});
var sum1 = d3.sum(data2, function(d) { return d.TOTCOUNT ;});
var sum2 = d3.sum(data2, function(d) { return d.DECAY_CNT ;});
console.log(sum1);
var decay = sum2/sum1 * 100 ;
console.log(decay);
}
第一步是确定日期的唯一值(contact_week) - 如何在reduce函数中执行此操作,因为它已经是遍历数据的for循环了?
我猜想对于最大等,我们可以使用reductio或一些其他逻辑,如评论中提到的,但我没有真正得到在这里遵循的方法/设计
任何方法/解决方案的帮助将不胜感激。
UPDATE2:
尝试使用reductio js的新方法
数据说明:
我的数据中的几列 - contact_week(日期); week_number(数字 - -4至6); decay_cnt(整数); 总数(整数); 持续时间(序数值 - 前,中,后);
现在,我需要计算一个名为decay%的百分比,计算方法如下:对于每个唯一的contact_week,查找week_number的最大值,现在针对此过滤的数据集计算sum(decay_cnt)/ sum(totcount)
这必须绘制在x轴为持续时间并且度量 - 衰变%为y轴的条形图中
为了计算单个日期的最大周数,我现在绘制了一个条形图,其中contact_week为x轴,week_number的最大值为y轴。 我如何获得我需要的图表?
代码:
dateDimension2 = ndx.dimension(function(d) {return d.CONTACT_WEEK ;});
decayGroup = reductio().max(function (d) { return d.WEEK_NUMBER; })(dateDimension2.group());
chart2
.width(500)
.height(200)
.x(d3.scale.ordinal())
//.x(d3.scale.ordinal().domain(["DURING","POST1"]))
.xUnits(dc.units.ordinal)
//.xUnits(function(){return 10;})
//.brushOn(false)
.yAxisLabel("Decay (in %)")
.dimension(dateDimension)
.group(decayGroup)
.gap(10)
.elasticY(true)
//.yAxis().tickValues([0, 5, 10, 15])
//.title(function(d) { return d.key + ": " + d3.round(d.value.new_count,2); })
/*.valueAccessor(function (p) {
//return p.value.count > 0 ? (p.value.dec_total / p.value.new_count) * 100 : 0;
return p.value.decay ;
})*/
.valueAccessor(function(d) { return d.value.max; })
.on('renderlet', function(chart) {
chart.selectAll('rect').on("click", function(d) {
console.log("click!", d);
});
})
.yAxis().ticks(5);
任何方法/建议将不胜感激
我认为解决方案主要在于假群体/维度和简化联合方法。 任何替代品是最受欢迎的!
我刚刚为这类问题添加了常见问题解答和示例。
正如在那里解释的那样,这个想法是维护一排落入每个垃圾箱的行,因为交叉过滤器不能提供访问权限。 一旦我们获得了实际的行数,您的计算结果与您现在所做的几乎相同,只不过crossfilter会跟踪您的星期列表。
所以你可以使用这个例子中的这些函数:
function groupArrayAdd(keyfn) {
var bisect = d3.bisector(keyfn);
return function(elements, item) {
var pos = bisect.right(elements, keyfn(item));
elements.splice(pos, 0, item);
return elements;
};
}
function groupArrayRemove(keyfn) {
var bisect = d3.bisector(keyfn);
return function(elements, item) {
var pos = bisect.left(elements, keyfn(item));
if(keyfn(elements[pos])===keyfn(item))
elements.splice(pos, 1);
return elements;
};
}
function groupArrayInit() {
return [];
}
您需要在记录中拥有唯一的密钥,以便可以可靠地添加和删除它们。 我会假设你的记录有一个ID
字段。
定义您的星期维度和组如下所示:
var weekDimension = ndx.dimension(function(d) {return d.CONTACT_WEEK ;}),
id_function = function(r) { return r.ID; },
weekGroup = weekDimension.group().reduce(groupArrayAdd(id_function), groupArrayRemove(id_function), groupArrayInit);
那么计算度量标准的最有效时间是在需要时,在值存取器中。 所以你可以用你在问题中发布的代码的核心来定义你的值访问器。
(当然,这个代码没有经过测试,因为我不知道你的数据。)
var calculateDecay = function(kv) {
// kv.value has the array produced by the reduce functions.
var data1 = kv.value;
var max = d3.max(data1, function(d) { return +d.WEEK_NUMBER ;});
data2 = data1.filter(function(d) { return d.WEEK_NUMBER == max ;});
var sum1 = d3.sum(data2, function(d) { return d.TOTCOUNT ;});
var sum2 = d3.sum(data2, function(d) { return d.DECAY_CNT ;});
var decay = sum2/sum1 * 100 ;
return decay;
}
chart.valueAccessor(calculateDecay);
链接地址: http://www.djcxy.com/p/5601.html
上一篇: how to do a complex crossfilter reduction
下一篇: Changing the data group in a dc.js line chart and redrawing it