用文本d3js中的换行符替换space

Replace space with new line charcter in texts d3js

我有一个脚本,可以通过以下方式制作 txt:

texts = svg.selectAll(null)
      .data(data)
      .enter()
      .append('text')
      .attr("text-anchor", "middle")
      .text(function(d) {
        return d.abbreviation;
      })
      .attr("pointer-events", "none")
      .attr("font-family", "sans-serif")
      .attr("font-size", "10px")
      .attr("fill", "black");

    texts.each(function(d) {
        console.log(this.getComputedTextLength());
        d.size = this.getComputedTextLength() / 2 ;
    });

    simulation.nodes(data).on("tick", function() {
        circles.attr("cx", function(d) {
                return d.x = Math.max(20, Math.min(width - 20, d.x));
            })
            .attr("cy", function(d) {
                return d.y = Math.max(20, Math.min(height - 20, d.y));
            })
        texts.attr("x", function(d) {
                return d.x;
            })
            .attr("y", function(d) {
                return d.y;
            });
    });

我在数据中使用 属性 缩写将文本放在气泡上,但我想用换行符替换输入中的所有空格。

我尝试了一些解决方案,例如 link:How to linebreak an svg text in javascript? 但是所有文本都转到最左角,或者如果我从中删除 .attr("x", 0) 属性 ,则文本的对齐方式不正确。见下图:

"State" 应该直接在 "Iowa"

下面

更新的脚本:

 texts = svg.selectAll(null)
      .data(data)
      .enter()
      .append('text')
      .attr("text-anchor", "middle")
      .each(function (d) {
         var arr = d.abbreviation.split(" ");
         for (i = 0; i < arr.length; i++) {
         d3.select(this).append("tspan")
        .text(arr[i])
        .attr("dy", i ? "1.2em" : 0)
        .attr("text-anchor", "middle")
        .attr("class", "tspan" + i);
      }
    })
      .attr("pointer-events", "none")
      .attr("font-family", "sans-serif")
      .attr("font-size", "10px")
      .attr("fill", "black");

我应该怎么做才能正确对齐,或者有其他方法可以做到这一点吗?

有多种方法可以解决此问题。一个简单的方法是将 <tspan> 附加到 <g> 元素,将其所有 x 属性设置为 0 并将 text-anchor 设置为 middle.

看看演示:

var svg = d3.select("svg");
var data = [{
  text: "some text"
}, {
  text: "a longer text here"
}, {
  text: "an even longer text here"
}, {
  text: "short text"
}, {
  text: "a long text"
}];

var texts = svg.selectAll(null)
  .data(data)
  .enter()
  .append("g");

texts.append("text")
  .attr("text-anchor", "middle")
  .each(function(d) {
    var arr = d.text.split(" ");
    d3.select(this).selectAll(null)
      .data(arr)
      .enter()
      .append("tspan")
      .attr("text-anchor", "middle")
      .attr("x", 0)
      .attr("dy", function(d, i) {
        return "1.2em"
      })
      .text(String)
  })

var simulation = d3.forceSimulation(data)
  .force("center", d3.forceCenter(200, 100))
  .force("collide", d3.forceCollide(40))
  .on("tick", tick);

function tick() {
  texts.attr("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")"
  })
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="400" height="250"></svg>

PS:不要在 each 中使用 for 循环。这不是 地道的 D3。取而代之的是,只需使用输入选择(请参阅演示以了解如何操作)。