d3.js-基于文本宽度的文本位置

dm1*_*988 2 html javascript d3.js

我正在使用d3.js生成代表不同假设的可视化。由于假设由不同的部分组成,因此每个单词/部分都有其自己的文本元素。

我想将每个文本元素的x位置基于上一个单词的文本宽度(包括偏移量)。有一个假设“ IF x THEN y”,我将需要4个文本元素,其中“ IF”的x = 0,并且由于“ IF”的宽度为10,并且我使用5的偏移量,因此“ x”将得到x = 15且以此类推。

我正在使用看起来像这样的json数据:

{[
    {"id" : "id0",
    "elements" : [
      {
         "text" : "IF",
         "type" : "conditional"
      },
      {
         "text" : "X",
         "type" : "variable"
      },
      {
         "text" : "THEN",
         "type" : "conditional"},
      {
         "text" : "Y",
         "type" : "variable"
      }
    ]},
   {"id" : "id1",
    "elements" : [
      {
         "text" : "IF",
         "type" : "conditional"
      },
      {
         "text" : "abc",
         "type" : "variable"
      },
      {
         "text" : "THEN",
         "type" : "conditional"},
      {
         "text" : "xyz",
         "type" : "variable"
      }
    ]}
]}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我用于生成文本元素的代码(每个假设都在g元素中

 var svg = d3.select("#viewport")
            .append("svg")
            .attr("width", 1200)
            .attr("height", 800);

        var content = svg.append("g").attr("id", "drawing");

        var groups = content.selectAll().data(arr)
            .enter()
            .append("g")
            .attr("class", function (d) {
                return "hypothesis " + d["id"];
            })
            .each(function (d, i) {
                d3.select(this).selectAll("text")
                    .data(d["elements"])
                    .enter()
                    .append("text")
                    .attr("class", function (d) {
                        return d.type;
                    })
                    .text(function (d) {
                        return d.text;
                    })
                    .attr("font-family", "sans-serif")
                    .attr("font-size", "20px")
                    .attr("x", function (d, j) {
                        return j++ * 100;
                    })
                    .attr("y", 50 * (i + 1));
            });
Run Code Online (Sandbox Code Playgroud)

设置x位置时,我想获取当前文本元素的宽度并将其推到变量上,这样我就可以获取下一个新的x坐标,而不仅仅是使用每个单词100 px的当前随机偏移量。

所以问题是我如何获得计算出的文本宽度(已经在getBBox或类似的东西上看到了东西,但是由于我不知道在哪里使用它们而对我不起作用)以及如何将其应用于文本元素。或者,如果有更好的方法来创建元素,则可能无法一次运行。

不同的元素需要以不同的颜色设置样式,并且必须做出反应,以便稍后将鼠标悬停在这上面,这就是为什么它们必须是单个文本元素的原因。

提前致谢。

Mar*_*ark 5

我总是将getComputedTextLength用于这类事情,尽管getBBox也可以工作:

.each(function(d, i) {
  var runningWidth = 0; //<-- keep a running total
  ...
  .attr("x", function(d, j) {
    var w = this.getComputedTextLength(), //<-- length of this node
        x = runningWidth; //<-- previous length to return
    runningWidth += w; //<-- total
    return x;
  })
  ...
Run Code Online (Sandbox Code Playgroud)

完整代码:

.each(function(d, i) {
  var runningWidth = 0; //<-- keep a running total
  ...
  .attr("x", function(d, j) {
    var w = this.getComputedTextLength(), //<-- length of this node
        x = runningWidth; //<-- previous length to return
    runningWidth += w; //<-- total
    return x;
  })
  ...
Run Code Online (Sandbox Code Playgroud)