Hacker News new | ask | show | jobs
by nxn 4816 days ago
I am not sure if I am more upset at this not providing any native means of word wrap, or IE not supporting foreignObject. Seriously, a large use case for using SVG on the web is data visualization -- where you will often find yourself displaying labels which need to wrap to a given size in order to display cleanly. Add to this the necessity to move other text around based on the height of other text elements and you're looking at a mess of ugly alignment code.
2 comments

At Moqups ( https://moqups.com ) we've been through a very painful process of trying to implement a word wrap component in SVG and after a few months decided to throw it out and use foreignObject. We decided that it's impossible to be able to cover the thousands of text handling scenarios for all the languages and scripts out there and the performance makes it very unfeasible beyond a few hundred words. With few exceptions related to measuring text across browsers/operating systems, this was a very good decision.

Sadly it's also the main reason for why we're not planning to support any version of IE moving forward although many users request it.

Slightly unrelated, but I'm also happy to see getStrokeBBox in there. It's been a total pain to manually compute the stroked bbox of each stencil so the layout engine can properly arrange each element in respect to its painted area.

I actually implemented a very primitive word wrap function specifically for wrapping text in SVGs about two weeks ago. I took the approach of keeping an single canvas object in memory (completely detached from the DOM, 1x1 pixel dimensions) and using its "measureText" method for calculating string lengths. This made the algorithm fairly simple, and if you set the font on the canvas context correctly, the results will actually be fairly accurate -- though you might have to take into account any scaling that you have applied on the SVG.

This approach did not cause any noticeable change in performance, at least not in my use case where there are at most around 100 nodes of text that needed word wrapping. I can't really compare it with other approaches since I saw no need to take multiple stabs at the problem when my first attempt proved to work well enough. I would guess that it might be faster than actually creating SVG text elements and then trying to get their widths since you're eliminating a lot of overhead in the pre-calculation phase. Also, as far as desktop browsers go, anything that has SVG also has canvas, so there were no worries there about browser compatibility issues.

EDIT: But yeah, I'm just mentioning this in case you find some use for it. Looking at your link I would say you're much better off just using foreignObject.

That only gives you the option of how you'd like to see it clipped (ex: ellipsis, an indication that the full text is not shown), it will not enable you to wrap the text onto another line. As per word wrap itself, the spec states it is not supported in the intro, and makes a few suggestions (two are essentially doing it manually, and one isn't an option if you'd like IE support): http://www.w3.org/TR/2013/WD-SVG2-20130409/text.html#Introdu...
It'll be a while before we have to worry about IE supporting SVG 2 in any case.
My concern, in this particular case, is that foreignObject isn't exactly a new addition to this spec, it's been mentioned in SVG specs since at least 2001, and the IE team apparently made the deliberate decision of not implementing it. I'm not sure what their rationale is exactly, but it doesn't appear like they will be changing their minds about it anytime soon.