66

D3を使用して棒グラフを生成しています(この例のコードを採用しました)。x軸で使用しているラベルは、それぞれ数語の長さです。これにより、すべてのラベルが重なるため、これらのラベルを行間で分割する必要があります。(各ラベルのすべてのスペースを改行で置き換えることができれば問題ありません。)

私はもともと、スペースを文字通りの改行()に置き換え、ラベルの要素に&#xA;設定することでこれを試しました。残念ながら、SVGはこのプロパティを尊重していないことがわかりました。次に、後でスタイルを設定できるように各単語をラップしようとしました。この関数に各ラベルを渡しました。xml:space="preserve"<text><tspan>

function (text) {
    return '<tspan>' + text.replace(/ /g, '</tspan><tspan>') + '</tspan>';
}

しかし、これは文字通り<tspan>のsを出力に入れるだけです。ラベルが重ならないように、テキストラベルをtspansでラップする(または何か他のことをする)にはどうすればよいですか?

4

6 に答える 6

89

次のコードを使用して、各x軸ラベルを行間で分割することになりました。

var insertLinebreaks = function (d) {
    var el = d3.select(this);
    var words = d.split(' ');
    el.text('');

    for (var i = 0; i < words.length; i++) {
        var tspan = el.append('tspan').text(words[i]);
        if (i > 0)
            tspan.attr('x', 0).attr('dy', '15');
    }
};

svg.selectAll('g.x.axis g text').each(insertLinebreaks);

これは、ラベルがすでに作成されていることを前提としていることに注意してください。(正規のヒストグラムの例に従うと、ラベルは必要な方法で設定されます。)また、実際の改行ロジックは存在しません。この関数は、すべてのスペースを改行に変換します。これは私の目的にぴったりですがsplit()、文字列の一部を行に分割する方法についてよりスマートになるように行を編集する必要がある場合があります。

于 2012-11-07T18:32:33.987 に答える
10

SVGテキスト要素はテキストラッピングをサポートしていないため、2つのオプションがあります。

  • テキストを複数のSVGテキスト要素に分割する
  • SVGの上にオーバーレイHTMLdivを使用する

これに関するMikeBostockのコメントをここで参照してください。

于 2012-11-06T16:04:29.640 に答える
6

私が便利だと思ったのは、textまたはtspan要素の代わりに'foreignObject'タグを使用することです。これにより、HTMLを簡単に埋め込むことができ、単語を自然に壊すことができます。注意点は、特定のニーズを満たすオブジェクトの全体的な寸法です。

var myLabel = svg.append('foreignObject')
    .attr({
        height: 50,
        width: 100, // dimensions determined based on need
        transform: 'translate(0,0)' // put it where you want it...
     })
     .html('<div class"style-me"><p>My label or other text</p></div>');

このオブジェクト内に配置した要素は、後でd3.select / selectAllを使用して取得し、テキスト値を動的に更新することもできます。

于 2015-04-13T17:05:26.730 に答える
5

周りを見回してみると、MikeBostockがテキストを折り返すことができるソリューションを提供していることがわかりました。

http://bl.ocks.org/mbostock/7555321

コードに実装するには(折りたたまれた樹形図を使用しています)。「wrap」メソッドをコピーしただけです。

次に、以下を追加しました

    // Standard code for a node    
    nodeEnter.append("text")
        .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
        .attr("dy", ".35em")
        .text(function(d) { return d.text; })
        // New added line to call the function to wrap after a given width
        .call(wrap, 40);

これが力指向、バー、またはその他のパタ​​ーンで機能しない理由はわかりません

修正 :

これを読み、折りたたみ可能なグラフを使用している人のために、ラップ関数を次のように変更しました。「x」属性の変更により、配置が正しく設定され、元のコードで問題が指摘されたため、行番号の増分が別の行で実行され、「y」がゼロにハード設定されました。そうしないと、行間隔が増加する問題が発生します。各行。

function wrap(text, width) {
    text.each(function() {
        var text = d3.select(this),
        words = text.text().split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        y = text.attr("y"),
        dy = parseFloat(text.attr("dy")),
        lineHeight = 1.1, // ems
        tspan = text.text(null).append("tspan").attr("x", function(d) { return d.children || d._children ? -10 : 10; }).attr("y", y).attr("dy", dy + "em");     
        while (word = words.pop()) {
            line.push(word);
            tspan.text(line.join(" "));
            var textWidth = tspan.node().getComputedTextLength();
            if (tspan.node().getComputedTextLength() > width) {
                line.pop();
                tspan.text(line.join(" "));
                line = [word];
                ++lineNumber;
                tspan = text.append("tspan").attr("x", function(d) { return d.children || d._children ? -10 : 10; }).attr("y", 0).attr("dy", lineNumber * lineHeight + dy + "em").text(word);
            }
        }
    });
}
于 2016-02-15T09:10:05.530 に答える
0

長いラベルのラッピングについてもこの答えがあります。

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.bar {
  fill: steelblue;
}

.bar:hover {
  fill: brown;
}

.title {
  font: bold 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.axis {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.x.axis path {
  display: none;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var margin = {top: 80, right: 180, bottom: 80, left: 180},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1, .3);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(8, "%");

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.tsv("data.tsv", type, function(error, data) {
  x.domain(data.map(function(d) { return d.name; }));
  y.domain([0, d3.max(data, function(d) { return d.value; })]);

  svg.append("text")
      .attr("class", "title")
      .attr("x", x(data[0].name))
      .attr("y", -26)
      .text("Why Are We Leaving Facebook?");

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
    .selectAll(".tick text")
      .call(wrap, x.rangeBand());

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.name); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.value); })
      .attr("height", function(d) { return height - y(d.value); });
});

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", ++lineNumber * lineHeight + dy + "em").text(word);
      }
    }
  });
}

function type(d) {
  d.value = +d.value;
  return d;
}

</script>

およびデータファイル「data.tsv」:

name    value
Family in feud with Zuckerbergs .17
Committed 671 birthdays to memory   .19
Ex is doing too well    .10
High school friends all dead now    .15
Discovered how to “like” things mentally    .27
Not enough politics .12
于 2014-11-14T03:38:34.397 に答える
-1

使用する<tspan>

とnv.d3で

nv.models.axis = function(){

..。

      .select('text')
            .attr('dy', '0em')
            .attr('y', -axis.tickPadding())
            .attr('text-anchor', 'middle')
            .text(function(d,i) {
              var v = fmt(d);
              return ('' + v).match('NaN') ? '' : v;
            });

.text(のすべての出現箇所を.html(に変更します

于 2014-03-28T19:12:13.277 に答える