D3.js - How to add a new line to the text in this summary tree?

I have a precast tree built by D3. Here is JSFIDDLE: http://jsfiddle.net/mEyQW/57/

As you can see, when the nodes are completely used up, the text was blocked. I want to add a new line to replace the space (may have 1 or 2). For example: SDS 123 will become

Sds
123

I tried several similar answers found in stack overflow, but still can't solve my problem. Could you help with this? Submitted by JSFIDDLE will be appreciated!

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"; }) .text(function(d) { return d.NickName ; }) .style("fill-opacity", 1e-6); 

Thanks!!

+6
source share
2 answers

I had a similar problem, so I had to do a little manual work. First, you need a function that actually wraps 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 bind 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 as follows:

enter image description here

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

EDIT A simpler way would be to use the wordwrap method as:

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

and apply it as follows:

 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 the script for this last approach: http://jsfiddle.net/mEyQW/59/

Hope this helps.

+6
source

It was difficult for me to split the line into a comma and put the text fragments in the 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]) } } 

To prevent default placement, a style float is required by default.

+1
source

Source: https://habr.com/ru/post/980526/


All Articles