捕捉刷到下一个 x 值? [dc.js]

snapping brush to the next x value? [dc.js]

我有折线图和数据

[{
    time: "2016-4-29"
    total: 23242
},
{ 
    time: "2016-5-16
    total: 3322
}
...
]

我正在尝试使用刷子在 x 轴上进行过滤,但是,由于我没有每个日期,如果我在一个小范围内刷,过滤器处理程序似乎 return我的过滤器的空数组

我已经像这样设置折线图的 x 轴:

.x(d3.time.scale().domain([minDate,maxDate]))

有没有办法让用户只能过滤数据集中的日期?

我希望画笔捕捉到数据集中的日期。

似乎发生的事情是你可以在刻度之间刷牙..所以它不知道它选择了什么。

我要回答一个更简单的问题:如何创建不允许选择任何内容的画笔?

换句话说,如果刷机没有数据,就不允许刷机。

解决方案分为两部分。首先,由于任何带有画笔的图表都会删除旧过滤器,然后添加新过滤器,我们可以设置 addFilterHandler 拒绝任何不包含 non-zero bins 的过滤器:

spendHistChart.addFilterHandler(function(filters, filter) {
  var binsIn = spendHistChart.group().all().filter(function(kv) {
    return filter.isFiltered(kv.key) && kv.value;
  });
  console.log('non-empty bins in range', binsIn.length);
  return binsIn.length ? [filter] : [];
});

这是最简单的部分,顺便说一下,我认为您可以修改它以将画笔捕捉到现有数据。 (不过我还没试过。)

更棘手的部分是这不会摆脱画笔,它只是不应用过滤器。所以图表最终会处于不一致的状态。

我们需要检测刷操作何时完成,如果此时没有过滤器,明确告诉图表清除过滤器:

spendHistChart.brush().on('brushend.no-empty', function() {
  if(!spendHistChart.filters().length)
    window.setTimeout(function() {
        spendHistChart.filterAll().redraw();
    }, 100);
});

我们这里需要一个短暂的延迟,因为如果我们同步响应brushend,图表可能还在响应它,引起争吵和不满。

作为奖励,由于 unintentional remove-brush animation.

,您可以获得一种 "nah-ah" 动画效果

demo fiddle