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

时间:2014-01-31 17:43:47

标签: javascript svg d3.js

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

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

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;
          });

然后我使用宽度创建rectanglestext框相同的尺寸

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;
            })

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

3 个答案:

答案 0 :(得分:11)

我会将长度作为原始数据的一部分:

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;
      });

然后再

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

答案 1 :(得分:4)

您可以使用getBoundingClientRect()

示例:

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

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

答案 2 :(得分:0)

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

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

d3选择的_groups属性在[0]处有一个节点列表。此列表包含您可以通过索引访问的所有元素。获取SVG 元素非常重要,这样您才能使用getComputedTextLength方法。

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

<强>更新

但是,您通常不会访问text,因此获得匹配文本元素宽度的更安全方法是:

_groups

使用.attr('width', function (d, i) { return d3.selectAll('text').filter(function (d, j) { return i === j; }) .node().getComputedTextLength(); }); 安全地检索元素,过滤器将找到与index匹配的文本元素。