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);
}
}
};
我们将忽略序数部分,因为那只是单独选择,而不是刷选。这是第二部分的反面:
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/
我不是数据可视化专家或 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);
}
}
};
我们将忽略序数部分,因为那只是单独选择,而不是刷选。这是第二部分的反面:
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/