我不是数据专家或d3,我已经找到了很多关于如何构建刷牙和缩放for example Mike的例子。
他们都已经展示了如何过滤到拉丝区域,但我想实现扭转这种效果,怎么样?
有人可以通过我的想法如何实现它吗?
答案 0 :(得分:1)
我不知道为什么当你链接到区域图表时我认为你的意思是条形图。如果您对使用折线图感兴趣,可以忽略突出显示部分并跳过过滤。没有突出显示折线图,只是刷子本身。
这并不是那么难,但它有些混乱,因为我们在图表中替换了未记录的函数。与dc.js中的大多数内容一样,如果没有选项,您通常可以替换功能(或者在图表渲染/绘制后添加或更改内容)。
这里有一个特定的公共功能,它会消除取消选择的区域。它被称为fadeDeselectedArea
。 (实际上,当图表是序数时,它都会淡化和淡化,但我们会忽略该部分。)
原始函数如下所示:
_chart.fadeDeselectedArea = function () {
var bars = _chart.chartBodyG().selectAll('rect.bar');
var extent = _chart.brush().extent();
if (_chart.isOrdinal()) {
if (_chart.hasFilter()) {
bars.classed(dc.constants.SELECTED_CLASS, function (d) {
return _chart.hasFilter(d.x);
});
bars.classed(dc.constants.DESELECTED_CLASS, function (d) {
return !_chart.hasFilter(d.x);
});
} else {
bars.classed(dc.constants.SELECTED_CLASS, false);
bars.classed(dc.constants.DESELECTED_CLASS, false);
}
} else {
if (!_chart.brushIsEmpty(extent)) {
var start = extent[0];
var end = extent[1];
bars.classed(dc.constants.DESELECTED_CLASS, function (d) {
return d.x < start || d.x >= end;
});
} else {
bars.classed(dc.constants.DESELECTED_CLASS, false);
}
}
};
我们会忽略序数部分,因为这只是个人选择,而不是刷选择。这是第二部分的反面:
spendHistChart.fadeDeselectedArea = function () {
var _chart = this;
var bars = _chart.chartBodyG().selectAll('rect.bar');
var extent = _chart.brush().extent();
// only covering the non-ordinal (ranged brush) case here...
if (!_chart.brushIsEmpty(extent)) {
var start = extent[0];
var end = extent[1];
bars.classed(dc.constants.DESELECTED_CLASS, function (d) {
return d.x >= start && d.x < end;
});
} else {
bars.classed(dc.constants.DESELECTED_CLASS, false);
}
};
创建变量_chart
只是为了尽可能保持代码相同。您可以看到d.x >= start && d.x < end
与d.x < start || d.x >= end
我们需要在图表中添加filterHandler
才能撤消过滤。同样,我们将它基于default behavior,但这里有一个合法的自定义点,所以我们不必替换一个函数,只需提供一个:
spendHistChart.filterHandler(function(dimension, filters) {
if(filters.length === 0)
dimension.filter(null);
else {
// assume one RangedFilter but apply in reverse
// this is less efficient than filterRange but it shouldn't
// matter much unless the data is huge
var filter = filters[0];
dimension.filterFunction(function(d) {
return !filter.isFiltered(d);
})
}
});
同样,我们删除了我们不关心的案例。没有理由对某些具有特定目的的东西进行一般性处理,这只会导致维护问题。我们唯一关心的两个案例是无过滤器和一个范围过滤器。
此处RangedFilter
已经提供了过滤功能,因此我们可以调用它而不是(!
)结果。这比filterRange
的效率略低,但是crossfilter对多个范围(或范围的倒数)没有原生支持。
就是这样!在这里小提琴:http://jsfiddle.net/gordonwoodhull/46snsbc2/8/