【问题标题】:How can a tooltip in D3 fetch data dynamically?D3 中的工具提示如何动态获取数据?
【发布时间】:2015-08-06 05:19:50
【问题描述】:

我们有一些数据

University,Total,Females,Males,Year,Type
PortSaid,13817,6679,7138,2012,Public
PortSaid,14790,7527,7263,2013,Public
PortSaid,17295,8509,8786,2010,Public
6OctoberUniversity,12507,4297,8210,2012,Private
6OctoberUniversity,14608,5360,9248,2013,Private

我尝试创建像 Block 这样的饼图,并附有动态工具提示。 我手动创建一个 HTML 元素

        <p>
            <strong>University is </strong>
            <span id="UniversityName"></span>
        </p>
        <p><span id="NumberStudents"></span> Students</p>

以及创建弧线和工具提示的代码

        svg.selectAll("path")
            .data(pie(data))
          .enter().append("path")
            .each(function(d) { d.outerRadius = outerRadius - 20; })
            .attr("d", arc)
            .on("mouseover", arcTween(outerRadius, 0))
            .on("mouseout", arcTween(outerRadius - 20, 150))
            .on("mouseover", function(d) {
                var xPosition = 100;
                var yPosition = 100;
                d3.select("#tooltip")
                    .data(pie(data))
                      .style("left", xPosition + "px")
                      .style("top", yPosition + "px")
                      .select("#NumberStudents")
                        .text(function(d) { return d.value })
                      .select("#UniversityName")
                        .text(function(d) { return d.value });
                    //Show the tooltip
                d3.select("#tooltip").classed("hidden", false);
                })
            .on("mouseout", function() {

                //Hide the tooltip
                d3.select("#tooltip").classed("hidden", true);          
           })

问题: Tooltip 总是返回 Total 列的第一个值,即 13817。如何根据鼠标悬停的弧线动态显示正确的值?


编辑:在代码 sn-p 和 HTML 工具提示模板中添加了第二个数据点 #UniversityName。

问题 2 正如@minikomi 指出的那样,正确的数据绑定将导致正确获取与每个弧相关的值。但是,似乎每条弧都附加了一个值,正确地是标记为 Total 的值。 然而,这会将每行的其余数据留在哪里,例如 Female、MaleYear?如何将它们也绑定到工具提示?

【问题讨论】:

  • 那只是d3.select("#tooltip").text(d.value);,不是吗?
  • 关于您的编辑:查看我的评论、我对答案的编辑和docs。这些文档非常全面,因此如果您想从块中学习,最好阅读每一行并检查它在另一个选项卡中对文档的作用。
  • @minikomi 我很难将文档与 javascript 的数据模型联系起来,它变得相当混乱。使用控制台猜测/评估任何给定点的数据几乎是无用的(尽管在文档中推荐!)感谢您的帮助,我会给他们一个全新的外观

标签: javascript html d3.js data-visualization


【解决方案1】:

可能值得回顾一下 d3 和 data binding 背后的想法。

这里:

.on("mouseover", function(d) {
            var xPosition = 100;
            var yPosition = 100;
            d3.select("#tooltip")
                .data(pie(data)) // re-bind tooltip with entire data set
                  .style("left", xPosition + "px")
                  .style("top", yPosition + "px")
                  .select("#NumberStudents")
                  .text(function(d) { return d.value });
                //Show the tooltip
            d3.select("#tooltip").classed("hidden", false);
            })

原来的data是一个数组。当您使用.data.enter.each 时,不仅会创建饼图的一个片段,而且每个片段还会绑定一个数据点。

因此,当您告诉段对鼠标悬停事件作出反应时,回调函数的d 参数将由 d3 设置为该段的绑定数据点。

相比之下,在上面的代码中,在选择#tooltip 元素后,会调用.data(pie(data)) - 每次鼠标悬停时都会将整个数据集 绑定到工具提示 - 并且是您观察到的意外行为的原因。

改为使用单个数据项(此处为函数内的 d)及其值来设置工具提示的文本:

 .on("mouseover", function(d) {
            // d = the single data point used 
            //     to create the segment here
            var xPosition = 100;
            var yPosition = 100;
            d3.select("#tooltip")
                .style("left", xPosition + "px")
                .style("top", yPosition + "px")
                .select("#NumberStudents")
                  .text(d.value);

            d3.select("#tooltip").classed("hidden", false);
            })

要访问其他值(与用于创建饼图切片的值不同),请检查docs 以获取饼图布局。原始数据将在 d 的 .data 属性中。因此,例如,假设您的工具提示有 #SchoolType &lt;span&gt;,那么您可以设置 Type 属性中的文本,例如:

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

            var xPosition = 100;
            var yPosition = 100;
            d3.select("#tooltip")
                .style("left", xPosition + "px")
                .style("top", yPosition + "px")
                .select("#NumberStudents")
                  .text(d.value)

            //d.data will hold the original data map
            d3.select("#tooltip #SchoolType").text(d.data["Type"]);

            d3.select("#tooltip").classed("hidden", false);
            })

【讨论】:

  • 这行得通,但我仍然不完全理解。似乎 .data(pie(data)) 创建了一个弧数组,每个弧都附加了 Total 值。但是,与数据相关的其余数据,即女性、男性、年份等(这需要一个对象)缺失。我无法参考它们以获得完整的工具提示。问题:如何在每行 cvs 数据中引用第二个数据点?这甚至可能吗?
  • 检查docs 的饼图布局。原始数据将在 d 的.data 属性中。因此,例如,您可以说 d.data["Females"] 并获取女性值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-15
  • 2013-07-25
  • 2017-11-20
  • 1970-01-01
  • 2016-06-08
  • 2012-12-21
  • 1970-01-01
相关资源
最近更新 更多