让父母的孩子找到父母的孩子文字宽度

时间:2018-01-11 21:03:52

标签: javascript d3.js

我需要获取文本的宽度才能计算作为背景的rect的宽度。我不知道如何遍历父母" nodeGroup"然后获取子文本宽度,希望得到一些帮助。下面的伪代码。

代码用于尝试获取宽度(不起作用)

nodeGroups.selectAll('rect')
    .attr("width", function(d) {      
      let width = this.parentNode.select('text').getComputedTextLength; //??     
      console.log(width);
      return width;
    })

错误: this.parentNode.select不是函数

以下是nodeGroup的基本结构:

  <g class="nodeGroup">
      <circle class="node" r="15" fill="#67b14f" cx="163.66683334043782" cy="25.26573226107303">
      </circle>
      <rect fill="#676767" text-anchor="middle" class="labelBack" height="20" x="179.66683334043782" y="15.26573226107303">
      </rect>
      <text class="label" x="187.66683334043782" y="29.26573226107303">
        GET MY WIDTH <--- ?????
      </text>
  </g>

1 个答案:

答案 0 :(得分:3)

您可能希望按照评论中的建议使用bbox方法。

parentNode返回DOM元素,而不是D3选择,所以

this.parentNode.select('text')

无法工作,您需要使用:

d3.select(this.parentNode)

然后,您可以选择文本元素,并从DOM元素本身获取其bbox(而不是d3选择):

d3.select(this.parentNode).select(text).node().getBBox();

然后从那里你可以得到bbox.width的宽度。当然,您不需要在中间步骤中使用d3选项,但是当您开始沿着这条道路前进时,我会继续使用它来获取下面的第一个片段:

&#13;
&#13;
var data = ["Short String","A Longer String"];

var svg = d3.select("body")
  .append("svg");
  
var g = svg.selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .attr("transform",function(d,i) { 
     return "translate("+[20,i*20+20]+")";
  });
  
g.append("rect")
  .attr("height", 20)
  .attr("fill","yellow");
  
g.append("text")
 .text(function(d) { return d; })
 .attr("y", 18);

g.selectAll("rect")
  .attr("width",function() {
     let parentSelection = d3.select(this.parentNode)
     
     let bbox = parentSelection.select("text").node().getBBox();
  
     let width = bbox.width;
     
     return width;
  })
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
&#13;
&#13;

更好的方法

但是,如果没有d3用于中间步骤,事情会变得更容易(也更快)。如果您的矩形是文本前最近的兄弟,那么您可以使用nextSibling(因为this指的是矩形,下一个元素是文本):

&#13;
&#13;
var data = ["Short String","A Longer String"];

var svg = d3.select("body")
  .append("svg");
  
var g = svg.selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .attr("transform",function(d,i) { 
     return "translate("+[20,i*20+20]+")";
  });
  
g.append("rect")
  .attr("height", 20)
  .attr("fill","yellow");
  
g.append("text")
 .text(function(d) { return d; })
 .attr("y", 18);

g.selectAll("rect")
  .attr("width",function() {
     return this.nextSibling.getBBox().width;
  })
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
&#13;
&#13;