我正在尝试构建一个平行坐标图,如Mike的例子所示。到目前为止一切顺利,但我在处理刷子事件时遇到了一些问题。
迈克的例子使用 v3,我使用的是 v4。v4 更新删除了brush.empty()
,留下d3.brushSelection(node)
来完成此角色。
这是我第一次使用该库,所以我不完全了解如何在某些情况下迭代选择。似乎 API 想要selection.node()
作为参数,但我的选择不是 1,而是画笔的集合。
有没有办法在 v4 中使用简单的 JS 构造(类似于 Mike 的(实现这一点?
下面是 Mike 在 v3 中对 brush 事件处理程序的实现
function brush() {
var actives = dimensions.filter(function(p) {
return !y[p].brush.empty();
}),
extents = actives.map(function(p) {
return y[p].brush.extent();
});
foreground.style("display", function(d) {
return actives.every(function(p, i) {
return extents[i][0] <= d[p] && d[p] <= extents[i][1];
}) ? null : "none";
});
}
这是互联网的匿名灵魂再次的事件处理程序,他在 v4 中实现了并行坐标。奖金(理论上(指向任何可以解释此代码如何工作的人。
function brush_parallel_chart() {
for (var i = 0; i < dimensions.length; ++i) {
if (d3.event.target == y[dimensions[i]].brush) {
extents[i] = d3.event.selection.map(y[dimensions[i]].invert, y[dimensions[i]]);
}
}
foreground.style("display", function(d) {
return dimensions.every(function(p, i) {
if (extents[i][0] == 0 && extents[i][0] == 0) {
return true;
}
return extents[i][1] <= d[p] && d[p] <= extents[i][0];
}) ? null : "none";
});
}
我能够通过引用 v4 示例中的上述代码片段来解决此问题。
我最初的方法是遍历画笔,并使用每个画笔的属性来确定当前点是否包含在其范围内。从概念上讲,这是正确的。
但是d3.event没有引用画笔,而是包含了我需要的所有信息。
const [upperBound, lowerBound] = d3.event.selection.map(scale.invert, scale);
// Or
const bounds = [scale(d3.event.selection), scale.invert(d3.event.selection)];
换句话说...
来自d3.event.selection
的数据是一个数字对,需要应用于画笔所包含的维度(轴(的scale
。
一旦有了画笔的边界,就很容易弄清楚所讨论的点是否包含在边界中。
return val >= lowerBound && val <= upperBound