2014-06-14 58 views
3

我有两个数据集具有相似的列/维但按行分组并且包含不同的度量。将一个Crossfilter数据集中的过滤器应用到另一个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对象,数据集2具有一个单独的crossfilter对象。我有多个dc.js图表​​,其中一些与数据集1相关,一些与数据集1相关,一些与数据集2相关。

当dc.js图表​​对数据集2中也存在的列/维过滤数据集1时,我希望将同样的过滤器到数据集2.如何实现这一目标?

回答

3

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

编辑:基于下面@亚拉文的小提琴,这里是一个“维镜”这样的作品,至少在这个简单的例子:

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') 
    }; 
} 

它使用这个有点凌乱。对于你想从crossfilter A到镜像到crossfilter B中的每个层面,你需要创建crossfilter 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/

+0

我与两个数据集有相同的情况进行比较。如果我点击数据集1中的一个项目,它将在数据集2图表中反映相同。你能否告诉我一个更好的方法来处理这个问题。 –

+0

这是我所知道的最好的方式,除了@ Ethan的建议将数据组合成一个交叉过滤器(以便它成为数据问题而不是逻辑问题)。你试过这个吗?它是如何失败的? – Gordon

+0

https://jsfiddle.net/caravinden/y8tts7eo/ @Gordon在这个例子中,我怎样才能同步两个图形之间的点击事件? –

2

@戈登的建议是一个很好的一个。

我通常通过将2个表合并成一个表(将ValueA和ValueB添加到数据集1的每一行),然后使用自定义分组为每个唯一Year /年仅聚合一次ValueA和ValueB,分类组合。每个组都需要保存一个前面已经看到的密钥的地图和每个密钥的计数,如果它是一个新的密钥组合,则仅聚合ValueA或ValueB的值。这确实会导致复杂的分组逻辑,但可以避免需要在2个Crossfilter对象之间进行协调。

就我个人而言,我只是发现复杂的自定义组合比协调逻辑更易于测试和使用,但这不适用于所有人。