web-dev-qa-db-ja.com

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長方形の内部に段落を書くための気の利いた方法はありますか?おかげで、

13
mike

この質問 への回答が適切かもしれません。 SVGはテキストを自動的に折り返す方法を提供しませんが、SVG内にHTMLを埋め込んでから、たとえばdivを使用できます。

Jsfiddle here を更新しましたが、アニメーションとの連携がうまくいきません。それを適切に機能させ、他のSVG要素のように動作させたい場合は、改行を事前に計算して手動で挿入する必要があります。

16
Lars Kotthoff

アニメーションで機能させるには、グループ要素で囲み、代わりにそれをアニメーション化します。 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)");
14
GusOst

このテクニックは便利かもしれません。現在のsvg仕様で動作し、foreignObject要素はありません http://bl.ocks.org/mbostock/7555321

3
arunkjn

別のアプローチとして、テキストの直線を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");
2
maia

同様の問題があり、ボックスの幅を計算することで合理的な解決策を見つけました。次に、現在のフォントの文字幅は平均して約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");
2
dirk