javascript 创建后获取 d3.js SVG 文本元素的宽度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21486622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 21:01:17  来源:igfitidea点击:

Get width of d3.js SVG text element after it's created

javascriptsvgd3.js

提问by sanjaypoyzer

I'm trying to get the widths of a bunch of textelements I have created with d3.js

我正在尝试获取text我用 d3.js 创建的一堆元素的宽度

This is how I'm creating them:

这就是我创建它们的方式:

var nodesText = svg.selectAll("text")
           .data(dataset)
           .enter()
           .append("text")
           .text(function(d) {
                return d.name;
           })
          .attr("x", function(d, i) {
                return i * (w / dataset.length);
           })
          .attr("y", function(d) {
                return 45;
          });

I'm then using the width to create rectanglesthe same size as the text's boxes

然后我使用宽度来创建rectanglestext's 框相同的大小

var nodes = svg.selectAll("rect")
            .data(dataset)
            .enter()
            .append("rect")
            .attr("x", function(d, i) {
                return i * (w / dataset.length);
            })
            .attr("y", function(d) {
                return 25;
            })
            .attr("width", function(d, i) {
              //To Do: find width of each text element, after it has been generated
              var textWidth = svg.selectAll("text")
                  .each(function () {
                      return d3.select(this.getComputedTextLength());
                  });
                console.log(textWidth);
                return textWidth;
            })
            .attr("height", function(d) {
                return 30;
            })

I tried using the Bbox method from herebut I don't really understand it. I think selecting the actual element is where I'm going wrong really.

我尝试使用这里的 Bbox 方法,但我不太明白。我认为选择实际元素是我真正出错的地方。

回答by Lars Kotthoff

I would make the length part of the original data:

我会制作原始数据的长度部分:

var nodesText = svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text(function(d) {
            return d.name;
       })
      .attr("x", function(d, i) {
            return i * (w / dataset.length);
       })
      .attr("y", function(d) {
            return 45;
      })
      .each(function(d) {
        d.width = this.getBBox().width;
      });

and then later

然后后来

var nodes = svg.selectAll("rect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("width", function(d) { return d.width; });

回答by Liran Brimer

You can use getBoundingClientRect()

您可以使用 getBoundingClientRect()

Example:

例子:

.style('top', function (d) {
     var currElemHeight = this.getBoundingClientRect().height;
}

edit: seems like its more appropriate for HTML elements. for SVG elements you can use getBBbox()instead.

编辑:似乎它更适合 HTML 元素。对于 SVG 元素,您可以使用getBBbox()代替。

回答by M. Davis

d3.selectAllreturns a selection. You can get each of the elementsby navigating through the array in the _groupsproperty. When you are determining the width of a rectangle, you can use its index to get the corresponding text element:

d3.selectAll返回一个选择。您可以通过浏览属性中的数组来获取每个元素_groups。在确定矩形的宽度时,可以使用其索引来获取相应的文本元素:

.attr('width', function (d, i) {
    var textSelection = d3.selectAll('text');
    return textSelection._groups[0][i].getComputedTextLength();
});

The _groupsproperty of d3's selection has a list of nodes at [0]. This list contains all of the selected elements, which you can access by index. It's important that you get the SVG elementso that you can use the getComputedTextLengthmethod.

_groupsD3的选择的酒店在节点列表[0]。此列表包含所有选定元素,您可以通过索引访问这些元素。获取 SVG元素很重要,这样您就可以使用该getComputedTextLength方法。

You may also want to consider creating the rectelements first, then the textelements, and then going back to the rectangles to edit the widthattribute, so that the textelements are on top of the rectangles (in case you want to fill the rectangles with color).

您可能还需要考虑先创建rect元素,然后是text元素,然后返回到矩形以编辑width属性,以便text元素位于矩形的顶部(以防您想用颜色填充矩形)。

Update:

更新:

It's typically preferred that you don't access _groups, though, so a safer way to get the matching text element's width would be:

但是,通常最好不要访问_groups,因此获取匹配文本元素宽度的更安全方法是:

.attr('width', function (d, i) {
    return d3.selectAll('text').filter(function (d, j) { return i === j; })
        .node().getComputedTextLength(); 
});

Using nodesafely retrieves the element, and filter will find the text element which matches index.

使用node安全检索元素,过滤器将找到与索引匹配的文本元素。