Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG: using getComputedTextLength to wrap text

Tags:

javascript

svg

I'm trying to wrap text by building up a text string, and using getComputedTextLength to find out when the text goes beyond the allowed width. However, I can't find a simple way to incrementally build up the text which will work with getComputedTextLength.

The general idea is:

  str = svgDocument.createTextNode(myText[word]); // first word on new line
  word++;
  obj = text.cloneNode(true);                     // new text element for this line
  obj.appendChild(str);
  svgDocument.documentElement.appendChild(obj);   // reqd for getComputedTextLength?
  for( ; word < myText.length; word++) {
     next_width = obj.getComputedTextLength();    // get current line width
     if(next_width >= extent)
        break;
     str += " ";                                  // add next word to the line
     str += myText[word];
     ...
  }

Can anyone tell me how to get this to work? Presumably str is copied rather than referenced in obj, but I've also tried putting obj.removeChild(str) and obj.appendChild(str) in the loop, but the appendChild crashes. I've also tried various combinations of moving around the documentElement.appendChild, and removing obj and re-appending it, and so on.

like image 441
EML Avatar asked Aug 12 '11 22:08

EML


1 Answers

a wrapper function for overflowing text:

    function wrap() {
        var self = d3.select(this),
            textLength = self.node().getComputedTextLength(),
            text = self.text();
        while (textLength > (width - 2 * padding) && text.length > 0) {
            text = text.slice(0, -1);
            self.text(text + '...');
            textLength = self.node().getComputedTextLength();
        }
    } 

usage:

text.append('tspan').text(function(d) { return d.name; }).each(wrap);
like image 86
user2846569 Avatar answered Oct 03 '22 11:10

user2846569