如何将文本附加到D3工具提示?

问题描述 投票:2回答:2

我在向D3工具提示附加文本时遇到问题。生成工具提示的代码会导致以下错误:

Uncaught TypeError: Cannot read property 'Name' of undefined

工具提示显示,但没有任何文本。以下代码用于生成工具提示:

1.Code创建.toolTip的地方

.toolTip {
position: absolute;
display: none;
min-width: 80px;
height: auto;
background: none repeat scroll 0 0 #ffffff;
border: 1px solid #6F257F;
padding: 14px;
text-align: center;

2.Code创建变量的位置。

 var tooltip = d3.select("body")
                .append("div")
                .attr("class", "toolTip");
  1. 尝试附加到节点的代码 // Nodes d3.select('svg g.nodes') .selectAll('circle.node') .data(root.descendants()) .enter() .append('circle') .classed('node', true) .attr('cx', function(d) {return d.x;}) .attr('cy', function(d) {return d.y;}) .attr('r', 4) .on("mousemove", function(d){ tooltip .style("left", d3.event.pageX - 50 +"px") .style("top", d3.event.pageY - 70 + "px") .style("display", "inline-block") .html(function (d) {return d.Name}); }) .on("mouseout", function(d){ tooltip.style("display", "none");});
d3.js tooltip
2个回答
2
投票

我们来看一下在mousemove上调用的函数:

.on("mousemove", function(d){
   tooltip
    .style("left", d3.event.pageX - 50 +"px")
    .style("top", d3.event.pageY - 70 + "px")
    .style("display", "inline-block")
    .html(function (d) {return d.Name});
})

在第一行中,函数中的d指的是绑定到svg圆的基准,而在这里:.html(function(d) {d指的是绑定到工具提示的基准面。在这种情况下,两个ds不指同一件事。你没有绑定到工具提示的任何数据,所以这不起作用 - 这里的d是未定义的,因此你的错误信息:“无法读取未定义的属性'名称'。”

相反,只需使用圆的基准:

.on("mousemove", function(d){
   tooltip
    .style("left", d3.event.pageX - 50 +"px")
    .style("top", d3.event.pageY - 70 + "px")
    .style("display", "inline-block")
    .html(d.Name); 
})

每当您在d3选择的.html.attr方法中看到函数(d)时,您将访问当前选择的每个元素的数据。您不希望数据与工具提示相关联,因此您不需要在function(d)方法中使用.html(),您已经在第一行中访问了所需的数据。


看起来好像您正在使用d3分层布局。如果您从以下表单开始,这将改变您的数据结构:

 var data = { "name": "Parent", "children": [ 
    { "name": "Child A", "children": [ { "name": "Grandchild" } ] }, 
    { "name": "Child B", } 
    ] };

d3.hierarchy(data)将返回一个具有以下结构的数组:

[
 {data: Object, height: number, depth: number, parent: null, children: array[number], x: number, y: number},
 {data: Object, height: number, depth: number, parent: object, children: array[number], x: number, y: number},
  ... and so forth.
]

这样,数据数组中有一个元素用于要追加的每个节点(selection.data()需要一个数组),并且传递给选择的数据中的每个项都有一些允许它的属性。正确定位,连接等。关键点在于数据数组中的原始元素现在位于d.data。这与d3.pie或其他布局生成器相同 - 并且避免了属性名称之间的潜在重叠(原始属性与布局创建的属性之间)。

对你而言,主要结果是你的名字不会驻留在d.Name,而是d.data.Name,因为这是由d3.hierarchy()创建的数据结构。


0
投票

这是因为您没有任何与工具提示相关的数据。你的代码必须是这样的:

var t = d3.select("body")
                .selectAll("div")
                .data(<your data>)
                .enter()
                .append("div")
                .attr("class", "toolTip");

现在你的div附加了数据来迭代。

© www.soinside.com 2019 - 2024. All rights reserved.