dc.js 多图与范围图交互 - 设置过滤器后饼图变为空

dc.js multichart interaction with range chart - pie chart goes empty when filter set

我设置了一个小型 dc.js 仪表板,其中包含代表不同实验的饼图 select、代表实验结果的系列图以及结果的相关范围图。范围图正确更新系列图,类似地,饼图正确更新系列图。然而,范围图和饼图似乎并不想很好地相互配合。当我在范围图中设置过滤范围时,饼图变空了。

我在这里做了一个 jsfiddle:https://jsfiddle.net/nwhite/zb1xf0cu/132/

理想情况下,我可以 select 使用饼图进行 2 次左右的实验,然后使用范围图放大感兴趣的区域。但是当我应用范围过滤器时,饼图消失了。

系列图和范围图都使用相同的维度(runDimension)和组(runGroup),而饼图使用exptDimension和exptGroup:

ndx = crossfilter(experiments);
runDimension = ndx.dimension(function(d) {return [+d.Expt, +d.Run]; });
runGroup = runDimension.group().reduceSum(function(d) { return +d.Speed; });

exptDimension = ndx.dimension(function(d) {return +d.Expt; });
exptGroup = exptDimension.group();

虽然它是几年前推出的,但 seriesChart 仍然处于前沿,某些功能无法正常工作。

问题是维度键 ([+d.Expt, +d.Run]) 与图表应用的筛选器不一致,仅 RangeFilters 超过 d.Run

(Here's the issue on GitHub.)

它不如真正的 RangedFilter 高效,但我们可以定义一个过滤器处理程序,它可以查看此维度使用的复合键,并检查第二部分(通过 keyAccessor)在范围内:

function seriesFilter(dimensions, filters) {
  if (filters.length === 0) {
    runDimension.filter(null);
  } else {
    var filter = dc.filters.RangedFilter(filters[0][0], filters[0][1]);
    runDimension.filterFunction(function(k) {
      return filter.isFiltered(rangeChart.keyAccessor()({key: k, value: null}));
    });
  }
  return filters;
}

使问题复杂化的是,复合图表不仅会在父级应用过滤器,还会在每个子级应用过滤器。所以我们需要修补很多 filterHandlers 才能让它工作。

我们必须将此 filterHandler 应用于焦点图、范围图及其所有子图!

rangeChart.filterHandler(seriesFilter);
seriesChart.filterHandler(seriesFilter);
rangeChart
    // ...
    .chart(function(c) { return dc.lineChart(c).curve(d3.curveCardinal).filterHandler(seriesFilter); })
// same with seriesChart

Working fork of your fiddle.

请注意,无论您 select 做什么,切片的大小始终相同。所以演示中唯一很酷的事情是饼图在你 select 东西时不会变成空白。