我有一个使用 D3 生成的散点图。可以通过单击选择图上的点(SVG 圆圈),也可以使用 D3 画笔选择区域。
为了确保圆圈获得点击事件,我需要先创建画笔,以便圆圈位于画笔上方。不幸的是,这意味着当我的光标位于绘图中的某个点上时,我无法通过拖动来创建画笔范围。
有没有办法将悬停和点击事件传递给圆圈,但处理与画笔拖动相关的事件?
最佳答案
它可以完成,但需要 use of the D3 brush API (见下面的注释)。
这是一个例子 http://bl.ocks.org/4747894其中:
brush
元素在圆圈后面- 圆圈响应
mousedown
事件。 (也可以响应其他事件。) - 即使从其中一个圆圈内部开始拖动,
brush
元素也表现良好。
一些跟踪和查看 D3 source code提示当从画笔顶部的 circle
元素触发 mousemove
事件时,extent
未正确重置。这可以通过为 circle
元素的 mousedown
监听器重置画笔的 extent
来解决:
circles.on("mousedown", function (d, i) {
// _svg_ is the node on which the brush has been created
// x is the x-scale, y is the y-scale
var xy = d3.mouse(svg.node()),
xInv = x.invert(xy[0]),
yInv = y.invert(xy[1]);
// Reset brush's extent
brush.extent([[xInv, yInv], [xInv, yInv]]);
// Do other stuff which we wanted to do in this listener
});
注意: As per the API ,调用 .extent(values)
时,画笔的选择不会自动刷新。只需单击一个圆圈即可重置范围
,但不会重新绘制所做的选择。仅当在 circle
内开始不同的选择,或通过在圆圈和当前选择之外单击时,才会放弃选择。 正如我从问题中理解的那样,这是期望的行为。但是,这可能会破坏编写时假设画笔的 extent
是图形上可见的选择的代码。
关于javascript - 使用 D3 画笔进行细粒度事件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14697495/