使用捕捉行为将鼠标单击处理程序分配到d3中的行

时间:2017-05-29 18:53:12

标签: javascript events d3.js mouse

我的d3线只有一个像素宽。我希望点击一下 分配给此行的处理程序。但是,在尝试选择它时,很难完全处于最佳状态。是否有一些“选择走廊”功能可让您指定“距离线”。即如果鼠标指针在距离线最大8pt的距离并且单击鼠标时触发click事件?

2 个答案:

答案 0 :(得分:2)

other answer中的解决方案是一个很好的解决方案,也是一个有趣的解决方案。

但是,我更喜欢"传统"解决方案,绘制另一条线,透明且比可见细线更粗,只是为了捕捉click事件。我之所以喜欢这个"传统"解决方案(D3编码器中最常见的一个)是用户体验:让用户知道她/他可以点击该线路是一个好主意。

因此,在细线,可见线上有一条更粗,更透明的线的优点是你可以将光标设置为一只手...

.attr("cursor", "pointer")

...当用户将鼠标悬停在透明线上时。

这是一个简单的演示:



var svg = d3.select("svg");
var data = d3.range(30).map(function(d) {
  return {
    x: d * 10,
    y: Math.random() * 150
  }
});
var lineGenerator = d3.line()
  .x(function(d) {
    return d.x
  })
  .y(function(d) {
    return d.y
  });

var realLine = svg.append("path")
  .attr("stroke", "teal")
  .attr("fill", "none")
  .attr("stroke-width", 1)
  .attr("d", lineGenerator(data));

var transparentLine = svg.append("path")
  .attr("stroke", "teal")
  .attr("fill", "none")
  .attr("stroke-width", 12)
  .attr("opacity", 0)
  .attr("cursor", "pointer")
  .attr("d", lineGenerator(data));

transparentLine.on("click", function() {
  console.log("clicked")
})

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
&#13;
&#13;

当然,这&#34;传统&#34;解决方案只有在该图表上有一行或几行时才有意义。如果你有数十或数百行,那将是一个完整的混乱。

答案 1 :(得分:1)

您可以攻击svg / group元素上的click事件,并检查鼠标位置与路径上最近点的距离是否小于某个固定值,例如: 4.可以使用Closest Point on Path example中的函数计算距离。

点击活动:

var path = svg.append('path').datum(data).attr("d", line);
svg.on('click', function() {
  var m = d3.mouse(this),
    p = closestPoint(path.node(), m);

  if (p.distance < 4) {
    /* make action */
    console.log('click', p.distance)
  }
})

closestPoint()取自上面的示例。

示例:https://jsfiddle.net/xny9bx4v/