Csv 使用交叉过滤器减少多个间接指定的字段

Csv 使用交叉过滤器减少多个间接指定的字段,csv,dc.js,crossfilter,Csv,Dc.js,Crossfilter,我有一个CSV数据集,我正在使用dc.js(crossfilter)进行开发 日期,国家1、国家2、国家3、国家4、国家5、国家6、目标国家(…) 2014/12/11,美国、法国、阿联酋、(…)、伊拉克 我想做的是绘制一个行图,每个国家有一行。 以下是我今天的解决方案: var-countries=ndx.dimension(函数(d){ var列表=[]; 列表.推送(d[“国家1”); if(d[“国家2]”){list.push(d[“国家2]”);}; if(d[“国家3]”){l

我有一个CSV数据集,我正在使用dc.js(crossfilter)进行开发


日期,国家1、国家2、国家3、国家4、国家5、国家6、目标国家(…)
2014/12/11,美国、法国、阿联酋、(…)、伊拉克

我想做的是绘制一个行图,每个国家有一行。 以下是我今天的解决方案:

var-countries=ndx.dimension(函数(d){
var列表=[];
列表.推送(d[“国家1”);
if(d[“国家2]”){list.push(d[“国家2]”);};
if(d[“国家3]”){list.push(d[“国家3]”);};
if(d[“国家4”]){list.push(d[“国家4”]);};
if(d[“国家5”]){list.push(d[“国家5”]);};
if(d[“国家6]”){list.push(d[“国家6]”);};
退货清单;
});
var countriesGroup=countries.group().reduceSum(函数(d){
返回d.totalNumberOfStrikes;
});;
乡村图
.宽度(400).高度(500)
.组(countriesGroup)
.层面(国家)
.排序(函数(d){return-d.value});
但是,正如您所看到的,它不会在列表数组中推送uniques。这会导致愚蠢的结果,因为CSV行中的每个国家/地区组合都会在列表中创建一个新项目

我想要的是有一个包含每个独特国家的列表,然后在行图表中绘制

你能帮忙吗?
多谢各位

最简单的方法可能是将数组展平,这样您的源代码中就有了日期、国家、目标。类似于(未经测试):

然后将
dest
传递给交叉筛选,而不是原始数据


这样做的好处是,现在当您单击图表中的行时,您可以按单个国家筛选其余的图表。由于crossfilter仅按行过滤,因此没有其他方法(没有严重的欺骗)按单个国家过滤,而不会无意中过滤共享这些行的其他国家。

根据后面的对话和,这里有一个更好的简化方法,可以保持数据的原样:

var strikingCountriesGroup = xScaleDimension.group().reduce(
    function(p, v) { // add
        countryFields.forEach(function(c) {
            if(v[c]) p[v[c]] = (p[v[c]] || 0) + v.totalNumberOfStrikes;
        });
        return p;
    },
    function(p, v) { // remove
        countryFields.forEach(function(c) {
            if(v[c]) p[v[c]] = p[v[c]] - v.totalNumberOfStrikes;
        });
        return p;
    },
    function() { // initial
        return {};
    }
);
虽然这看起来像是一个大括号,但其想法是字段
v[c]
,其中
c
是“国家1”,“国家2”。。。在原始数据集中,间接指定要在缩减中创建的字段

我们从值
v
减少到map
p
。我们在国家/地区字段上循环,对于每个
c
,如果
v
有一个
c
的条目,我们从
p[v[c]
中添加或减去
v.totalNumberOfStrikes
。如果值不存在,我们必须小心:表达式
|124; 0
如果未定义,则默认值为零

然后,我们可以像这样动态创建堆栈(按值排序):


在这里摆弄:

这里唯一的问题是,除了国家维度之外,您的计数和总数将在任何维度上膨胀。如果您需要处理这种情况,有几种方法可以定义自定义分组来处理这个问题。啊,这是一个很好的观点。你是不是想把每个国家都归为一个有字段的对象?老实说,我太迷茫了。从昨天开始就一直在修修补补,但没有任何成功:(如果这没有帮助,很抱歉。@Ethan,你是不是在想一种类似于中的“标记集”方法?@Gordon是的,我想这就是我的想法。按照你的建议做(将组合吹成单独的行)然后使用奇特的分组函数以确保不重复计数。ReduceTio支持对总和和计数进行此操作-请参阅自述文件底部的异常聚合示例-您可以在中看到保持值列表和基于值的计数的一般方法
var strikingCountriesGroup = xScaleDimension.group().reduce(
    function(p, v) { // add
        countryFields.forEach(function(c) {
            if(v[c]) p[v[c]] = (p[v[c]] || 0) + v.totalNumberOfStrikes;
        });
        return p;
    },
    function(p, v) { // remove
        countryFields.forEach(function(c) {
            if(v[c]) p[v[c]] = p[v[c]] - v.totalNumberOfStrikes;
        });
        return p;
    },
    function() { // initial
        return {};
    }
);
  var reducedCountries = strikingCountriesGroup.all()[0].value;
  var countries = d3.keys(reducedCountries).sort(function(a, b) {
      return reducedCountries[b] - reducedCountries[a];   
  });

  // we have to special-case the first group, see https://github.com/dc-js/dc.js/issues/797
  var first = countries.shift();
  strikingCountries
      .group(strikingCountriesGroup, first, 
         function(d) { 
             return d.value[first];
         });
  // rest
  countries.forEach(function(c) {    
      strikingCountries
          .stack(strikingCountriesGroup, c, 
             function(d) { 
                 return d.value[c];
             });
  });