+ All Categories
Home > Documents > Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured...

Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured...

Date post: 19-May-2018
Category:
Upload: vunhi
View: 224 times
Download: 10 times
Share this document with a friend
27
Chapter 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not, utilize many different methods to achieve our aim. By this I don’t simply mean the ability to achieve an identical presentation with different graphical elements, for example using the general <path> element to create a rectangle instead of the more specialized and comfortable <rect> element. Nor am I concerned with different styling options via <style> elements or presentation attributes. Essentially I am referring here to the deliberate use of SVG’s structuring elements, which we will also designate as container elements. Let’s start directly into this with an example. Suspend disbelief for a moment, escape the world of design and assume that you are a pallet rack manufacturer, in fact a pallet manufacturer with a penchant for graphical presentations of your products. Below is a pile of your produce. Figure 3-1. The pallet rack Now, you might create the above vector graphics image by coding the following SVG document: <?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <rect x="50" y="20" width="12" height="300" stroke="black" fill="steelblue" /> <rect x="64" y="20" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="64" y="120" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="64" y="220" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="350" y="20" width="12" height="300" stroke="black" fill="steelblue" /> <rect x="364" y="20" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="364" y="120" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="364" y="220" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="650" y="20" width="12" height="300" stroke="black" fill="steelblue" /> <rect x="30" y="320" width="654" height="10" stroke="none" fill="lightgray" />
Transcript
Page 1: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Chapter 3 : Document Structure

Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not, utilize many different methods to achieve our aim. By this I don’t simply mean the ability to achieve an identical presentation with different graphical elements, for example using the general <path> element to create a rectangle instead of the more specialized and comfortable <rect> element. Nor am I concerned with different styling options via <style> elements or presentation attributes.

Essentially I am referring here to the deliberate use of SVG’s structuring elements, which we will also designate as container elements. Let’s start directly into this with an example. Suspend disbelief for a moment, escape the world of design and assume that you are a pallet rack manufacturer, in fact a pallet manufacturer with a penchant for graphical presentations of your products. Below is a pile of your produce.

Figure 3-1. The pallet rack

Now, you might create the above vector graphics image by coding the following SVG document:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <rect x="50" y="20" width="12" height="300" stroke="black" fill="steelblue" /> <rect x="64" y="20" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="64" y="120" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="64" y="220" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="350" y="20" width="12" height="300" stroke="black" fill="steelblue" /> <rect x="364" y="20" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="364" y="120" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="364" y="220" width="284" height="10" stroke="black" fill="steelblue" /> <rect x="650" y="20" width="12" height="300" stroke="black" fill="steelblue" /> <rect x="30" y="320" width="654" height="10" stroke="none" fill="lightgray" />

Page 2: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 2

<line x1="30" y1="320" x2="684" y2="320" stroke="black" /> </svg>

So, what do we have here? Well, a really simple document consisting almost exclusively of <rect> elements. It is compact and somehow elegant. Nevertheless, you are a rack manufacturer and used to thinking in terms of racks, upright posts, beams and pallets. With this in mind your document is not particularly verbose. In order to identify the beams in this document we have to look at those <rect> elements with a width attribute much bigger than their height attribute — not particularly helpful! Despite the documents simple appearance and near-symmetrical pattern, it does not give us many clues to meaning, to what part of the code is doing what, and how it is controlled.

Let us create, then, a document with an identical end-product, but which is richer in structure and organization. If you’ve not already done so I suggest you have a read through the

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <rect id="uprightPost" width="12" height="300" /> <rect id="beam" x="14" y="0" width="284" height="10" /> <g id="column"> <use xlink:href="#beam" x="0" y="0" /> <use xlink:href="#beam" x="0" y="100" /> <use xlink:href="#beam" x="0" y="200" /> <use xlink:href="#uprightPost" x="300" y="0" /> </g> <g id="rack"> <use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="300" y="0" /> <g id="ground"> <rect x="-20" y="300" width="662" height="10" stroke="none" fill="lightgray" /> <line x1="-20" y1="300" x2="642" y2="300" stroke="black" fill="none" /> </g> </g> </defs> <use xlink:href="#rack" x="50" y="20" fill="steelblue" stroke="black" /> </svg>

What a document! You might stare at it, wondering why I consider this second one, with nearly double the size of the first, an improvement — after all, both render the same graphical output. Remember though, that we wanted a more meaningful document, and indeed — the longer you look at the second document’s code, the better we can understand its structure — consisting of racks, upright posts and beams, it is somehow both self-referential and self-explanatory. I won’t discuss the SVG key features used in detail here since we will do this in the rest of this chapter.

Quick Change Just to demonstrate the increased functionality of our second piece of code, let’s suppose we wanted to include the following adjustments:

• A rack with stronger beams • A red rack • A rack with one more column

2

Page 3: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 3

Figure 3-2. Pallet Rack Adjustements

1. We create the first variant with a slight modification of the height attribute in a single line:

<rect id="beam" x="14" y="0" width="284" height="20" /> 2. The second variant is generated by changing the colour in:

use xlink:href="#rack" x="50" y="20" < fill="red" stroke="black" />

3. Finally, we end up in the third variant by adding one single line of SVG code:

<g id="rack">

<use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="300" y="0" />

<use xlink:href="#column" x="600" y="0" />

4. Now try to generate these variants shown above with the first “unstructured” document. Awkward

isn’t it!

So, as a generalization, Structure in documents is the way forward.

Another option So, now that you are now deeply impressed by the potential power of structured documents, but still complaining about the increased file size, take a look at this third document. It results in the same graphical output as the previous two SVG documents.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <g id="rack" externalResourcesRequired="true"> <use xlink:href="RackParts.svg#xpointer(id('uprightPost'))" x="0" y="0" /> <use xlink:href="RackParts.svg# xpointer(id('column'))" x="0" y="0" /> <use xlink:href="RackParts.svg# xpointer(id('column'))" x="300" y="0" /> <g id="ground"> <rect x="-20" y="300" width="662" height="10" stroke="none" fill="lightgray" /> <line x1="-20" y1="300" x2="642" y2="300" stroke="black" fill="none" /> </g> </g> </defs> <use xlink:href="#rack" x="50" y="20" fill="steelblue" stroke="black" /> </svg>

Here again I don’t want to explain the content in detail, but here are some useful characteristics of the document.

3

Page 4: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 4

• The file’s size is even smaller than that of the first unstructured document. • We put the groups uprightPost, beam and column into an external file RackParts.svg. • We simply reference the groups in that external file.

Now you may be thinking — It’s a bluff. As we need the code in the external file, we didn’t actually reduce the total code size. OK. You’re right, to an extent. But the benefit of evacuating SVG elements into external files comes with the magic of sharing code. As you (the pallet manufacturer remember) have to handle not only one rack image, but several hundred different ones, all those different SVG documents will refer to that one single file. That is real code reduction.

Reusing Elements Let’s have a closer look at how SVG’s mighty define once, use everywhere principle works in detail. To do this in an illustrative manner, we will gradually evolve the rack example. We start with two upright posts and three beams.

Figure 3-3. Basic Element

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <!-- the upright posts --> <rect x="50" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <rect x="200" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <!-- the beams --> <rect id="beam" x="62" y="20" width="136" height="8" fill="steelblue" stroke="black" /> <rect id="beam" x="62" y="70" width="136" height="8" fill="steelblue" stroke="black" /> <rect id="beam" x="62" y="120" width="136" height="8" fill="steelblue" stroke="black" /> </svg>

Realizing that the three rectangles of the beams are identical except for their location, we decide to try out SVG’s element reuse concept with them.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <!-- the upright posts --> <rect x="50" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <rect x="200" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <!-- the beams --> <rect id="beam" x="62" y="20" width="136" height="8" fill="steelblue" stroke="black" /> <use xlink:href="#beam" x="0" y="50" /> <use xlink:href="#beam" x="0" y="100" />

4

Page 5: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 5

</svg>

It works, thanks to SVG’s referencing element <use>. The first rectangle is simply cloned – i.e. duplicated – and positioned at the same location as the previous second and third rectangle. So we get an identical image as before. Now it is time to take a closer look at the <use> element’s syntax:

Syntax <use xlink:href=”uri” x=”coordinate” y=”coordinate” width=”length” height=”length” style-attribute=”style-attribute” >

The xlink:href attribute references the target element via it’s id, so we need to provide id attributes for all elements we want to refer to by <use>. Bear in mind that the id’s values must be unique across the document. Since the id’s value must be an XML URI (uniform resource identifier), we can reference any element in any SVG document across the web. Most often you will access elements in your local document (local URI reference) via xlink:href="#name"

but we can also reference elements in external resources (non-local URI reference) by an absolute URI as in

xlink:href="http://www.w3.org/TR/2001/REC-SVG-20010904/images/struct/Use01.svg/#xpointer(id('MyRect'))"

or by a relative URI as in xlink:href="../svglib/Vehicels.svg#xpointer(id('Motorcycle'))"

Using the x and y attribute, we can position our duplicated element in the drawing, and methods of interpreting the attributes values will be discussed later in the chapter, where we examine coordinate systems and transformations. For now, simply add the x and y values to the coordinates of the referenced object to get the correct position. When you omit the x- and y-attribute as in <use xlink:href="#beam" /> the x- and y-values are taken to be zero, so the <use> element is positioned exactly over its referenced original. One drawback of utilizing the <use> element is that we are unable to manipulate the original referenced element’s attributes. While we may make adjustments to the instance we are dealing with, the original will remain the same. We can duplicate it and put it at a different place in the document, but that’s it . As it is so important, here are the characteristics of the <use> element again.

• The <use> element creates a reference to another SVG element. • We must assign an id attribute to those elements that might be reused by <use>. This id

attribute is available for all SVG elements. • The referenced SVG element can reside in the same file, or in another SVG file. This fact

supports the evolving of application specific symbol libraries.

5

Page 6: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 6

• The <use> element cannot change any attributes of the referenced element. • The application of the <use> element on a complex element – a <path> element with lots of

data – can result in a notably reduced file size.

Use All or Nothing Lets have a look at our rack example in more detail. Maybe we can improve it further.

Figure 3-4. A basic element <?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <svg> <!-- the upright posts --> <rect x="50" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <rect x="200" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <!-- the beams --> <rect id="beam" x="62" y="20" width="136" height="8" fill="steelblue" stroke="black" /> <use xlink:href="#beam" x="0" y="50" /> <use xlink:href="#beam" x="0" y="100" /> </svg>

This is the SVG document from above. We didn’t change anything so far, and still want to focus on the structure of the beams.

Spot the difference Just looking at the image it’s impossible to tell which of the beams is the original and which are the clones. We have to look into the code to identify the upper beam as the original element. This may prompt the question…

What is the importance of the original beam over the clones?

The answer is simply “Nothing”. The importance is to be found in our group structure only. Visually there is no difference whatsoever. However, it will of course behave differently, and need to be treated differently.

Assume we want to raise the lower beam by 20 units. No problem, we change the y-attribute of the last <use> element.

<use xlink:href="#beam" x="0" y="90" />

6

Page 7: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 7

Figure 3-5. Modified element

This gives the result seen above. Now lets make a change to the original, the topmost beam.

As we now want to lower the upper beam, we’ll need to change the beam’s original <rect> element. But wait — all of our <use> elements are dependent on the attributes of our original, a change here will affect all instances of our rectangle. Thus, we need to compensate for this in each <use> element.

<rect id="beam" x="62" y="30" width="136" height="8" fill="steelblue" stroke="black" /> <use xlink:href="#beam" x="0" y="40" /> <use xlink:href="#beam" x="0" y="80" />

Figure 3-6. Another modified element

Fine, that works too. But with some more work, as we must modify all affiliated <use> elements. We were lucky we didn’t have to accommodate several hundred beams!

OK. So what did we just learn? The advantage, that the change of an element’s attribute is transparent to all referencing <use> elements, became a disadvantage here.

It would be best, if we didn’t have the original element visible. So we would not have needed to change its position. What if we put the original graphical element into a <def> section?

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <!-- the upright posts --> <rect x="50" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <rect x="200" y="20" width="10" height="150" fill="steelblue" stroke="black" /> <defs> <!-- the beam --> <rect id="beam" width="136" height="8" fill="steelblue" stroke="black" />

7

Page 8: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 8

</defs> <use xlink:href="#beam" x="62" y="30" /> <use xlink:href="#beam" x="62" y="70" /> <use xlink:href="#beam" x="62" y="110" /> </svg>

This markup results in exactly the same image — the difference is that all visible rectangles are simply <use> elements of our original, which is now tucked safely away in a <defs>. This ensures that any changes we make to individual instances will not affect other instances.

If you want to reuse any SVG element, put this element into a <defs> section. This is an important point. As the SVG specification tells us — “For understandability and accessibility reasons, it is recommended that, whenever possible, referenced elements be defined inside of a 'defs.”

Groups Now I want to introduce you to SVG’s most important structural element – the group element <g>.The group element is not a graphics element. That is, it produces no graphical output by itself. It is rather a container element like the <def> element — meant for collecting different elements, mainly other graphics elements and graphics referencing elements, but also other container elements.

Syntax <g id=”<name>” style-attribute=”style-attribute” transform=”transformation commands”> <!-- group’s content here --> </g>

The id attribute is the standard XML attribute for assigning a unique name to an element. It is heavily used with groups. The id attribute must be known to any other element that needs to reference the group. The behaviour of the styling attributes will be discussed later in this chapter.

With that knowledge we now want to build a group column out of the three beams and the right upright post in order to reuse that group later.

Figure 3-7. Column group

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <rect id="uprightPost" width="10" height="150" fill="steelblue" stroke="black" /> <rect id="beam" width="136" height="8" fill="steelblue" stroke="black" /> </defs> <use xlink:href="#uprightPost" x="50" y="20" /> <g id="column"> <use xlink:href="#beam" x="62" y="20" />

8

Page 9: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 9

<use xlink:href="#beam" x="62" y="70" /> <use xlink:href="#beam" x="62" y="120" /> <use xlink:href="#uprightPost" x="200" y="20" /> </g> </svg>

As expected, we don’t see any sensational shift. Nevertheless, we will benefit from this structural improvement soon. A look at the SVG code shows nothing magical. To build a group, just enclose the graphic elements you want to collect within the group tags <g> .. </g>. There are several reasons why we may need to include a group.

• We need to create a meaningful object for reuse. • We want to make your code more self-explaining and collect elements with a common logical

context. • We want the group elements to share particular presentation attributes. • We intend to emulate layers and control their visibility.

Using Groups The usefulness of the <g> element is largely increased by it’s companion — the familiar <use> element. We apply <use> to drawing elements in the same way we use it for groups. So we are finally able to create a real world pallet rack.

Figure 3-8. More elements

Here is the code:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <rect id="uprightPost" width="10" height="150" fill="steelblue" stroke="black" /> <rect id="beam" width="136" height="8" fill="steelblue" stroke="black" /> <g id="column"> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g> </defs> <use xlink:href="#uprightPost" x="50" y="20" /> <use xlink:href="#column" x="50" y="20" /> <use xlink:href="#column" x="200" y="20" /> <use xlink:href="#column" x="350" y="20" /> <use xlink:href="#column" x="500" y="20" /> </svg>

9

Page 10: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 10

As we learned in the section about element reuse, we put the column group into a <defs> section. Now we have only five elements that create graphical output: One instance of uprightPost and three instances of column. Since it is so important, I need to tell you again:

Every group that will be instantiated more than once, should go into a <defs> section.

It is not uncommon to reuse groups in different SVG files. We still know how SVG supports the referencing of elements from other local files or even across the World Wide Web via the xlink:href="uri" attribute. We want to do this now with our rack example. So this results in two files:

RackParts.svg <?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg xmlns="http://www.w3.org/2000/svg"> <defs> <rect id="uprightPost" width="10" height="150" fill="steelblue" stroke="black" /> <rect id="beam" width="136" height="8" fill="steelblue" stroke="black" /> <g id="column"> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g> </defs> </svg>

and Rack.svg

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" externalResourcesRequired="true" xmlns="http://www.w3.org/2000/svg"> <use xlink:href="../parts/RackParts.svg#xpointer(id('uprightPost'))" x="50" y="20" /> <use xlink:href="../parts/RackParts.svg#xpointer(id('column'))" x="50" y="20" /> <use xlink:href="../parts/RackParts.svg#xpointer(id('column'))" x="200" y="20" /> <use xlink:href="../parts/RackParts.svg#xpointer(id('column'))" x="350" y="20" /> <use xlink:href="../parts/RackParts.svg#xpointer(id('column'))" x="500" y="20" /> </svg>

The file RACKPARTS.SVG is located in a subdirectory parts parallel to your current directory where RACK.SVG resides. We have just stepped over the point of no return. No longer will you be able to cope without groups in your SVG files. And since we are getting used to using them, let’s now have a look at structuring our documents with a number of groups.

Nested Groups Remember that I mentioned that a group, as a container element, can collect other SVG elements. Not only graphics elements, but also container elements — in particular other groups. With that we have groups inside of groups or nested groups. You may be quite uncertain now, how to reference nested groups or why you should have nested groups at all. Before we discuss this further, let us explore the nesting of groups with our familiar rack example.

10

Page 11: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 11

Nesting our pallet groups The images in the brochure of your company always have a floor-segment drawn under the rack. To visualize this floor-segment we use a black line and a grey rectangle. Furthermore the beams are missing some details — the fasteners. Ok, we’ll start with the fasteners. 1. Shorten the beams a little and place two small rectangles at each end. 2. Put these three elements into a group named ‘beam’, so that the rest of the SVG document isn’t

affected if we modify this beam. 3. We’ll also define a new group ‘rack’ out of the starting upright post and all columns. We’ll add the

floor-segment’s line and rectangle too.

Figure 3-9. Rack with floor

4. This leaves us with the following code

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <rect id="uprightPost" width="10" height="150" fill="steelblue" stroke="black" /> <g id="beam"> <rect x="0" width="3" height="16" fill="steelblue" stroke="black" /> <rect x="5" width="126" height="8" fill="steelblue" stroke="black" /> <rect x="133" width="3" height="16" fill="steelblue" stroke="black" /> </g> <g id="column"> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g> <g id="rack"> <use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="150" y="0" /> <use xlink:href="#column" x="300" y="0" /> </g> </defs> <use xlink:href="#rack" x="50" y="20" /> <rect x="40" y="170" width="480" height="10" stroke="none" fill="lightgray" /> <line x1="40" y1="170" x2="520" y2="170" stroke="black" /> </svg>

The image looks quite good. Though after having added the line and the rectangle to the document, it looks somewhat unstructured. The rectangle and the line belong logically together. So we feel, we should have a group ‘floor’.

11

Page 12: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 12

5. Implement this group in the following manner

<use xlink:href="#rack" x="50" y="20" /> <g id="floor" /> <rect x="40" y="170" width="480" height="10" stroke="none" fill="lightgray" /> <line x1="40" y1="170" x2="520" y2="170" stroke="black" /> </g>

Ok, that seems to be a bit more structured. Should we now leave the group ‘floor’ where it is or would it be it better placed inside of the <defs> section? Well, we won’t reference this group, so we do not necessarily need to add it to the <defs> section. But perhaps we should think more about where this floor segment belongs. The question we need to address is “Does each rack need its own floor segment?” You, the rack expert, spontaneously answer here: “yes absolutely — since it is very uncommon, that rack images share floor space”. Fine, so the floor group can go into the rack group. It’s really that simple! 6. Make the following adjustments to your code

<g id="rack"> <g id="floor" /> <rect x="-10" y="150" width="480" height="10" stroke="none" fill="lightgray" /> <line x1="-10" y1="150" x2="470" y2="150" stroke="black" /> </g> <use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="150" y="0" /> <use xlink:href="#column" x="300" y="0" /> </g>

If you’re wondering why I inserted the floor group at the beginning of the rack members, rather than appending it at the end, I must say here, it’s only a matter of personal coding style. It is no problem here (due to the fact, that no graphics elements overlap), to have the floor group appended at the existing group members alternatively. Please also note, that we needed to modify the line’s and rectangle’s coordinates a little (we subtracted the coordinates of the last <use> element). This will become more transparent in Chapter 6, where we will talk about coordinate systems and transformations. After looking at the SVG code, you may question: “Why didn’t we define the beam’s group also inside of the column’s group, as it is solely used there too?” Good. I like your thinking. There seem to be no arguments against this remarkable observation. 7. So we update the column group accordingly.

<g id="column"> <defs> <g id="beam"> <rect x="0" width="3" height="16" fill="steelblue" stroke="black" /> <rect x="5" width="126" height="8" fill="steelblue" stroke="black" /> <rect x="133" width="3" height="16" fill="steelblue" stroke="black" /> </g> </defs> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g>

12

Page 13: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 13

Here we could not simply transfer the beam’s group into the column’s group. We had to create a local <defs> section first. Why? Well, we learned, that everything in a <defs> section will not get rendered, it is for referencing only. So what, if we reference the column’s group without its internal <defs> section? Correct – the internal beam’s group would become visible. As we also learned, to put everything into a <defs> section that will be referenced, we have to put it into a <defs> section local to the group. Confusing you may think. Why didn’t we just leave the beam where it was? The answer is (as you should be getting used to by now) — clean document structure.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <rect id="uprightPost" width="10" height="150" fill="steelblue" stroke="black" /> <g id="column"> <defs> <g id="beam"> <rect x="0" width="3" height="16" fill="steelblue" stroke="black" /> <rect x="5" width="126" height="8" fill="steelblue" stroke="black" /> <rect x="133" width="3" height="16" fill="steelblue" stroke="black" /> </g> </defs> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g> <g id="rack"> <g id="ground"> <rect x="-10" y="150" width="480" height="10" stroke="none" fill="lightgray" /> <line x1="-10" y1="150" x2="470" y2="150" stroke="black" /> </g> <use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="150" y="0" /> <use xlink:href="#column" x="300" y="0" /> </g> </defs> <use xlink:href="#rack" x="50" y="20" /> </svg>

Fantastic — a place for everything and everything in its place.

Group rules Here are some rules of thumb on proper group location:

• General purpose groups, that are to be instantiated from anywhere in the same or even from other documents, should be placed in an outermost <defs> section (public group).

• Groups, that are reused exclusively in one enclosing parent group, should be defined in that parent group (private group). So the parent group can be designed as complete as possible.

• Avoid references to an inner group from outside its parent group (public access to a private group).

• Never instantiate a group from inside that group (self-reference). The behaviour is undefined.

Styling of Groups The SVG committee wisely designed the <g> element so that it passes its style to the enclosed elements. What we see then results from the CSS2 inheritance rules.

13

Page 14: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 14

Let’s illustrate this by example. 1. Enter the following markup into a fresh document. Two blue circles are contained in a group.

Figure 3-10. Two blue circles

<g> <circle cx="50" cy="50" r="20" fill="blue" /> <circle cx="100" cy="50" r="20" fill="blue" /> </g>

2. Now, we can make the fill colour a presentation attribute of the enclosing group.

<g fill="blue"> <circle cx="50" cy="50" r="20" /> <circle cx="100" cy="50" r="20" /> </g>

You see that the contained elements inherit their style from,the group. 3. So what happens, if one element has a colour defined and another hasn’t? Lets see

Figure 3-11. Blue group and red circle

<g fill="blue"> <circle cx="50" cy="50" r="20" /> <circle cx="100" cy="50" r="20" fill="red" /> </g>

Fine, if an element wants to have a certain colour – here red – it simply defines that colour by a presentation attribute or via CSS styles. This colour will remain unaffected. Only those elements, that don’t have a colour defined will inherit it from their enclosing group. So if we have a group of elements, that have a lot of style in common, it is always a good idea to define this style by the group. Moreover, if we have to deal with a lot of elements with common style, we should even consider enclosing these elements in a group just to share that style. 4. Just to be sure that this works also with nested groups, we’ll expand our example a bit.

Figure 3-12. Green group and red circle

<g fill="green"> <g> <circle cx="50" cy="50" r="20" />

14

Page 15: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 15

<circle cx="100" cy="50" r="20" fill="red" /> </g> <rect x="130" y="30" width="40" height="40" /> </g>

No surprise here. The inner group, as well as its contained elements inherit the colour from the outer group as expected. Please note, that – for simplicity – I use presentation attributes only here in this chapter. Using CSS styles instead, the above is also true. You should only know, that

When mixing presentation attributes and CSS style sheets, the style sheets have a higher priority over the presentation attributes.

You can override the inheritance rules by the "!important" declaration.

Look at the CSS chapter of this book or read the CSS recommendation to learn more.

Back on the rack 8. Let’s see if we can improve our rack document with what we just learned.

Figure 3-13. Our rack with floor

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <rect id="uprightPost" width="10" height="150" /> <g id="column"> <defs> <g id="beam"> <rect x="0" width="3" height="16" /> <rect x="5" width="126" height="8" /> <rect x="133" width="3" height="16" /> </g> </defs> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g> <g id="rack" fill="steelblue" stroke="black" > <use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="150" y="0" /> <use xlink:href="#column" x="300" y="0" /> <g id="ground"> <rect x="-10" y="150" width="480" height="10" stroke="none" fill="lightgray" /> <line x1="-10" y1="150" x2="470" y2="150" stroke="black" /> </g> </g>

15

Page 16: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 16

</defs> <use xlink:href="#rack" x="50" y="20" /> </svg>

We’ve just omitted every occurrence of fill="steelblue" stroke="black" and given those attributes to the rack’s group instead. It works great and we’ve significantly reduced the size of our document. But what if one of your customers wants the middle column moccasin-coloured? An unusual request, but as a simple pallet supplier, ours is not to reason why!

Figure 3-14. Changing color of beams

This is achieved by adding an individual fill element to the particular rack.

<use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="150" y="0" fill="moccasin" /> <use xlink:href="#column" x="300" y="0" />

Obviously no problem there. But wait, this seems to be remarkable. We didn’t tell the column group to get moccasin-coloured. We told one instance of the column group to get moccasin-coloured. So how does the <use> element influence the group’s styling? Lets have a look, using our basic example.

Figure 3-15. Color in use element

<g fill="green"> <defs> <g id="inner"> <circle cx="50" cy="50" r="20" /> <circle cx="100" cy="50" r="20" fill="red" /> </g> </defs> <rect x="130" y="30" width="40" height="40" /> <use xlink:href="#inner" fill="moccasin" /> </g>

A group seems to be transparent for the styles of its instances, i.e. a group is passing presentation attributes from a referencing <use> element to its contained elements, as long as the group itself does not have that particular presentation attribute defined. In that case the group becomes opaque and blocks the style. Therefore the CSS inheritance rules also apply to group instances.

16

Page 17: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 17

Lets see how this adds to our rapidly expanding structure knowledge. What do we know now?

• Group elements inherit the parent group’s style. • Group elements also inherit the parent group’s instance’ style. • If we want all instances of a group to have the same style, we implement the style in the

group. • If we want the instances of a group to have different styles, we implement the style in

the group’s instances, rather in the group itself.

Symbols SVG provides us with another structuring element, the <symbol> element. It is another container element like its companions <g> and <defs>. In fact it is something in between the two.

1. The <symbol> element contains graphics elements and other container elements. Here it behaves like the <g> element.

2. The <symbol> element’s content is never rendered. It must be instanced by an <use> element. With that it is more like the <defs> container element.

3. The <symbol> element always renders in a rectangular area. For this you will supply a referencing <use> element with additional width and height attributes.

Syntax Lets look at symbols in their working environment <symbol id=”name” viewbox=”min-x min-y width height” preserveAspectRatio="align [meetOrSlice]" style-attribute=”style-attribute” > <!-- symbols’s content here --> </symbol>

and kick off a brand new example.

Working with Symbols Lets have a look at some of the practical implications of using symbols.

1. Start by entering the following markup in your text editor <?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <symbol id="icon" viewBox="0 0 100 100" preserveAspectRatio="none" stroke="blue" stroke-width="5" fill="blue"> <circle cx="50" cy="14" r="14" /> <path fill="none" d="M0,0 L50,40 50,60 0,100 M100,0 L50,40 M100,100 L50,60" /> </symbol> <rect x="50" y="50" width="100" height="100" fill="wheat" stroke="black" /> <use xlink:href="#icon" x="50" y="50" width="100" height="100" /> </svg>

This will hopefully give you the rather interesting graphic shown below.

17

Page 18: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 18

Figure 3-16. A symbol

The symbol consists of a circle – the head – and a path element – the arms, body and legs. We reuse the symbol by the <use> element, that defines a rectangular area 100 units wide and 100 units high. We also provide a true rectangle just to show the borders of this area. The viewBox attribute establishes a new coordinate system, into which the symbol’s graphic elements are drawn. We will discuss the viewBox attribute in more detail in Chapter 7. Just notice here that the viewBox’s rectangle exactly meets the use’s rectangle here initially. 2. Now we want to play a bit with different sizes. So let’s enlarge the use’s rectangle a bit

<symbol id="icon" viewBox="0 0 100 100" preserveAspectRatio="none" … <use xlink:href="#icon" x="50" y="50" width="150" height="100" />

Figure 3-17. Symbol in enlarged rectangle

As we see, the symbols content is scaled non-uniformly so that it fits into the use’s rectangle. To change that behaviour, SVG provides us with a lot of other values for the preserveAspectRatio attribute. Let’s meet one of them 3. Adjust the lines of markup we just worked with again to read

<symbol id="icon" viewBox="0 0 100 100" preserveAspectRatio="xMidyMid meet" … <use xlink:href="#icon" x="50" y="50" width="150" height="100" />

18

Page 19: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 19

Figure 3-18. "xMidyMid meet" preserveAspectRatio

Any value for the preserveAspectRatio attribute other than "none" will result in a uniform scale of the viewBox’s rectangle. The xMidyMid value instructs the SVG rendering engine to coincide with the midpoints of the viewBox’s and the use’s rectangles. The second value “meet” results in a scaling so that the complete viewBox rectangle fits into the use’s rectangle. 4. Now try the following markup

<symbol id="icon" viewBox="0 0 100 100" preserveAspectRatio="xMidyMid slice" … <use xlink:href="#icon" x="50" y="50" width="150" height="100" />

Figure 3-19. "xMidyMid slice" preserveAspectRatio

A second value “slice” causes a scaling so that the viewBox rectangle completely fills out the use’s rectangle. I won’t cover the numerous variants of the preserveAspectRatio attribute’s values here. If you are interested, I suggest, that you look into the SVG specification. There you will find a complete explanation of all variants with an example.

All together now I don’t think that there is a great danger of you confusing the symbol element with the group element. Look at the symbol element more as a rectangular image element, where you can directly draw into. After that you are able to map that rectangle onto an other rectangle to make it visible. Personally I do not use the symbol element often. But we will benefit from knowing it, as both the <pattern> element and the <marker> element use the concepts we’ve just discussed here.

19

Page 20: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 20

Finally, I recommend that whenever you define a symbol element, to put it into a <defs> section. This results in good SVG coding style as everything that is referenced should go into a <defs> section.

Patterns Let’s go back to our rack example. Perhaps our theoretical foreman has been complaining about the visual appearance of the upright posts. The real upright posts don’t look like simple filled rectangles. They rather have equidistant holes along them. This is for saving material and weight. Hmm, the pattern element might be useful here. The spec reads:

A pattern is used to fill or stroke an object using a pre-defined graphic object which can be replicated ("tiled") at fixed intervals in x and y to cover the areas to be painted.

So let’s try it out and have a quick look at the pattern’s syntax.

Syntax Here is an example of pattern in effect. <pattern id=”name” x=”coordinate” y=”coordinate” width=”length” height=”length” patternUnits=”userSpaceOnUse” style-attribute=”style-attribute” > <!-- pattern’s content here --> </pattern>

With the <pattern> element we have yet another container element. It is quite helpful to think of patterns as rectangular tiles. To help illustrate this, have a look at the next example.

Figure 3-20. Two rectangles filled with pattern

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <pattern id="holes" x="0" y="0" width="50" height="50" patternUnits="userSpaceOnUse"> <rect x="0" y="0" width="50" height="50" stroke="black" fill="lightgray" /> <circle cx="25" cy="25" r="20" fill="blue" /> </pattern> </defs> <rect x="50" y="50" width="200" height="150" fill="url(#holes)" stroke="black" /> <rect x="275" y="50" width="200" height="150" fill="url(#holes)" stroke="black" /> </svg>

20

Page 21: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 21

One pattern tile consists of a lightgray square with a size of 50 units and a centred blue circle. When we fill the 200 units wide and 150 units high rectangles with these pattern tiles, we are a bit surprised to achieve the above image. This behaviour is due to the fact, that the first tile starts in the origin of the documents coordinate system, which is in the upper left corner of SVG canvas. This results in seemingly fixed pattern tiles, that only shine through those shapes, that are using the tiles for filling. Just to test this, we move the rectangles a little to the right.

Figure 3-21. Moving Rectangles

<rect x="75" y="50" width="200" height="150" fill="url(#holes)" stroke="black" /> <rect x="300" y="50" width="200" height="150" fill="url(#holes)" stroke="black" />

As this is what we expected here, it is not always what we want. To have the coordinate systems used by the pattern fixed with object to fill, we can use the fact, that every group establish an own coordinate system. We will discuss this more detailed in Chapter 7. So all we have to do now, is to enclose one rectangle in a group and reuse that group twice.

Figure 3-22. "userSpaceOnUse" for patternUnits

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <pattern id="holes" width="50" height="50" patternUnits="userSpaceOnUse"> <rect x="0" y="0" width="50" height="50" stroke="black" fill="lightgray" /> <circle cx="25" cy="25" r="20" fill="blue" /> </pattern> <g id="rect"> <rect width="200" height="150" fill="url(#holes)" stroke="black" /> </g> </defs> <use xlink:href="#rect" x="50" y="50" /> <use xlink:href="#rect" x="275" y="50" />

21

Page 22: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 22

</svg>

The pattern’s origin can then be moved by the values of the x- and y- attribute.

<pattern id="holes" width="50" height="50" patternUnits="userSpaceOnUse">

Now, that we know how patterns work, it should be easy, to add the holes in your upright posts.

Figure 3-23. Rack with holes on beams

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <pattern id="holes" width="10" height="10" patternUnits="userSpaceOnUse"> <rect width="10" height="10" stroke="none" fill="steelblue" /> <circle cx="5" cy="5" r="2" fill="lightgray" /> </pattern> <g id="uprightPost"> <rect width="10" height="150" fill="url(#holes)" stroke="black" /> </g> <g id="column"> <defs> <g id="beam"> <rect x="0" width="3" height="16" /> <rect x="5" width="126" height="8" /> <rect x="133" width="3" height="16" /> </g> </defs> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g> <g id="rack" fill="steelblue" stroke="black" > <g id="ground"> <rect x="-10" y="150" width="480" height="10" stroke="none" fill="lightgray" /> <line x1="-10" y1="150" x2="470" y2="150" stroke="black" /> </g> <use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="150" y="0" /> <use xlink:href="#column" x="300" y="0" /> </g> </defs> <use xlink:href="#rack" x="50" y="20" /> </svg>

Markers Very delighted about the new look of the upright posts you say: “ And if we finally could add dimensions to the racks, SVG would be appropriate for our new brochure.”

22

Page 23: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 23

Ok, so let’s look at markers. The SVG specification states:

A marker is a symbol which is attached to one or more vertices of ‘path’, ’line’, ’polyline’ and ‘polygon’ elements.

Sounds good. Here is the syntax for <marker> element.

Syntax <marker id=”name” refX=”coordinate” refY=”coordinate” markerWidth=”length” markerHeight=”length” markerUnits=”strokeWidth | userSpaceOnUse” viewBox=”min-x min-y width height” orient=”auto | angle” style-attribute=”style-attribute” > <!-- pattern’s content here --> </marker>

The <marker> element like its companion – the pattern – is a container element. Since we want to attach arrowheads to a line, we design the arrow offline first. For this we use a path element.

<path d="M0,0 L20,-4 20,4 z M0,-10 L0,10" stroke="black" />

In order to integrate this path in our new marker, we should illustrate some coordinates and lengths first.

Figure 3-24. Detailled arrow marker

<marker id="arrow" viewBox="0 -10 20 20" markerUnits="userSpaceOnUse" markerWidth="20" markerHeight="20" orient="auto"> <path d="M0,0 L20,-4 20,4 z M0,-10 L0,10" stroke="black" /> </marker>

As usual with SVG there are several ways to make things work. I will show you my preferred method here. Starting to make a marker, we first create a little sketch of it. We mark the origin of our locale marker coordinate system with (0,0). This is also the marker’s point, that will be placed onto the line’s start- , mid- or endpoint. Then you designate the dimensions of the marker’s bounding box. Given these, you can then determine the coordinates of the bounding box’s upper left corner with respect to the marker’s coordinate system.

23

Page 24: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 24

1. Fill the viewBox attribute with the coordinates of the bounding box’s upper left corner, its width and its height in exactly that order.

2. Give the markerWidth attribute the value of your bounding box’s width. 3. Give the markerHeight attribute the value of your bounding box’s height. 4. Create the <marker>’s contained elements using coordinates with respect to the marker’s locale

coordinate system’s origin. Ok? Now that we know, how to create little markers, we should also be able to put them onto a path, line, polyline, etc.. To support markers, all those elements support the marker-start, marker-mid, and marker-end attributes. With the help of these attributes we can assign separate marker symbols to the start-point, the end-point and all mid-points. So let’s now complete our dimension line with what we know.

Figure 3-25. Line with arrows at each side

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <marker id="startArrow" viewBox="0 -10 20 20" markerUnits="userSpaceOnUse" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto"> <path d="M0,0 L20,-4 20,4 z M0,-10 L0,10" stroke="black" /> </marker> <marker id="endArrow" viewBox="-20 -10 20 20" markerUnits="strokeWidth" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto"> <path d="M-20,-4 L0,0 -20,4 z M0,-10 L0,10" stroke="black" /> </marker> </defs> <line x1="50" y1="150" x2="500" y2="50" stroke="black" marker-start="url(#startArrow)" marker-end="url(#endArrow)" /> </svg>

Since the start- and end-arrow must have different directions, we had to define two different markers "startArrow" and "endArrow". Thanks to the orient="auto" attribute value the markers will align themselves to the line’s direction. With this we can finally dimension the rack.

24

Page 25: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 25

Figure 3-26. Rack and dimensions

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <svg> <defs> <marker id="startArrow" viewBox="0 -10 20 20" markerUnits="userSpaceOnUse" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto"> <path d="M0,0 L20,-4 20,4 z M0,-10 L0,10" stroke="black" /> </marker> <marker id="endArrow" viewBox="-20 -10 20 20" markerUnits="strokeWidth" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto"> <path d="M-20,-4 L0,0 -20,4 z M0,-10 L0,10" stroke="black" /> </marker> <!-- previous <defs> content goes here --> </defs> <use xlink:href="#rack" x="50" y="20" /> <g id="dimensions"> <line x1="50" y1="210" x2="512" y2="210" stroke="black" marker-start="url(#startArrow)" marker-end="url(#endArrow)" /> <text x="281" y="205" text-anchor="middle">462</text> <line x1="540" y1="20" x2="540" y2="170" stroke="black" marker-start="url(#startArrow)" marker-end="url(#endArrow)" /> <text x="545" y="95">150</text> </g>

</svg>

In the case, where you want your markers to grow and shrink with the stroke-width of the line, you might use markerUnits="strokeWidth" instead.

Visibility of Groups You may not always want to have all elements of an SVG document visible at every time. To change the visibility control of certain elements you have to make some changes to your document structure. The best way is to build so called layers. These layers contain elements that belong together logically. For this task the <group> element is the ideal instrument. The first step will be , to collect all elements that should become visible/invisible in one group. SVG or exactly CSS2 provides us with two presentation attributes display and visibility to control the visibility of elements. I recommend, to use the visibility attribute with a group, when you want to control the visibility of the contained elements.. With that we can override the visibility attribute for particular group members.

25

Page 26: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 26

Read the Chapter 11.5 of the SVG recommendation, if you want to learn more about the differences between the display and visibility attributes. Now assume, we want to control the visibility of the rack’s dimensions. For this we have to

1. Add the visibility attribute to the group. 2. Ensure that no element in the dimensions group has its visibility attribute explicitly set.

Figure 3-27. Hide/show rack dimensions

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <defs> <marker id="startArrow" viewBox="0 -10 20 20" markerUnits="userSpaceOnUse" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto"> <path d="M0,0 L20,-4 20,4 z M0,-10 L0,10" stroke="black" /> </marker> <marker id="endArrow" viewBox="-20 -10 20 20" markerUnits="strokeWidth" refX="0" refY="0" markerWidth="20" markerHeight="20" orient="auto"> <path d="M-20,-4 L0,0 -20,4 z M0,-10 L0,10" stroke="black" /> </marker> <pattern id="holes" width="10" height="10" patternUnits="userSpaceOnUse"> <rect width="10" height="10" stroke="none" fill="steelblue" /> <circle cx="5" cy="5" r="2" fill="lightgray" /> </pattern> <g id="uprightPost"> <rect width="10" height="150" fill="url(#holes)" stroke="black" /> </g> <g id="column"> <defs> <g id="beam"> <rect x="0" width="3" height="16" /> <rect x="5" width="126" height="8" /> <rect x="133" width="3" height="16" /> </g> </defs> <use xlink:href="#beam" x="12" y="0" /> <use xlink:href="#beam" x="12" y="50" /> <use xlink:href="#beam" x="12" y="100" /> <use xlink:href="#uprightPost" x="150" y="0" /> </g> <g id="rack" fill="steelblue" stroke="black" > <g id="ground"> <rect x="-10" y="150" width="480" height="10" stroke="none" fill="lightgray" /> <line x1="-10" y1="150" x2="470" y2="150" stroke="black" /> </g> <use xlink:href="#uprightPost" x="0" y="0" /> <use xlink:href="#column" x="0" y="0" /> <use xlink:href="#column" x="150" y="0" />

26

Page 27: Chapter 3 : Document Structure - Carl Petersheim 3 : Document Structure Benefits of Structured Documents When creating a graphical presentation with SVG we can, more often than not,

Learn SVG Chapter 3 Document Structure 27

<use xlink:href="#column" x="300" y="0" /> </g> </defs> <use xlink:href="#rack" x="50" y="20" /> <g id="dimensions" visibility="visible"> <line x1="50" y1="210" x2="512" y2="210" stroke="black" marker-start="url(#startArrow)" marker-end="url(#endArrow)" /> <text x="281" y="205" text-anchor="middle">462</text> <line x1="540" y1="20" x2="540" y2="170" stroke="black" marker-start="url(#startArrow)" marker-end="url(#endArrow)" /> <text x="545" y="95">150</text> </g> </svg>

With this complete rack document you now don’t only have SVG based images for your print brochure, you also can extend it easily to a dynamic document for your e-commerce projects. The visitor of your rack product sites can magically make the dimensions appear with a simple button press. How we can accomplish this kind of interactivity, we will explore in more detail in the scripting chapter of this book.

27


Recommended