title: D3 vertical bar chart add newline to label text
body: <p>I was trying to break long lines of y-axis labels. My bar chart is like <a href="http://bl.ocks.org/erikvullings/51cc5332439939f1f292" rel="nofollow noreferrer">this</a> but with longer labels (usually more than 10 words with spaces). This is my code (it works and I see the chart, the only 'error' is the text, i load the JSON dinamically, this data is only for SO):</p>
  <p>HTML:</p>
  <pre><code>&lt;svg id='table1'&gt;&lt;/svg&gt;
  
  &lt;script&gt;
      var window_width = $(window).width();
      var main_width = (window_width / 100 ) * 80;
      var w = main_width - 400;
  
      var data = {
        labels: [
          'the text to be splitted 1', 'the text to be splitted 2'
        ],
        series: [
          {
            label: '2012',
            values: [4, 8]
          },
          {
            label: '2013',
            values: [12, 43]
          }
        ]
      };
  
      var chartWidth   = w,
      barHeight        = 25,
      groupHeight      = barHeight * data.series.length,
      gapBetweenGroups = 10,
      spaceForLabels   = 175,
      spaceForLegend   = 0;
  
      // Zip the series data together (first values, second values, etc.)
      var zippedData = [];
      for (var i=0; i&lt;data.labels.length; i++) {
        for (var j=0; j&lt;data.series.length; j++) {
          zippedData.push(data.series[j].values[i]);
        }
      }
  
      var chartHeight = barHeight * zippedData.length + gapBetweenGroups * data.labels.length;
      var x = d3.scale.linear()
          .domain([0, d3.max(zippedData)])
          .range([0, chartWidth]);
  
      var y = d3.scale.linear()
          .range([chartHeight + gapBetweenGroups, 0]);
  
      var yAxis = d3.svg.axis()
          .scale(y)
          .tickFormat('')
          .tickSize(0)
          .orient(&quot;left&quot;);
  
      // Specify the chart area and dimensions
      var chart = d3.select(&quot;#table&quot;+ambit)
          .attr(&quot;width&quot;, spaceForLabels + chartWidth + spaceForLegend)
          .attr(&quot;height&quot;, chartHeight);
  
      // Create bars
      var bar = chart.selectAll(&quot;g&quot;)
          .data(zippedData)
          .enter().append(&quot;g&quot;)
          .attr(&quot;transform&quot;, function(d, i) {
            return &quot;translate(&quot; + spaceForLabels + &quot;,&quot; + (i * barHeight + gapBetweenGroups * (0.5 + Math.floor(i/data.series.length))) + &quot;)&quot;;
          });
  
      // Create rectangles of the correct width
      bar.append(&quot;rect&quot;)
          .attr(&quot;fill&quot;, function(d,i) { return color(i % data.series.length); })
          .attr(&quot;class&quot;, &quot;bar&quot;)
          .attr(&quot;width&quot;, x)
          .attr(&quot;height&quot;, barHeight - 1);
  
      // Add text label in bar
      bar.append(&quot;text&quot;)
          .attr(&quot;class&quot;, &quot;label_txt1&quot;)    
          .attr(&quot;x&quot;, function(d) { return x(d) - 3; })
          .attr(&quot;y&quot;, barHeight / 2)
          .attr(&quot;fill&quot;, &quot;red&quot;)
          .attr(&quot;dy&quot;, &quot;.35em&quot;)
          .text(function(d) { return d; });
  
      // Draw labels
      bar.append(&quot;text&quot;)
          .attr(&quot;class&quot;, &quot;label_txt&quot;)
          .attr(&quot;x&quot;, function(d) { return - 10; })
          .attr(&quot;y&quot;, groupHeight / 2)
          .attr(&quot;dy&quot;, &quot;.35em&quot;)
          .text(function(d,i) {
            if (i % data.series.length === 0)
          return data.labels[Math.floor(i/data.series.length)];
            else
          return &quot;&quot;});
  
      chart.append(&quot;g&quot;)
            .attr(&quot;class&quot;, &quot;y axis&quot;)
            .attr(&quot;transform&quot;, &quot;translate(&quot; + spaceForLabels + &quot;, &quot; + -gapBetweenGroups/2 + &quot;)&quot;)
            .call(yAxis);
  
  &lt;/script&gt;
  </code></pre>
  <p>I follow multiple examples to solve this, like:
  <a href="https://stackoverflow.com/questions/13241475/how-do-i-include-newlines-in-labels-in-d3-charts">How do I include newlines in labels in D3 charts?</a>
  and <a href="https://stackoverflow.com/questions/18488970/adding-a-line-break-to-d3-graph-y-axis-labels">Adding a line break to D3 graph y-axis labels</a> and <a href="https://bl.ocks.org/mbostock/7555321" rel="nofollow noreferrer">Wrapping Long Labels</a>.</p>
  <p>First attempt:</p>
  <pre><code>var insertLinebreaks = function (d) {
      var el = d3.select(this);
      var words = d.split(' ');
      el.text('');
  
      for (var i = 0; i &lt; words.length; i++) {
      var tspan = el.append('tspan').text(words[i]);
      if (i &gt; 0)
          tspan.attr('x', 0).attr('dy', '15');
      }
  };
  
  chart.selectAll('g.y.axis text').each(insertLinebreaks); 
  </code></pre>
  <p>and:</p>
  <pre><code>bar.selectAll('.label_txt1').each(insertLinebreaks);
  </code></pre>
  <p>Also I tried:</p>
  <pre><code>bar.append(&quot;text&quot;)
      .attr(&quot;class&quot;, &quot;label_txt1&quot;)    
      .attr(&quot;x&quot;, function(d) { return x(d) - 3; })
      .attr(&quot;y&quot;, barHeight / 2)
      .attr(&quot;fill&quot;, &quot;red&quot;)
      .attr(&quot;dy&quot;, &quot;.35em&quot;)
      .text(function(d) { return d; });
  
  chart.selectAll(&quot;.label_txt1&quot;).call(wrap, 40)
  
  function wrap(text, width) {
      alert(JSON.stringify(text));
      text.each(function() {
          var text = d3.select(this),
          words = text.text().split(/\s+/).reverse(),
          word,
          line = [],
          lineNumber = 0,
          y = text.attr(&quot;y&quot;),
          dy = parseFloat(text.attr(&quot;dy&quot;)),
          lineHeight = 1.1, // ems
          tspan = text.text(null).append(&quot;tspan&quot;).attr(&quot;x&quot;, function(d) { return d.children || d._children ? -10 : 10; }).attr(&quot;y&quot;, y).attr(&quot;dy&quot;, dy + &quot;em&quot;);     
          while (word = words.pop()) {
              line.push(word);
              tspan.text(line.join(&quot; &quot;));
              var textWidth = tspan.node().getComputedTextLength();
              if (tspan.node().getComputedTextLength() &gt; width) {
                  line.pop();
                  tspan.text(line.join(&quot; &quot;));
                  line = [word];
                  ++lineNumber;
                  tspan = text.append(&quot;tspan&quot;).attr(&quot;x&quot;, function(d) { return d.children || d._children ? -10 : 10; }).attr(&quot;y&quot;, 0).attr(&quot;dy&quot;, lineNumber * lineHeight + dy + &quot;em&quot;).text(word);
              }
          }
      });
  }
  </code></pre>
  <p>I changed <code>text()</code> to <code>html()</code> as I read at: <a href="https://stackoverflow.com/questions/13241475/how-do-i-include-newlines-in-labels-in-d3-charts">How do I include newlines in labels in D3 charts?</a></p>
  <p>In the browser I see the <code>&lt;text&gt;</code> created with class <code>label_txt1</code>. When I try to select the text with <code>selectAll(&quot;.label_txt1&quot;)</code> I get the values of the line, not the text.</p>
  <p>Can someone help me?</p>