在没有嵌套的情况下在d3中附加标签

时间:2018-04-30 05:23:12

标签: javascript html css d3.js

我想生成html,其中包含每个<p>标记的工具提示和工具提示文本。我知道我可以在d3中完成所有工具提示,但我现在使用的是CSS风格,因为它更熟悉。

在理想的世界中,我的html 输出看起来像

<p class="tooltip" style="font-size: 73.6207pt;">eyes.
  <span class="tooltiptext">Tooltip text</span>
</p>
<br>
<p class="tooltip" style="font-size: 73.6207pt;">eyes.
  <span class="tooltiptext">filler text</span>
</p>

我使用的是<br>,因为p标记中的文字显示在同一行,但我遇到的问题是<br>嵌套在范围内标签,所以我的html输出看起来像这样。

<p class="tooltip" style="font-size: 73.6207pt;">eyes.
  <span class="tooltiptext">Tooltip text <br></span>
</p>
<p class="tooltip" style="font-size: 73.6207pt;">eyes.
  <span class="tooltiptext">filler text <br></span>
</p>

我的d3看起来像这样:

我已经尝试移动.append("d3"),但它要么打破了工具提示,要么只是弄乱整个可视化。

div.selectAll(null)
  .data(myData)
  .enter()
  .append("p")
  .attr("class", "tooltip")
  .text(function(d) {
     return d.word;
  })
  .style("font-size", function(d) {
     return scale(parseInt(d.score))  + "pt";
  })
  .append('span')
  .attr("class", "tooltiptext")
  .text("filler text")
  .append("br")

提前感谢你帮忙

1 个答案:

答案 0 :(得分:1)

d3&#39; s .insert()(同时出现在v3v4+选择API中)只插入一次元素,因此当您拥有超过一个元素时,它可能不会太有用两个<p>元素。您可以做的是简单地遍历所有<p>节点并使用本机JS Element.insertBefore()方法执行您想要的操作:在每个{之后插入<br /> {1}}元素。

在这种情况下,我们根本不会为第一个遇到的<p>元素调用insertBefore(),而是随后为所有其他元素调用。

<p>

见下面的概念验证:

&#13;
&#13;
var paragraphs = div.selectAll(null)
  .data(myData)
  .enter()
  .append("p")
  .attr("class", "tooltip")
  .text(function(d) {
     return d.word;
  })

paragraphs.append('span')
  .attr("class", "tooltiptext")
  .text("filler text");

// Iterate through all inserted paragraphs
paragraphs.each(function(d, i) {

  // Do not insert if first `<p>` is encountered
  if (i === 0)
    return;

  this.parentNode.insertBefore(document.createElement('br'), this);
});
&#13;
var div = d3.select('div');
var myData = [{
  word: 'Lorem ipsum dolor sit amet'
}, {
  word: 'Consectetur adipiscing elit'
}, {
  word: 'Nam id sollicitudin magna'
}, {
  word: 'Pharetra rutrum nisl'
}];

var paragraphs = div.selectAll(null)
  .data(myData)
  .enter()
  .append("p")
  .attr("class", "tooltip")
  .text(function(d) {
     return d.word;
  })

paragraphs.append('span')
  .attr("class", "tooltiptext")
  .text("filler text");

// Iterate through all inserted paragraphs
paragraphs.each(function(d, i) {

  // Do not insert if first `<p>` is encountered
  if (i === 0)
    return;
    
  this.parentNode.insertBefore(document.createElement('br'), this);
});
&#13;
&#13;
&#13;