Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG Word Wrap - Show stopper?

Tags:

For fun I am trying to see how far I can get at implementing an SVG browser client for a RIA I'm messing around with in my spare time.

But have hit what appears to be a HUGE stumbling block. There is no word wrap!!

Does anyone know of any work around (I'm thinking some kind of JavaScript or special tag I don't know)?

If not I'm either going to have to go the xhtml route and start sticking HTML elements in my SVG (ouch), or just come back again in ten years when SVG 1.2 is ready.

like image 693
ChrisInCambo Avatar asked Jan 24 '09 09:01

ChrisInCambo


People also ask

How do I stop text wrapping in Word?

Right-click the control for which you want to enable or disable text wrapping, and then click Control Properties on the shortcut menu. Click the Display tab. Select or clear the Wrap text check box.

Does SVG text wrap?

Text wrapping is not part of SVG1. 1, the currently implemented spec. If you are targeting a pure SVG renderer without HTML support or want your graphic to be editable using professional vector graphics manipulation software (Adobe Illustrator, Inkscape, ...), this solution will probably not suit you.

How do you change word wrap settings?

Select Format and then under Arrange, select Wrap Text. Choose the wrapping option that you want to apply. Tip: To change a picture or drawing object's position on the page relative to the text, select the picture or object, select Format > Position, and then select the position that you want.

How do you stop word wrap in CSS?

If you want to prevent the text from wrapping, you can apply white-space: nowrap; Notice in HTML code example at the top of this article, there are actually two line breaks, one before the line of text and one after, which allow the text to be on its own line (in the code).


2 Answers

There is also foreignObject tag. Then you can embed HTML in SVG which gives the greatest flexibility. HTML is great for document layout and has been hacked to no end to support application layout, drawing, and everything us developers want. But it's strength is word wrapping and document layout. Let HTML do what it does best, and let SVG do what it does best.

http://www.w3.org/TR/SVG/extend.html

This works for most browsers FireFox, Opera, Webkit, except IE (as of IE11). :-( Story of the web ain't it?

like image 154
chubbsondubs Avatar answered Sep 24 '22 12:09

chubbsondubs


This SVG stuff is baffling, isn't it ?

Thankfully, you can achieve some good results, but it takes more work than using the HTML 5 .

Here's a screenshot of my ASP.Net / SVG app, featuring a bit of "faked" word wrapping.

enter image description here

The following function will create an SVG text element for you, broken into tspan pieces, where each line is no longer than 20 characters in length.

<text x="600" y="400" font-size="12" fill="#FFFFFF" text-anchor="middle">     <tspan x="600" y="400">Here a realy long </tspan>     <tspan x="600" y="416">title which needs </tspan>     <tspan x="600" y="432">wrapping </tspan> </text> 

It's not perfect, but it's simple, fast, and the users will never know the difference.

My createSVGtext() JavaScript function takes three parameters: an x-position, y-position and the text to be displayed. The font, maximum-chars-per-line and text color are all hardcoded in my function, but this can be easily changed.

To display the right-hand label shown in the screenshot above, you would call the function using:

var svgText = createSVGtext("Here a realy long title which needs wrapping", 600, 400); $('svg').append(svgText); 

And here's the JavaScript function:

function createSVGtext(caption, x, y) {     //  This function attempts to create a new svg "text" element, chopping      //  it up into "tspan" pieces, if the caption is too long     //     var svgText = document.createElementNS('http://www.w3.org/2000/svg', 'text');     svgText.setAttributeNS(null, 'x', x);     svgText.setAttributeNS(null, 'y', y);     svgText.setAttributeNS(null, 'font-size', 12);     svgText.setAttributeNS(null, 'fill', '#FFFFFF');         //  White text     svgText.setAttributeNS(null, 'text-anchor', 'middle');   //  Center the text      //  The following two variables should really be passed as parameters     var MAXIMUM_CHARS_PER_LINE = 20;     var LINE_HEIGHT = 16;      var words = caption.split(" ");     var line = "";      for (var n = 0; n < words.length; n++) {         var testLine = line + words[n] + " ";         if (testLine.length > MAXIMUM_CHARS_PER_LINE)         {             //  Add a new <tspan> element             var svgTSpan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');             svgTSpan.setAttributeNS(null, 'x', x);             svgTSpan.setAttributeNS(null, 'y', y);              var tSpanTextNode = document.createTextNode(line);             svgTSpan.appendChild(tSpanTextNode);             svgText.appendChild(svgTSpan);              line = words[n] + " ";             y += LINE_HEIGHT;         }         else {             line = testLine;         }     }      var svgTSpan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');     svgTSpan.setAttributeNS(null, 'x', x);     svgTSpan.setAttributeNS(null, 'y', y);      var tSpanTextNode = document.createTextNode(line);     svgTSpan.appendChild(tSpanTextNode);      svgText.appendChild(svgTSpan);      return svgText; } 

The logic for word-wrapping is based on this HTML5 Canvas tutorial

I hope you find this useful !

Mike

http://www.MikesKnowledgeBase.com

UPDATE

One thing I forgot to mention.

That "Workflow diagram" screen that I've shown above was originally just written using an HTML 5 canvas. It worked beautifully, the icons could be dragged, popup menus could appear when you clicked on them, and even IE8 seemed happy with it.

But I found that if the diagram became "too big" (eg 4000 x 4000 pixels), then the would fail to initialise in all browsers, nothing would appear - but - as far as the JavaScript code was concerned, everything was working fine.

So, even with error-checking, my diagram was appearing blank, and I was unable to detect when this showstopper problem was occurring.

var canvasSupported = !!c.getContext; if (!canvasSupported) {     //  The user's browser doesn't support HTML 5 <Canvas> controls.     prompt("Workflow", "Your browser doesn't support drawing on HTML 5 canvases.");     return; }  var context = c.getContext("2d"); if (context == null) {     //  The user's browser doesn't support HTML 5 <Canvas> controls.     prompt("Workflow", "The canvas isn't drawable.");     return; }  //  With larger diagrams, the error-checking above failed to notice that //  the canvas wasn't being drawn. 

So, this is why I've had to rewrite the JavaScript code to use SVG instead. It just seems to cope better with larger diagrams.

like image 42
Mike Gledhill Avatar answered Sep 24 '22 12:09

Mike Gledhill