使用d3.js为饼图添加工具提示

8

我正在踏上学习使用d3.js可视化数据的旅程,到目前为止,我发现Scott Murray的《交互式数据可视化》非常有帮助。我正在按照书中第11章的示例代码操作,并想知道如何向饼图添加工具提示(书中已经介绍了使用条形图实现此过程的方法)。总之,我已经折腾了几个小时的代码,希望能得到任何人的帮助:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <title>D3: Pie layout</title>
   <script type="text/javascript" src="d3/d3.v3.js"></script>
   <style type="text/css">

            text {
               font-family: sans-serif;
               font-size: 12px;
               fill: white;
            }

            #tooltip {
               position: absolute;
               width: 200px;
               height: auto;
               padding: 10px;
               background-color: white;
               -webkit-border-radius: 10px;
               -moz-border-radius: 10px;
               border-radius: 10px;
               -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
               -mox-box-shadow: 4px 4px 4px 10px rgba(0, 0, 0, 0.4);
               box-shadow: 4px 4px 10px rbga(0, 0, 0, 0.4)
               pointer-events: none;
            }

            #tooltip.hidden {
               display: none;
            }

           #tooltip p {
               margin: 0;
               font-family: sans-serif;
               font-size: 16px;
                        line-height: 20px;
           }
   </style>
</head>

<body>
    <div id="tooltip" class="hidden">
            <p><strong>Important Label Heading</strong></p>
            <p><span id="value">100</span>%</p>
    </div>
    <script type="text/javascript">

        //Width and height
        var w = 300;
        var h = 300;

        var dataset = [ 5, 10, 20, 45, 6, 25 ];

        var outerRadius = w / 2;
        var innerRadius = 0;
        var arc = d3.svg.arc()
                        .innerRadius(innerRadius)
                        .outerRadius(outerRadius);

        var pie = d3.layout.pie();

        // Easy colors accessible via a 10-step ordinal scale
        var color = d3.scale.category10();

        // Create SVG element
        var svg = d3.select("body")
                    .append("svg")
                    .attr("width", w)
                    .attr("height", h);

        // Set up groups
        var arcs = svg.selectAll("g.arc")
                      .data(pie(dataset))
                      .enter()
                      .append("g")
                      .attr("class", "arc")
                      .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")")
                      .on("mouseover", function(d){
                        d3.select("#tooltip")
                          .select("#value")
                          .text(d);

                        d3.select("tooltip").classed("hidden",false);
                      })
                      .on("mouseout", function() {
                        // Hide the tooltip
                        d3.select("#tooltip").classed("hidden", true);
                      });

        // Draw arc paths
        arcs.append("path")
            .attr("fill", function(d, i) {
                 return color(i);
            })
            .attr("d", arc);

        // Labels
        arcs.append("text")
            .attr("transform", function(d) {
                 return "translate(" + arc.centroid(d) + ")";
            })
            .attr("text-anchor", "middle")
            .text(function(d) {
                 return d.value;
            });
    </script>
</body>
</html>

我知道这可能有点难以理解,但我想更具体地了解如何设置工具提示的x和y值。谢谢您提前。

2个回答

16

我更喜欢使用不透明度来显示/隐藏工具提示。这是FIDDLE链接。这应该能帮助你开始。

d3.select("#tooltip")
    .style("left", d3.event.pageX + "px")
    .style("top", d3.event.pageY + "px")
    .style("opacity", 1)
    .select("#value")
    .text(d.value);

1
正是我所需要的,非常感谢。再次查看我的脚本,我还注意到我在CSS部分关闭了指针事件(pointer-events:none)。 - Young Song
谢谢提供这个代码片段 :) 我发现使用不透明度会导致我的应用程序出现一些故障行为 - 当工具提示不可见但仍然定位在图表的某个部分时,它会阻止 mouseover 事件的触发。因此,我更喜欢只使用 .style("display", "block").style("display", "none") - danwild
@Daniel,很有趣。为了参考,我使用了你的方法创建了另一个FIDDLE。谢谢。 - FernOfTheAndes
1
使用这种方法的用户体验并不是很好,当提示框在同一元素上时,它不会随着鼠标移动而移动。 - Ankit Balyan

3
我正在对FernOfTheAndes的解答添加鼠标移动事件,这将使其使用更加美观。希望这对你有所帮助。
.on("mouseover", function(d) {
  d3.select("#tooltip").style('opacity', 1)
    .select("#value").text(d.value);
})
.on("mousemove", function(d) {
  d3.select("#tooltip").style("top", (d3.event.pageY - 10) + "px")
  .style("left", (d3.event.pageX + 10) + "px");
})
.on("mouseout", function() {
  d3.select("#tooltip").style('opacity', 0);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接