2

Hmmm. Now that I've figured out how to wrap SVG text dynamically using TSPANs (see Auto line-wrapping in SVG text), trying to animate it has me stumped. I'm basing it off the Zoomable Treemap example from Mike Bostock.

My text wrapping code is invoked thus:

    g.append("text")
     .attr("dy", ".75em")
     .text(function(d) { return d.name; })
 //  .call(text)                // Mike's line
     .each(function (d,i) {     // My line
         wraptorect(this,this.previousSibling,6,2,2);
     });

Putting the old Mike line back works fine but removes the text wrapping:

function text(text) {
  text.attr("x", function(d) { return x(d.x) + 6; })
      .attr("y", function(d) { return y(d.y) + 6; });
}

I'd have thought that you'd just need to animate the parent TEXT element but I'm getting the text moving in weird directions in Chrome (and even worse behaviour in IE9 where the text doesn't want to wrap yet). I suspect it's something to do with the TSPANs having x attributes but can't see the way forward beyond that...

Single line

<text dy=".75em" x="252" y="2">Other purposes which could be interesting</text>

Wrapped lines

<text dy=".75em" x="252" y="2">
  <tspan x="252" dy="15">Other purposes </tspan>
  <tspan x="252" dy="15">which could be </tspan>
  <tspan x="252" dy="15">interesting </tspan>
</text>

The JS code is quite long so here's the fiddle link: http://jsfiddle.net/gHdR6/6/

Community
  • 1
  • 1
MSC
  • 3,286
  • 5
  • 29
  • 47
  • What are you aiming for with this? In your jsfiddle the positions of the text elements don't seem to be animated at all. – Lars Kotthoff Apr 07 '14 at 09:25
  • Hi Lars. I am aiming for this behaviour: http://bost.ocks.org/mike/treemap/ (I couldn't include a thrid link in my original question.) – MSC Apr 07 '14 at 10:09
  • Have you tried transitioning the `text` elements as in that example then? You shouldn't need to change anything if the `text`s contain `tspan`s. – Lars Kotthoff Apr 07 '14 at 10:16
  • http://jsfiddle.net/gHdR6/8/ is the code updated as you suggest. Lines 339-344 and 373-376 were commented / uncommented. The trouble is the TSPANs are built dynamically from the (simulated) JSON stored in 'root'. I've made the text in each box longer so you can see the (lack of) wrapping more clearly. – MSC Apr 07 '14 at 10:30
  • I see. Not sure where the problem is -- your function to wrap the text is quite long. Have you considered using [this (simpler) example](http://bl.ocks.org/mbostock/7555321)? – Lars Kotthoff Apr 07 '14 at 10:36
  • I just came across that a few hours ago and may have a go with it tomorrow. It takes a fixed width as a parameter but I'll see how it goes. – MSC Apr 07 '14 at 10:42
  • After fiddling around with some simple SVG, I now see that if the TSPAN has an x attribute, it will _not_ move as the parent TEXT element's x is changed. So I can either wrap the whole TEXT in a G element or use dx attributes on the TSPANs instead. Going with the dx for now. I'll let you know how I get on. – MSC Apr 08 '14 at 03:01
  • OK so I used transform="translate(x,y)" on the TEXT instead of dx's on the TSPANs or a wrapper G. It was just easier with the existing SVG structure. There are still some problems (see http://jsfiddle.net/gHdR6/15/) but I'll ask separate questions for those. I'll answer the original question for other people's benefit. – MSC Apr 09 '14 at 00:14

1 Answers1

3

If TSPANs are positioned absolutely (ie. they have x and / or y attributes) then you can't move then by moving the parent TEXT. You can either (a) position them relatively (using dx and dy), or (b) move the entire text block by using a transform on the TEXT or a wrapper G. I found inconsistencies in how IE and Chrome render font-widths so used (b) to good effect.

See http://jsfiddle.net/gHdR6/15/ for the updated demo. Here's the SVG structure which works:

<text transform="translate(772,439)">
    <tspan x="0" dy="15">Transport and </tspan>
    <tspan x="0" dy="15">communication </tspan>
</text>

Your zoom (or animation) code then needs to update the translate for these nodes instead of x and y.

MSC
  • 3,286
  • 5
  • 29
  • 47