尝试使用d3只在鼠标悬停时显示一个工具提示

时间:2016-01-28 15:35:02

标签: d3.js

我正在尝试使用我的d3代码处理一些工具提示。我简化了这段代码,如下所示。

目前,代码会生成6个带有与之关联的名称的移动圆圈,并且console.log显示当我将鼠标悬停在每个圆圈上时,会记录其关联的名称。

此外,当我将鼠标悬停在圆圈上时,名称标签会显示在圆圈附近。但是,标签显示在圈子的所有上方,我只希望标签显示在光标悬停的圆圈上。

我对添加鼠标或其他任何东西都不感兴趣,只是希望得到它以便只有悬停在圆圈上才会显示标签。关于如何做到这一点的任何建议?

以下是我的代码目前的样子:

<!DOCTYPE html>
<meta charset="utf-8">

<body>

<script src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">

var names = ["Jack","Anne","Jacob","Mary","Michael","Lisa"];

var width = 960,
    height = 500;

var n = names.length,
    m = 12,
    degrees = 180 / Math.PI;

var bubbles = d3.range(n).map(function() {
  var x = Math.random() * width,
      y = Math.random() * height;
  return {
    vx: Math.random() * 2 - 1,
    vy: Math.random() * 2 - 1,
    path: d3.range(m).map(function() { return [x, y]; }),
    count: 0
  };
});

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var g = svg.selectAll("g")
    .data(bubbles)
  .enter().append("g")
  .on("mouseover", function(d,i){console.log(names[i])}); 

  var labels = g.selectAll("text")
        .data(bubbles)
        .enter().append("text")
        .attr("dy",".35em")
        .attr("class", "tooltip")
        .style("visibility", "hidden")
        .text(function(d,i){return names[i]})

var head = g.selectAll("circle")
    .data(bubbles)
    .enter().append("circle")
    .attr("r", 6)
    .on("mouseover", function(d,i) {
                labels.style("visibility","visible")
                          })

d3.timer(function() {
  for (var i = -1; ++i < n;) {
    var bubble = bubbles[i],
        path = bubble.path,
        dx = bubble.vx,
        dy = bubble.vy,
        x = path[0][0] += dx,
        y = path[0][1] += dy,
        speed = Math.sqrt(dx * dx + dy * dy),
        count = speed * 10,
        k1 = -5 - speed / 3;

    if (x < 0 || x > width) bubble.vx *= -1;
    if (y < 0 || y > height) bubble.vy *= -1;

      for (var j = 0; ++j < m;) {
      var vx = x - path[j][0],
          vy = y - path[j][1],
          k2 = Math.sin(((bubble.count += count) + j * 3) / 300) / speed;
      path[j][0] = (x += dx / speed * k1) - dy * k2;
      path[j][1] = (y += dy / speed * k1) + dx * k2;
      speed = Math.sqrt((dx = vx) * dx + (dy = vy) * dy);
    }
  }

  labels.attr("transform", labelsTransform);
  head.attr("transform", headTransform);
});

function headTransform(d) {
  return "translate(" + d.path[0] + ")rotate(" + Math.atan2(d.vy, d.vx) * degrees + ")";
}

function labelsTransform(d) {
  return "translate(" + d.path[0]  + ")translate(10)";
}

</script>
<body>

</html>

这是我关于Stack Overflow的第一个问题,很抱歉,如果我的问题格式错误或呈现的话!任何帮助都会非常感激,即使它是关于如何更好地提出我的问题!

1 个答案:

答案 0 :(得分:0)

欢迎使用Stack Overflow! :)

您遇到的问题可以追溯到此部分代码:

var head = g.selectAll("circle")
    .data(bubbles)
    .enter().append("circle")
    .attr("r", 6)
    .on("mouseover", function(d,i) {
         labels.style("visibility","visible")
    })

这说明当用户mouseover 任何圈子时,让所有标签可见。你可能想要这样的东西

    .on("mouseover", function(d,i) {
         // only make visible the current mouseover-ed point
         labels.filter(function(p){
            if(p === d) d3.select(this).style("visibility","visible");
            else d3.select(this).style("visibility","hidden");
         });
    })