javascript - Crossfilter 中的自定义计算聚合字段

标签 javascript json crossfilter

我一直在玩 crossfilter,发现它很棒,但最近碰壁了。我不知道我的问题是否需要 crossfilter,很高兴听到任何替代解决方案。

我的数据是这样的:

[{ 
year: "1987", 
country: "UK", 
product: "pineapple", 
tons_available: 10, 
tons_sold: 8
},
{ year: "1987", country: "US", product: "pineapple", tons_available: 34, tons_sold: 18},
{ year: "1987", country: "UK", product: "pear", tons_available: 4, tons_sold: 3},
{ year: "1987", country: "US", product: "pear", tons_available: 23, tons_sold: 20},
{ year: "1988", country: "UK", product: "pineapple", tons_available: 12, tons_sold: 3},
{ year: "1988", country: "US", product: "pineapple", tons_available: 56, tons_sold: 6},
{ year: "1988", country: "UK", product: "pear", tons_available: 32, tons_sold: 32},
{ year: "1988", country: "US", product: "pear", tons_available: 31, tons_sold: 8},
and on, and on...]

我想汇总年度数据,并且能够针对“tons_available”和“tons_sold”等已有指标进行汇总。

var by_week = data_to_filter.dimension( function(d) { return d.year; });
var tons_sold_by_week = by_week.group()
                         .reduceSum(function(d) { return d.tons_sold; });

但是,我找不到在聚合对象之上创建指标的方法。例如,我想创建一个每年的销售率。为此,我需要每年对所有字段求和,然后仅除以:tons_sold/tons_available。

理想情况下,这会给我一个格式如下的 json:

[{ 
year: "1987", 
tons_available: 71, 
tons_sold: 49
str: 0.69
},
{ year: "1988", tons_available: 131, tons_sold: 49, str: 0.37 },
and on, and on...]

在我看来,聚合对象每年只保留求和变量和结果,只有一对键/值。

有没有办法实现我所追求的?

非常感谢!

最佳答案

希望这对你仍然有用。

您可以通过为您的特定用例定义 reduceAdd、reduceRemove 和 reduceInitial 函数,然后将它们传递给 reduce 来实现这一点。

代码:

var cf   = crossfilter(data),
    year = cf.dimension(function(d) { return d.year; });

var reduceAdd = function(p, v) {
    p.tons_available += v.tons_available;
    p.tons_sold      += v.tons_sold;
    p.str            = p.tons_sold/p.tons_available;
    return p;
}

var reduceRemove = function(p, v) {
    p.tons_available -= v.tons_available;
    p.tons_sold      -= v.tons_sold;
    p.str            = p.tons_sold/p.tons_available;
    return p;
}

var reduceInitial = function() {
    return {
        tons_available : 0,
        tons_sold      : 0,
        str            : 0
    }
}

var json = year.group().reduce(reduceAdd,reduceRemove,reduceInitial).orderNatural().top(Infinity);

console.log(json);

当 Crossfilter 添加记录时,它使用 reduceAdd 重新计算值。当 Crossfilter 删除过滤掉的记录时,它使用 reduceRemove 来更新值。它需要一个由 reduceInitial 提供的初始值(注意它是一个函数)。从文档中查看此永久链接 https://github.com/square/crossfilter/wiki/API-Reference#group_reduce .

我使用了您在上面提供的输入,这是我得到的 json:

[{key: "1988", value: {
    str: 0.37404580152671757,
    tons_available: 131,
    tons_sold: 49},
 {key: "1987", value: {
    str: 0.6901408450704225,
    tons_available: 71,
    tons_sold: 49}]

这不完全是您要求的输出,但非常接近。

关于javascript - Crossfilter 中的自定义计算聚合字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18211448/

相关文章:

javascript - 如何禁用/抑制 jQuery 数据表的某些部分的渲染?

javascript - 大型 FOR 循环中的新局部变量,这是一个问题吗?

javascript - 在新窗口中打开按钮?

php - JSON 未在 php 中编译

javascript - 在 Crossfilter/DC.js 中加载 CSV 并创建过滤器

javascript - 使用交叉过滤器为十进制值创建组

javascript - 防止同IP的cors

javascript - JSON.PARSE 不会丢失 header 数组字段

json - 如何在 GJSON 中循环 slice

javascript - dc-js 禁止在单击饼图时选择切片