使用D3画笔处理细粒度事件

Ric*_*chH 11 javascript events svg d3.js

我有一个使用D3生成的散点图.可以通过单击它们来选择绘图上的点(SVG圆),并使用D3笔刷选择区域.

为了确保圆圈获得点击事件,我需要先创建画笔,使圆圈位于其上方.不幸的是,这意味着当光标位于绘图中的某个点上时,我无法拖动以创建画笔范围.

有没有办法将悬停和点击事件传递给圈子,但是用画笔处理与拖动相关的事件?

mus*_*_ut 14

它可以完成,但使用D3刷API(见下面的注释).

这是一个例子http://bl.ocks.org/4747894其中:

  1. 所述brush元件是后面的圆圈
  2. 圈子响应该mousedown事件.(也可以回应其他事件.)
  3. brush即使从其中一个圆圈内部开始拖动,该元素仍然表现良好.

一些跟踪和D3源代码的观察表明,extentmousemovecircle画笔顶部的元素触发事件时,没有正确地重置.这可以通过在元素extentmousedown侦听器中重置画笔来解决circle:

        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
        });
Run Code Online (Sandbox Code Playgroud)

注意: 根据API,刷子的选择在调用时不会自动刷新.extent(values).只需单击一个圆圈即可重置extent但不会重绘所做的选择.仅当在内部开始不同的选择时circle,或者通过在圆圈和当前选择之外单击时,才会丢弃选择.正如我从问题中理解的那样,这是理想的行为.但是,这可能会破坏编写的代码,假设无论extent刷子是什么,都可以在图形上看到选择.


Wex*_*Wex 5

使用selection.on:http://jsfiddle.net/NH6zD/1

var target,
    dimensions = {width: 200, height: 200},
    svg = d3.select("body").append("svg").attr(dimensions),
    rect = svg.append("rect").attr(dimensions); // Must be beneath circles 
svg
  .on("mousedown", function() {
      target = d3.event.target || d3.event.srcElement;
      if ( target === rect.node() ) {
          /* Brush */
      } else {
          /* Circle */
      }
  })
  .on("mousemove", function() {
      if (!target) return;
      if ( target === svg.rect() ) {
          /* Brush */
      } else {
          var mouse = d3.mouse(svg.node());
          target.attr({x: mouse[0], y: mouse[1]});
      }
  });
(function(exit) {
    for (var i in exit) svg.on(exit[i], function() { target = undefined; });
})(["mouseout", "mouseup"]);
Run Code Online (Sandbox Code Playgroud)