将Filter从一个Crossfilter数据集应用到另一个Crossfilter

时间:2014-06-14 23:57:02

标签: d3.js dc.js crossfilter

我有两个具有相似列/维度的数据集,但按行分组并包含不同的度量。

例如:

数据集1

Year   Category   SubCategory    Value01    Value02
2000   Cars       Sport          10         11
2000   Cars       Family         15         16
2000   Boats      Sport          20         21
2000   Boats      Family         25         26
...

数据集2

Year   Category    ValueA     ValueB
2000   Cars        100        101
2000   Boats       200        201
...

数据集1有自己的crossfilter对象,Dataset 2有一个单独的crossfilter对象。我有多个dc.js图表​​,其中一些与数据集1相关,一些与数据集2相关联。

当dc.js图表​​过滤数据集2中也存在的列/维度上的数据集1时,我想将相同的过滤器应用于数据集2.如何实现?

2 个答案:

答案 0 :(得分:4)

我不认为在crossfilter或dc.js中有任何自动方法可以做到这一点。但是,如果您愿意推广自己的维度包装器,则可以提供该维度包装而不是原始维度对象,并将其转发到所有基础维度。

编辑:基于@ Aravind的小提琴,这里是一个"尺寸镜"这是有效的,至少对于这个简单的例子:

function mirror_dimension() {
    var dims = Array.prototype.slice.call(arguments, 0);
    function mirror(fname) {
        return function(v) {
            dims.forEach(function(dim) {
                dim[fname](v);
            });
        };
    }
    return {
        filter: mirror('filter'),
        filterExact: mirror('filterExact'),
        filterRange: mirror('filterRange'),
        filterFunction: mirror('filterFunction')
    };
}

使用它有点乱。对于要从​​交叉滤波器A镜像到交叉滤波器B的每个维度,您需要在交叉滤波器B上创建镜像维度,反之亦然:

// Creating the dimensions
subject_DA = CFA.dimension(function(d){ return d.Subject; });
name_DA = CFA.dimension(function(d){ return d.Name; });
// mirror dimensions to receive events from crossfilter B
mirror_subject_DA = CFA.dimension(function(d){ return d.Subject; });
mirror_name_DA = CFA.dimension(function(d){ return d.Name; });

subject_DB = CFB.dimension(function(d){ return d.Subject; });
name_DB = CFB.dimension(function(d){ return d.Name; });
// mirror dimensions to receive events from crossfilter A
mirror_subject_DB = CFB.dimension(function(d){ return d.Subject; });
mirror_name_DB = CFB.dimension(function(d){ return d.Name; });

现在,在将它们传递给图表时将它们绑在一起:

// subject Chart
subjectAChart
    .dimension(mirror_dimension(subject_DA, mirror_subject_DB))
    // ...

// subject Chart
subjectBChart
    .dimension(mirror_dimension(subject_DB, mirror_subject_DA))
    // ...

nameAChart
    .dimension(mirror_dimension(name_DA, mirror_name_DB))
    // ...

nameBChart
    .dimension(mirror_dimension(name_DB, mirror_name_DA))
    // ...

由于所有图表均为implicitly on the same chart group,因此重绘事件在过滤时会自动在它们之间传播。并且一个交叉滤波器上的每个滤波器动作将应用于另一个交叉滤波器上的镜像尺寸。

也许不是我推荐做的事情,但像往常一样,可以让它发挥作用。

这里是小提琴:https://jsfiddle.net/gordonwoodhull/7dwn4y87/8/

答案 1 :(得分:2)

@Gordon的建议很好。

我通常采用不同的方法,将2个表组合成一个表(将ValueA和ValueB添加到数据集1的每一行),然后使用自定义分组仅为每个唯一的年份/类别聚合ValueA和Value B.组合。每个组都需要保留之前看到的密钥映射以及每个密钥的计数,如果它是新的密钥组合,则只聚合ValueA或ValueB的值。这确实导致了复杂的分组逻辑,但允许您避免需要在2个Crossfilter对象之间进行协调。

就我个人而言,我发现复杂的自定义分组比协调逻辑更容易测试和维护,但并非每个人都这样。