【问题标题】:How to wrap text in SVG vertically in D3.js?如何在 D3.js 中垂直包装 SVG 中的文本?
【发布时间】:2020-05-13 06:32:05
【问题描述】:

我还没有完全找到使用 D3 的答案。我正在从一个 svg 元素制作一个矩形工具提示,该元素在单击节点时显示在图表上。与工具提示关联的文本,来自图表的 json,目前仅水平扩展,即使工具提示的尺寸是垂直扩展的。我希望矩形垂直环绕文本(如回车),而不是水平环绕,给定矩形的固定宽度。

下面是我在单击节点时创建工具提示的位置:

nodes.on("click", function (d){
    if (tip){ tip.remove()};

    tip = svg.append("g")
        .attr("id", "tip")
        .attr("transform", "translate(" + (d3.event.pageX - 10)  + "," + (d3.event.pageY - 35) + ")");

    let rect = tip.append("rect")
        .style("fill", "white")
        .style("stroke", "steelblue");

    tip.append("text")
        .text(d.description)
        .attr("dy", "1em")
        .attr("x", 5);

    let bbox = tip.node().getBBox();

    rect.attr("width", bbox.width + 5)
        .attr("height", bbox.height)
});

这是一个具有当前功能的 jsfiddle:https://jsfiddle.net/Thegreatmochi/epy6514t/14/

【问题讨论】:

标签: javascript d3.js svg


【解决方案1】:

从这个bl.ocks.org你可以使用 wrap 函数,只需稍加修改:

function wrap(text, width) {
  text.each(function() {
    var text = d3.select(this),
        words = text.text().split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        lineHeight = 1.1, // ems
        y = text.attr("y"),
        dy = parseFloat(text.attr("dy")),
        tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(" "));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(" "));
        line = [word];
        tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", lineHeight + "em").text(word);
      }
    }
  });
}

这是一个有效的 sn-p:

let graph = {
  "nodes": [{
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed porta consequat felis, eget varius mi volutpat sit amet. Nullam lobortis vehicula felis, in tempor dui. Sed scelerisque purus ac nisl auctor finibus sit amet nec massa. Duis erat sem, suscipit non molestie vitae, accumsan nec tortor. Nulla sed facilisis ligula, nec interdum elit. Nam tortor lectus, sodales ut nulla ac, feugiat ultrices velit. Vestibulum nec ultricies nisi. Donec leo nibh, fringilla eget pretium nec, condimentum in nulla."
  }]
}

let svg = d3.select("body")
  .append("svg")
  .attr("width", 700)
  .attr("height", 800);

let nodes = svg.selectAll("circle")
  .data(graph.nodes)
  .enter()
  .append("circle")
  .attr("r", 20)
  .attr("cx", function(d) {
    return 20;
  })
  .attr("cy", function(d) {
    return 20;
  })
  .style("fill", "red");
let tip;
nodes.on("click", function(d) {
  if (tip) {
    tip.remove()
  };

  tip = svg.append("g")
    .attr("id", "tip")
    .attr("transform", "translate(" + (d3.event.pageX - 10) + "," + (d3.event.pageY - 35) + ")");

  let rect = tip.append("rect")
    .style("fill", "white")
    .style("stroke", "steelblue");

  tip.append("text")
    .text(d.description)
    .attr("dy", "1em")
    .attr("x", 5)
    .call(wrap, 300)

  let bbox = tip.node().getBBox();

  rect.attr("width", bbox.width + 5)
    .attr("height", bbox.height + 50)

});


function wrap(text, width) {
  text.each(function() {
    var text = d3.select(this),
      words = text.text().split(/\s+/).reverse(),
      word,
      line = [],
      lineNumber = 0,
      lineHeight = 1.1, // ems
      y = text.attr("y"),
      dy = parseFloat(text.attr("dy")),
      tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(" "));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(" "));
        line = [word];
        tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", lineHeight + "em").text(word);
      }
    }
  });
}
<p>
  click the node to show description
</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.2/d3.js"></script>

【讨论】:

    猜你喜欢
    • 2020-06-18
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 2013-12-25
    • 2015-09-10
    • 2021-11-02
    相关资源
    最近更新 更多