【问题标题】:Fit Text into SVG Element (Using D3/JS)使文本适合 SVG 元素(使用 D3/JS)
【发布时间】:2012-06-15 23:36:12
【问题描述】:

我想在我创建的矩形内写入文本,如下所示:

body = d3.select('body')

svg = body.append('svg').attr('height', 600).attr('width', 200)

        rect = svg.append('rect').transition().duration(500).attr('width', 150)
                        .attr('height', 100)
                        .attr('x', 40)
                        .attr('y', 100)
                        .style('fill', 'white')
                        .attr('stroke', 'black')

        text = svg.append('text').text('This is some information about whatever')
                        .attr('x', 50)
                        .attr('y', 150)
                        .attr('fill', 'black')​

但是,如您所见 (http://jsfiddle.net/Tmj7g/3/),文本被截断。在创建的 svg 矩形内写一个段落的任何漂亮方法?谢谢,

【问题讨论】:

    标签: javascript text svg d3.js


    【解决方案1】:

    this question 的答案可能是相关的。 SVG 无法自动包装文本,但您可以在 SVG 中嵌入 HTML,然后使用 div 例如。

    我已经更新了 jsfiddle here,但它与动画配合得不太好。如果您想让它正常工作并像任何其他 SVG 元素一样工作,您必须预先计算换行符并手动插入它们。

    【讨论】:

    • 这适用于 IE9 吗?如果是这样,有哪些替代方案?我知道这是很久以前回答的。
    • 是的,它在 IE9 中根本不起作用,因为它不支持外部对象。在 D3.js 中换行是否有任何替代方法?
    • 这不是 D3 而是 SVG 问题。如果您不需要精美的图形,您可以简单地生成 HTML。如果你需要 SVG,你可以使用它的 tspan 元素来包装文本,但是这样不太方便。
    【解决方案2】:

    要使其与动画一起使用,只需将其包含在一个组元素中并为其设置动画即可。 http://jsfiddle.net/MJJEc/

    body = d3.select('body')
    svg = body.append('svg')
                        .attr('height', 600)
                        .attr('width', 200);
        var g = svg.append('g').attr("transform" ,"scale(0)");
        rect = g.append('rect')
                        .attr('width', 150)
                        .attr('height', 100)
                        .attr('x', 40)
                        .attr('y', 100)
                        .style('fill', 'none')
                        .attr('stroke', 'black')
        text = g.append('foreignObject')
                        .attr('x', 50)
                        .attr('y', 130)
                        .attr('width', 150)
                        .attr('height', 100)
                        .append("xhtml:body")
                        .html('<div style="width: 150px;">This is some information about whatever</div>')
    
        g.transition().duration(500).attr("transform" ,"scale(1)");
    

    【讨论】:

      【解决方案3】:

      这种技术可能会派上用场。 它适用于当前的 svg 规范并且没有 foreignObject 元素 http://bl.ocks.org/mbostock/7555321

      【讨论】:

      • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效
      【解决方案4】:

      我有一个类似的问题,并通过计算我的盒子的宽度找到了一个合理的解决方案。 其次,我发现我当前字体的平均字符宽度约为 8。 接下来我只是对要显示的文本做一个子字符串。 在大多数情况下,这似乎工作得很好。

      var rectText = rectangles.append("text")
          .text(function(d) {
      
              TextBoxLength = timeScale(dateFormat.parse(d.endTime)) - timeScale(dateFormat.parse(d.startTime));
              return d.task.substring(0, Math.floor(TextBoxLength / 8));
          })
          .attr("x", function(d) {
              return (timeScale(dateFormat.parse(d.endTime)) - timeScale(dateFormat.parse(d.startTime))) / 2 + timeScale(dateFormat.parse(d.startTime)) + theSidePad;
          })
          .attr("y", function(d, i) {
              return d.position * theGap + 14 + theTopPad;
          })
          .attr("font-size", 12)
          .attr("text-anchor", "middle")
          .attr("text-height", theBarHeight)
          .attr("fill", "#000000");
      

      【讨论】:

        【解决方案5】:

        另一种方法,当尝试将直线文本放入 svg 元素时,可以使用 http://bl.ocks.org/mbostock/1846692 中的策略:

        node.append("text")
          .text(function(d) { return d.name; })
          .style("font-size", function(d) { return Math.min(2 * d.r, (2 * d.r - 8) / this.getComputedTextLength() * 24) + "px"; })
          .attr("dy", ".35em");
        

        【讨论】:

          猜你喜欢
          • 2023-02-13
          • 2018-01-02
          • 1970-01-01
          • 1970-01-01
          • 2018-02-27
          • 1970-01-01
          • 2014-02-24
          • 1970-01-01
          • 2016-11-20
          相关资源
          最近更新 更多