D3.js - How can I add a new line to the text in this Collapsible Tree?

前端 未结 2 1880
长情又很酷
长情又很酷 2021-01-18 11:19

I have a Collapsible Tree built by D3. Here is the JSFIDDLE:http://jsfiddle.net/mEyQW/57/

As you can see, when the nodes fully expended, the text were all overlapped

相关标签:
2条回答
  • 2021-01-18 11:33

    I had a similar problem so I had to do a little manual work. First, you need a function that will actually 'wrap' the text:

    function wordwrap(text, max) {
      var regex = new RegExp(".{0,"+max+"}(?:\\s|$)","g");
      var lines = [];
      var line; 
      while ((line = regex.exec(text))!="") {lines.push(line);} 
      return lines
    }   
    

    Then, you need to appy this function to each text element. In your code I would write it like this:

    nodeEnter.append("text")
      .attr("x", function(d) { return d.children1 || d._children1 ? -10 : 10; })
      .attr("dy", ".35em")
      .attr("text-anchor", function(d) { return d.children1 || d._children1 ? "end" : "start"; })
       .style("fill-opacity", 1e-6)
       .each(function (d) {
           if (d.NickName!=undefined) {
              var lines = wordwrap(d.NickName, 15)
              for (var i = 0; i < lines.length; i++) {
                 d3.select(this).append("tspan")
                     .attr("dy",13)
                     .attr("x",function(d) { 
                          return d.children1 || d._children1 ? -10 : 10; })
                      .text(lines[i])
               }
            }
    }); 
    

    The end result is this:

    enter image description here

    Of course you should spend some time adjusting the x position of each text element.

    EDIT A simpler way would be to have a wordwrap method as:

    function wordwrap2(text) {
       var lines=text.split(" ")
       return lines
    }
    

    and apply it like the following:

    nodeEnter.append("text")
      .attr("x", function(d) { return d.children1 || d._children1 ? -10 : 10; })
      .attr("dy", ".35em")
      .attr("text-anchor", function(d) { return d.children1 || d._children1 ? "end" : "start"; })
       .style("fill-opacity", 1e-6)
       .each(function (d) {
           if (d.NickName!=undefined) {
              var lines = wordwrap2(d.NickName)
              for (var i = 0; i < lines.length; i++) {
                 d3.select(this).append("tspan")
                     .attr("dy",13)
                     .attr("x",function(d) { 
                          return d.children1 || d._children1 ? -10 : 10; })
                      .text(lines[i])
               }
            }
    });    
    

    Here is a fiddle for this last approach: http://jsfiddle.net/mEyQW/59/

    Hope this helps.

    0 讨论(0)
  • 2021-01-18 11:34

    I had a hard time to split a line on comma and place the text pieces in a list format. The following adaptation worked.

     function splitoncomma(text) {
       var lines=text.split(",") //splits text on comma
       return lines
    }
    
       label.append("div")
              .attr("class", "class_name")
              .each(function (d) {
                if (textValue(d)!==undefined) {
                  var lines = splitoncomma(textValue(d))
                  for (var i = 0; i < lines.length; i++) {
                    d3.select(this)
                    .append("text")
                    .append("tspan")
                    .style("float","left")// the float:left avoids default inline positioning
                    .text(lines[i])
           }
        }
    

    The style float left is required to avoid default inline placement.

    0 讨论(0)
提交回复
热议问题