Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display multiple lines of text in SVG?

Tags:

html

svg

Is it possible to display multiple lines of text in SVG without using the dy property? I'm using SVG 1.1 but might be able to use 1.2.

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <text x="0" y="15" font-size="15">
    <tspan>tspan line 1</tspan>
    <tspan>tspan line 2</tspan>
    <tspan>tspan line 3</tspan>
  </text>
</svg>

I've typed the code above. I want the text all flush to the left and each tspan to be a new line. Is tspan the only tag I can use? I want SVG to position the text lines vertically with line breaks. I do not want to manually enter the dy.

According to what I've read, each line should appear below the other. They are but they are also staggered across.

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <text x="0" y="0" font-size="15">
    <tspan dy="15">tspan line 1</tspan>
    <tspan dy="15">tspan line 2</tspan>
    <tspan dy="15">tspan line 3</tspan>
  </text>
</svg>

I guess it is required to add the x property. If you are setting the dy property to a fixed value, what happens when you change the font size?

This is working better than what I started with:

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xml:space="preserve">
  <text x="0" y="0" font-size="15" font-family="courier new" dy="0">
    <tspan x="0" dy="15">tspan line 1</tspan>
    <tspan x="0" dy="15">tspan line 2</tspan>
    <tspan x="0" dy="15">tspan line 3</tspan>
  </text>
</svg>

Is there a way to apply the x and dy to all the tspans? Maybe a property like line-height on the text element?

It doesn't look like the text tag has a property to set the delta y. It has been suggested in the comments to use JQuery to set the x attribute of all tspans. It looks like the dy property can accept other types of values such as points and percentages!? Is there a way to set the dy to a value that is 120% of the font size of its parent text element? I've tried to set it to 120%, but it doesn't seem to work like I expect. When I set 120% in the dy property, it goes off the screen. When I set it to 12 or 12px it stays in the same position. If I set it to 12%, it shifts slightly but is not 120% or 12px.

http://codepen.io/anon/pen/PqBRmd

It looks like it can accept any of the following:
http://www.w3.org/TR/SVG/types.html#InterfaceSVGLength

I've also looked up acceptable value types for dy and dx, and I can't make sense of it http://www.w3.org/TR/SVG/text.html#TSpanElementDXAttribute.

UPDATE 4:
Thanks for the answers so far. It looks like there is a way to display multiple lines of text spaced apart relatively. See my answer below.

like image 851
1.21 gigawatts Avatar asked Jul 17 '15 05:07

1.21 gigawatts


People also ask

How do I display text on multiple lines?

The correct way to do things is using things made for the things you need. If you want a line break (enter), use <br> ; If you want to define a paragraph, use <p> . Show activity on this post. According to this, the <br> element is used to insert a line break without starting a new paragraph.

What is Tspan SVG?

The SVG <tspan> element defines a subtext within a <text> element or another <tspan> element. It allows for adjustment of the style and/or position of that subtext as per user needs. Syntax: <tspan attributes="" > Subtext </tspan>

Is SVG text editable?

SVG 1.2 introduces editable text fields, moving the burden of text input and editing to the user agent, which has access to system text libraries.


3 Answers

It looks like this will space the lines one after another without hard-coding a font size in each tspan. Font at 15px:

<svg style="border:1px solid black" >
    <text x="0" y="0" font-size="15" dy="0">
        <tspan x="0" dy=".6em">tspan line 1</tspan>
        <tspan x="0" dy="1.2em">tspan line 2</tspan>
        <tspan x="0" dy="1.2em">tspan line 3</tspan>
    </text>
</svg>

If you change the font size the lines continue to be spaced at 120% apart from each other or 1.2em. Font at 20px:

<svg style="border:1px solid black" >
    <text x="0" y="0" font-size="20" dy="0">
        <tspan x="0" dy=".6em">tspan line 1</tspan>
        <tspan x="0" dy="1.2em">tspan line 2</tspan>
        <tspan x="0" dy="1.2em">tspan line 3</tspan>
    </text>
</svg>

Example - http://codepen.io/anon/pen/oXMVqo

like image 61
1.21 gigawatts Avatar answered Oct 25 '22 12:10

1.21 gigawatts


tspan is the right way to do it. And this is how:

<tspan x="10" dy="15">tspan line 1</tspan>

reference: http://tutorials.jenkov.com/svg/tspan-element.html

like image 33
Reptar Avatar answered Oct 25 '22 12:10

Reptar


just calculate the heights:

var drawx=part.x||0;
var drawy=part.y||0;
var fontSize=part.fontSize||14; 
var lineHeight=part.lineHeight||1.25; 
var style=part.style||""; 
var fontFamily=part.fontFamily||"Arial"; 
var text=part.text.split('\n').map(function(a,i){ return '<tspan x="'+drawx+'" y="'+(drawy+fontSize*lineHeight+i*fontSize*lineHeight)+'">'+a+'</tspan>' }).join('\n');

tqrSvg+='<text x="'+drawx+'" y="'+drawy+'" style="'+style+'" font-family="'+fontFamily+'" font-size="'+fontSize+'">'+text+'</text>'
like image 4
Shimon Doodkin Avatar answered Oct 25 '22 11:10

Shimon Doodkin