D3.js获取鼠标悬停事件

时间:2017-05-02 18:55:01

标签: d3.js

我试图在鼠标悬停时访问形状的数据索引,以便我可以根据索引控制形状的行为。

假设这个代码块基于某些数据在垂直行中列出5 rect。

var g_box = svg
      .selectAll("g")
      .data(controls)
      .enter()
      .append("g")
      .attr("transform", function (d,i){
        return "translate("+(width - 100)+","+((controlBoxSize+5)+i*(controlBoxSize+ 5))+")"
      })
      .attr("class", "controls");

    g_box
      .append("rect")
      .attr("class", "control")
      .attr("width", 15)
      .attr("height", 15)
      .style("stroke", "black")
      .style("fill", "#b8b9bc");

当我们将鼠标移到rect 3时,它会转换为double size。

g_box.selectAll("rect")
  .on("mouseover", function(d){
      d3.select(this)
        .transition()
        .attr("width", controlBoxSize*2)
        .attr("height", controlBoxSize*2);
      var additionalOffset = controlBoxSize*2;
      g_box
        .attr("transform", function (d,i){
          if( i > this.index) {       // want to do something like this, what to use for "this.index"?
          return "translate("+(width - 100)+","+((controlBoxSize+5)+i*(controlBoxSize+5)+additionalOffset)+")"
          } else {
          return "translate("+(width - 100)+","+((controlBoxSize+5)+i*(controlBoxSize+5))+")"
          }
        })
    })

我想要做的是在鼠标悬停时移动rect 4和5,这样它们就会滑开并且不会与正在扩展的rect 3重叠。

那么有没有办法在我的mouseover事件中检测“this”rect的数据索引“i”,以便我可以实现一些逻辑来相应地调整另一个rect的translate()?

2 个答案:

答案 0 :(得分:1)

我非常确定d3会传入索引以及事件侦听器中的数据。

所以试试

.on("mouseover", function(d,i)

其中i是索引。

另外,你可以看看我几个月前制作的小提琴,这与你提出的问题有关。

https://jsfiddle.net/guanzo/h1hdet8d/1/

答案 1 :(得分:1)

您可以使用匿名函数的第二个参数轻松获取任何选择的索引。

然而,这里的问题是你试图在一个匿名函数中获取索引,而这个函数本身就在事件处理程序中,这不会起作用。

因此,在事件处理程序中获取索引......

selection.on("mouseover", function(d, i) {
    //index here ---------------------^

...并且,在内部匿名函数中,使用不同的参数名称再次获取索引,比较它们:

innerSelection.attr("transform", function(e, j) {
    //index here, with a different name -----^

这是一个简单的演示(充满幻数),只是为了告诉你如何做到这一点:



var svg = d3.select("svg");

var data = d3.range(5);

var groups = svg.selectAll("foo")
  .data(data)
  .enter()
  .append("g");

var rects = groups.append("rect")
  .attr("y", 10)
  .attr("x", function(d) {
    return 10 + d * 20
  })
  .attr("width", 10)
  .attr("height", 100)
  .attr("fill", "teal");

groups.on("mouseover", function(d, i) {
  d3.select(this).select("rect").transition()
    .attr("width", 50);

  groups.transition()
    .attr("transform", function(e, j) {
      if (i < j) {
        return "translate(40,0)"
      }
    })
}).on("mouseout", function() {
  groups.transition().attr("transform", "translate(0,0)");
  rects.transition().attr("width", 10);
})
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
&#13;
&#13;

PS:不要......

g_box.selectAll("rect").on("mouseover", function(d, i){

...因为你没有获得正确的索引(解释your comment)。而不是那样,将事件附加到组,并在其中获取矩形。