tags:

views:

911

answers:

2

Hi,

I have the following SVG source code that generates a number of boxes with texts:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
       "http://www.w3.org/TR/2001/REC-SVG-20050904/DTD/svg11.dtd"&gt;
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600">
  <defs>
  </defs>
  <title>Draw</title>
  <g transform="translate(50,40)">
    <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" />
    <text text-anchor="middle" x="40">Text</text>
  </g>
  <g transform="translate(150,40)">
    <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" />
    <text text-anchor="middle" x="40">Text 2</text>
  </g>
  <g transform="translate(250,40)">
    <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" />
    <text text-anchor="middle" x="40">Text 3</text>
  </g>
</svg>

As you can see, I repeated the <g></g> three times to get three such boxes, when SVG has <defs> and <use> elements that allow reusing elements using id references instead of repeating their definitions. Something like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
       "http://www.w3.org/TR/2001/REC-SVG-20050904/DTD/svg11.dtd"&gt;
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600">
  <defs>
    <marker style="overflow:visible;fill:inherit;stroke:inherit"
            id="Arrow1Mend" refX="0.0" refY="0.0" orient="auto">
      <path transform="scale(0.4) rotate(180) translate(20,0)"
            style="fill-rule:evenodd;stroke-width:2.0pt;marker-start:none;"
            d="M 0.0,-15.0 L -20.5,0.0 L 0.0,15.0 "/>
    </marker>
      <line marker-end="url(#Arrow1Mend)" id="systemthread" x1="40" y1="10" x2="40" y2="410" style="stroke: black; stroke-dasharray: 5, 5; stroke-width: 1; "/>
  </defs>
  <title>Draw</title>
  <use xlink:href="#systemthread" transform="translate(50,40)" />
  <use xlink:href="#systemthread" transform="translate(150,40)" />
  <use xlink:href="#systemthread" transform="translate(250,40)" />
</svg>

Unfortunately I can't do this with the first SVG code since I need the texts to be different for each box, while the <use> tag simply duplicates 100% what's defined in <defs>.

Is there any way to use <defs> and <use> with some kind of parameters/arguments mechanism like function calls?

A: 

A way to achieve this with the current svg recommendation is not known to me.

But there is a working draft for a svg 2.0 module, see: SVG Referenced Parameter Variables. The example with the flowers there is exactly what you are looking for I suppose! But then you probably have to wait until june 2010 or even longer until this is a W3C recommendation and supported by clients I assume.

For now you could probably solve it with scripting.

räph
aww too bad i'm ahead of the standard :P .. i guess i'll just stick to repeating the elements inside the svg document since i'd prefer not to use scripting in svg unless if absolutely necessary. The svg document will be generated by php backend anyway ...
Lukman
+1  A: 

I was searching for an answer to my own SVG question. Your question helped me solve my answer, so I am answering yours.

.... Read your question more closely. Included TWO code samples

Sample #1. Boxes with text

Sample #2. Arrows with text

Sample 1

<html>
  <svg xmlns="http://www.w3.org/2000/svg"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       width="600" height="900">
    <defs>
      <g id="my_box"
         desc="my rectangle template">
        <rect width="80" height="30" x="0" y="-20" style="stroke: black; stroke-opacity: 1; stroke-width: 1; fill: #9dc2de" />
      </g>
    </defs>

    <g transform="translate(50 40)">
      <text text-anchor="middle" x="40"> This little box went to market </text>
      <use xlink:href="#my_box" />
    </g>

    <g transform="translate(150 140)">
      <use xlink:href="#my_box" />
      <text text-anchor="middle" x="40"> This little box stayed home </text>
    </g>

    <g transform="translate(250 240)">
      <use xlink:href="#my_box" />
      <text text-anchor="middle" x="40"> This little box had roast beef </text>
    </g>
  </svg>

</html>

Note in sample 1 that the order of the box and text are important.

Sample 2

<html>
  <svg xmlns="http://www.w3.org/2000/svg"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       width="600" height="900">
    <defs>
      <g id="arrow"
         desc="arrow with a long dashed tail">

         <marker style="overflow:visible;fill:inherit;stroke:inherit"
                 id="Arrow1Mend" refX="0.0" refY="0.0" orient="auto">
         <path transform="scale(0.4) rotate(180) translate(20,0)"
               style="fill-rule:evenodd;stroke-width:2.0pt;marker-start:none;"
               d="M 0.0,-15.0 L -20.5,0.0 L 0.0,15.0 "
               desc="The actual commands to draw the arrow head"
         />
         </marker>

        <line transform="translate(0 -450)"
              marker-end="url(#Arrow1Mend)"
              x1="40" y1="10" x2="40" y2="410"
              style="stroke: black; stroke-dasharray: 5, 5; stroke-width: 1; "
              desc="This is the tail of the 'arrow'"
        />
      </g>
    </defs>

    <g transform="translate(100 450)">
      <text> Text BEFORE xlink </text>
      <use xlink:href="#arrow" />
    </g>

    <g transform="translate(200 550)">
      <use xlink:href="#arrow" />
      <text> More to say </text>
    </g>

    <g transform="translate(300 650)">
      <use xlink:href="#arrow" />
      <text> The last word </text>
    </g>

    <g transform="translate(400 750)">
      <use xlink:href="#arrow" />
      <text> Text AFTER xlink </text>
    </g>

  </svg>
</html>
autotroph