dc.js 排除拉丝区域并突出显示其余部分

dc.js exclude the brushed area and highlight rest

我不是数据可视化专家或 d3,我发现了很多关于如何构建刷亮和缩放的示例 for example Mike

他们都展示了如何过滤到刷过的区域,但我想实现反转效果,如何?

有人可以通过我的想法如何实现吗?

我不知道为什么当您链接到面积图时我假设您指的是条形图。如果您对折线图感兴趣,可以忽略突出显示部分并跳至过滤。折线图没有突出显示,只有画笔本身。

反向突出显示条形图

这并不难,但有点乱,因为我们替换了图表中未记录的函数。与 dc.js 中的大多数内容一样,如果没有选项,您通常可以替换功能(或者在图表具有 rendered/drawn 后添加或更改内容)。

这里有一个特定的 public 函数可以淡化取消选择的区域。它被称为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);
        }
    }
};

source link

我们将忽略序数部分,因为那只是单独选择,而不是刷选。这是第二部分的反面:

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 本身不支持多个范围(或范围的倒数)。

就是这样! Fiddle 这里:http://jsfiddle.net/gordonwoodhull/46snsbc2/8/