D3 JS将工具提示附加到每个数据圆点并在svg元素的悬停事件中查找

时间:2016-06-06 10:02:35

标签: d3.js

我有一个对象数组。这些对象包含一组名为" x"的属性。和" y"。现在,当我遍历数组时,我将每个对象的圆附加到数组中,将这些坐标作为圆的中心。我正在尝试在每个圆的鼠标悬停上附加工具提示,显示圆的x和y坐标。 我面临的两个问题是 1.如何在每个圆圈中附加div元素 2.如何获得圈子的悬停事件? 请帮帮忙?

   <!doctype html>
    <html>
      <head>
        <title>D3 Basics</title>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
      </head>
      <body>
        <script>
          var data=[
            {"x":"100","y":"20"},
            {"x":"102","y":"22"},
            {"x":"200","y":"30"},
            {"x":"500","y":"40"},
            {"x":"500","y":"30"}
          ];

          var svgHeight=800;
          var svgWidth=800;
          var margin=50;

          var divelement=d3.select("body")
            .append("div")
            .attr("height",svgHeight)
            .attr("width",svgWidth)
            .attr("style","border:1px solid black;");

          var svgElement=divelement.append("svg")
            .attr("height",svgHeight)
            .attr("width",svgWidth);

          var boxGroupElement=svgElement.append("g")
            .attr("transform","translate("+margin+","+margin+")");


          //appending data circle points        
          for (var a=0; a<data.length; a++) {
           boxGroupElement.append("circle")
              .attr("cx",data[a].x)
              .attr("cy",data[a].y)
              .attr("r","3")
              .attr("fill","yellow")
              .attr("stroke","blue");
          }         
        </script>
      </body>
    </html>

2 个答案:

答案 0 :(得分:1)

我已将此标记为重复,但可以在此处学习。

您在创建圈子的位置:

for (var a=0; a<data.length; a++) {
           boxGroupElement.append("circle")
              .attr("cx",data[a].x)
              .attr("cy",data[a].y)
              .attr("r","3")
              .attr("fill","yellow")
              .attr("stroke","blue");
          } 

如果您使用D3,这是完全错误的。如果您将鼠标悬停事件放在此上,就像通常使用D3控制台记录数据一样:

.on('mouseover',function(d){ console.log(d);});

这不起作用,因为您的选择中没有附加数据。解决方法如下:

 var circles = boxGroupElement.selectAll('circle')
   .data(data)
   .enter()
   .append('circle')
   .attr("cx", function(d) {
     return d.x
   })
   .attr("cy", function(d) {
     return d.y
   })
   .attr("r", "3")
   .attr("fill", "yellow")
   .attr("stroke", "blue")

现在提供工具提示。我在上面引用了这个:Show data on mouseover of circle

第二个答案正是如此。以下是它的工作原理:

为工具提示添加一个div来设置隐藏的可见性(因此它可以在鼠标悬停时显示):

 var tooltip = d3.select("body")
   .append("div")
   .style("position", "absolute")
   .style("z-index", "10")
   .style("visibility", "hidden")
   .text("a simple tooltip");

在鼠标悬停时节点显示数据。我在这里展示了这个职位。请记住,如果您坚持使用创建圆圈的原始方式,这种方式将无效,因为您无法找到数据:

.on("mouseover", function(d) {
     tooltip.text("Pos : " + d.x + ' : ' + d.y);

     return tooltip.style("visibility", "visible");
   })
   .on("mousemove", function() {
     return tooltip.style("top",
       (d3.event.pageY - 10) + "px").style("left", (d3.event.pageX + 10) + "px");
   })
   .on("mouseout", function() {
     return tooltip.style("visibility", "hidden");
   });

工作小提琴:https://jsfiddle.net/thatOneGuy/7qt1aoan/2/

编辑

如果你是坚定的,你想保持它,就像你有以下可能是一个解决方法:

 .on("mouseover", function(d, i) {
       tooltip.text("Pos : " + data[i].x + ' : ' + data[i].y);

       return tooltip.style("visibility", "visible");
     })
     .on("mousemove", function() {
       return tooltip.style("top",
         (d3.event.pageY - 10) + "px").style("left", (d3.event.pageX + 10) + "px");
     })
     .on("mouseout", function() {
       return tooltip.style("visibility", "hidden");
     });

此解决方法的更新小提琴:https://jsfiddle.net/thatOneGuy/7qt1aoan/3/

再次在鼠标悬停时,您无法使用data[a].x,因为这将始终返回数据,闭包等的最后一个元素,因此我使用data[i].x为您提供当前正在圈选的圈子结束:))

答案 1 :(得分:-1)

您需要将鼠标悬停事件添加到boxGroupElement.append("circle")这样的内容

boxGroupElement.append("circle")
                  .attr("cx",data[a].x)
                  .attr("cy",data[a].y)
                  .attr("r","3")
                  .attr("fill","yellow")
                  .attr("stroke","blue").on("mouseover", function(d) {
                    div.transition().duration(100).style("opacity", .9);
                    div.html("My Tooltip" + "<br/>" +d )
                    .style("left", (d3.event.pageX) + "px")
                    .style("top",(d3.event.pageY - 28) + "px")
                   .attr('r', 8);
                   d3.select(this).attr('r', 8)})
                  .on("mouseout", function(d) {
                   div.transition().duration(600).style("opacity", 0)
                   d3.select(this).attr('r', 3);
                   });

这是一个有效的example