首页 > 解决方案 > 无法将工具提示添加到我的 d3 树节点

问题描述

我正在尝试将鼠标悬停工具提示添加到 d3 v4 树中的节点。我在这里关注这个 d3 v3 示例:http: //bl.ocks.org/jebeck/10699411

我在那个例子中看到了这段代码:

.on('mouseover', function() {
                    var fo = svg.append('foreignObject')
                        .attr({
                            'x': anchor.w - tip.w,
                            'y': anchor.h + tip.h,
                            'width': foWidth,
                            'class': 'svg-tooltip'
                        });
                    var div = fo.append('xhtml:div')
                        .append('div')
                        .attr({
                            'class': 'tooltip'
                        });
   ...

我相信我在我的代码中做同样的事情:

      .on('mouseover', function (d) {
        var foHeight = 100;
        var foWidth = 100;
        var t = 50, k = 15;
        var tip = {'w': (3/4 * t), 'h': k};
        var anchor = {'w': 100/3, 'h': 100/3};

        var fo = svg.append('foreignObject')
          .attr('x', 0)
          .attr('y', 0)
          .attr('width', this.rect_width)
          .attr('height', this.rect_height)
          .attr('class', 'svg-tooltip');

        var div = fo.append('xhtml:div')
           .append('div')
           .attr({'class': 'tooltip'});
   ...

但在我的代码中divnull. 我很确定这是因为这.attr({'class': 'tooltip'})条线,但我不明白为什么添加这条线.attr({'class': 'tooltip'})div导致null. 如果我删除该行.attr({'class': 'tooltip'}),div不为空,但当我将鼠标悬停在节点上时我的工具提示不会显示。

我的css文件中有这个:

.d3-chart {
  width: 100%;
  min-height:600px;
}

.wordwrap {
  white-space: pre-wrap; /* CSS3 */
  white-space: -moz-pre-wrap; /* Firefox */
  white-space: -pre-wrap; /* Opera <7 */
  white-space: -o-pre-wrap; /* Opera 7 */
  word-wrap: break-word; /* IE */
}

.svg-tooltip {
  pointer-events: none;
}

.tooltip {
  padding: 10px;
  color: #4A22FF;
}

标签: javascriptd3.js

解决方案


该引用使用 d3v3,它允许将对象传递给.attr().style()表示多个(或在这种情况下为单个)属性或样式。

selection.attr("property","value")

相当于:

selection.attr({property:"value"})

自 d3v4 以来(包括 d3v4),只有第一个选项有效。

正如在 v3 中看到的:

d3.select("body")
  .append("p")
  .attr("class","underline")
  .text("Underlined");

d3.select("body")
  .append("p")
  .attr({"class":"underline"})
  .text("Underlined too");
  
d3.select("body")
  .append("p")
  .attr({"class":"underline","style":"color:blue"})
  .text("Underlined and blue");
  
// Classes can also be assigned 
d3.select("body")
  .append("p")
  .attr({"class":"underline"})
  .classed("small",true)  // with selection.classed
  .text("Underlined and small");
.underline {
  text-decoration: underline;
}
.small {
  font-size: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

从 d3v4 开始,selection.attr()不再selection.style()接受对象(如果使用 d3-multi-selection,.attrs() 和 .styles() 可以

在这里看到:

d3.select("body")
  .append("p")
  .attr("class","underline")
  .text("Underlined");
  
d3.select("body")
  .append("p")
  .classed("underline",true)
  .text("Underlined");  
  
d3.select("body")
  .append("p")
  .attr({"class":"underline"})
  .text("Underlined");
.underline {
  text-decoration: underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>

您的工具提示可以通过以下方式获得所需的类,而不是使用对象来分配类:

div.classed("tooltip",true)
div.attr("class","tooltip") // will remove previously assigned classes

如果selection.attr({property:"value"})与 d3v4 一起使用,这会导致错误,并且不会触发任何链接到它的内容,因此 div 的 html 将为空 - 您永远不会执行填充 div 的代码。


推荐阅读