使文本适合SVG元素(使用D3 / JS)

时间:2012-06-13 02:56:54

标签: javascript text svg d3.js

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

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矩形内部的段落的任何好方法?谢谢,

5 个答案:

答案 0 :(得分:16)

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

我已经更新了jsfiddle here,但它与动画效果不佳。如果你想使它正常工作并且行为与任何其他SVG元素一样,你必须预先计算换行符并手动插入它们。

答案 1 :(得分:14)

要使其与动画一起使用,只需将其包含在一个组元素中,然后为该元素设置动画。 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)");

答案 2 :(得分:3)

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

答案 3 :(得分:2)

我有一个类似的问题,通过计算我的盒子的宽度找到了合理的解决方案。 其次,我发现平均而言我当前字体的字符宽度大约为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");

答案 4 :(得分:2)

另一种尝试将直线文本放入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");