2012年12月3日月曜日

Document Structure

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.

 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.

( view this picture as svg )

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'.

 1.      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!

2.      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 inChapter 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.

3.      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>

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="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>    </defs>    <use xlink:href="#rack" x="50" y="20" />  </svg>    Fantastic — a place for everything and everything in its place.

0 件のコメント:

コメントを投稿