The Visual Display of Quantitative XML
by Fabio Arciniegas A.
|
Pages: 1, 2, 3, 4
The City Layout
The first item is the representation of the city blocks. Some cities, like Washington D.C and New York, are arranged in a rectangular grid. Other cities have somewhat consistent block sizes (e.g. Bogotá). While in reality there are many exceptions to these rules, like diagonals and bigger blocks, for our city we will take an idealized view and assume a regular grid of blocks and streets. This convention will give us the chance to get warmed up with some simple SVG shapes and their systematic generation using XSLT.
So let's draw a simple city block as a rounded-corners rectangle. Listing 2 shows the SVG necessary.
Listing 2. A City Block
(source)
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- As you can see, the structure of this
simple SVG document is pretty straightforward: the
root element defines the size of the picture, and
the inner elements describe the constituent shapes
-->
<svg width="2in" height="2in" xmlns="http://www.w3.org/2000/svg">
<title>Block</title>
<desc>A City Block</desc>
<!-- rx and ry define how round the corners of
the rectangle should be -->
<rect x="2" y="2" rx="5" ry="5" width="30" height="20"
fill="none" stroke="black"/>
</svg>
Figure 3: A City Block (prototype-singleBlock.svg)
There are three important things to note about this simple listing.
|
Related Reading
|
-
SVG's DOCTYPE and namespace. These values don't change; it's smart to have a basic template so you don't have to remember them every time you start from scratch.
-
Width and height of the image. We specify this on the root element. In this case we want a rectangle of side 2 inches.
-
The use of the basic shape rect for drawing the rounded-edge rectangle. Look in the references at the end of this article for a complete list of elements and their attributes.
Listing 3 shows a simple XSLT stylesheet to repeat these rounded squares, creating the basic layout for our map. Since XSLT doesn't have mutable variables the way most other languages do, we need to implement the repetition of blocks by calling the templates recursively. If you are comfortable with the idea of recursion, the following listing should be familiar, but if you have doubts, jump to the commented source code.
Listing 3. Creating the city grid with an XSLT repetition
(source)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="blockHeight">20</xsl:variable>
<xsl:variable name="blockWidth">30</xsl:variable>
<xsl:variable name="streetWidth">10</xsl:variable>
<xsl:template match="/">
<svg width="90in" height="90in"
xmlns="http://www.w3.org/2000/svg">
<title>Basic Blocks</title>
<desc>A Simple Repetition Of Blocks</desc>
<xsl:call-template name="blocks">
<xsl:with-param name="vertical">7</xsl:with-param>
<xsl:with-param name="horizontal">9</xsl:with-param>
</xsl:call-template>
</svg>
</xsl:template>
<xsl:template name="blocks">
<xsl:param name="vertical"/>
<xsl:param name="horizontal"/>
<xsl:if test="$vertical > 0">
<xsl:call-template name="row_of_blocks">
<xsl:with-param name="number">
<xsl:value-of select="$horizontal"/>
</xsl:with-param>
<xsl:with-param name="y">
<xsl:value-of select="$vertical *
($blockHeight + $streetWidth)"/>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="blocks">
<xsl:with-param name="vertical">
<xsl:value-of select="$vertical - 1"/>
</xsl:with-param>
<xsl:with-param name="horizontal">
<xsl:value-of select="$horizontal"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="row_of_blocks">
<xsl:param name="number"/>
<xsl:param name="y"/>
<xsl:if test="$number > 0">
<rect x="{$number * ($blockWidth + $streetWidth)}"
y="{$y}"
rx="5"
ry="5"
width="{$blockWidth}"
height="{$blockHeight}"
fill="none"
stroke="black"/>
<xsl:call-template name="row_of_blocks">
<xsl:with-param name="number">
<xsl:value-of select="$number - 1"/>
</xsl:with-param>
<xsl:with-param name="y">
<xsl:value-of select="$y"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Figure 4: All the City Blocks (right-click for source)
Marking the City Streets
Now that we have the city blocks, we need to mark the streets, which will showcase two common aspects of XSLT-SVG production: generating labels and series of numbers. Just as we did with the blocks, let's first manually create the SVG needed to put one label for a particular street, then we'll generalize the procedure using XSLT. In order to output the name of the street we use the SVG text element as shown in listing 4.
Listing 4: City Blocks with a Few Streets Marked
<!-- The rest of the file, including the surrounding svg
element, remains the same as source for Figure 4 -->
<rect stroke="black" fill="none"
height="20" width="30" ry="2"
rx="2" y="168" x="306" />
<!-- STREET NAME -->
<text x="300" y ="200"
style="font-family:Arial;
font-size:8pt">8<tspan
style="font-size:7pt">th</tspan></text>
<rect stroke="black" fill="none"
height="20" width="30" ry="2"
rx="2" y="168" x="272" />
<!-- STREET NAME -->
<text x="268" y ="200"
style="font-family:Arial;
font-size:8pt">7<tspan
style="font-size:7pt">th</tspan></text>
<rect stroke="black" fill="none"
height="20" width="30" ry="2"
rx="2" y="168" x="238"/>
Adding basic text with SVG is quite intuitive, just specify the
upper left corner of the bounding box using the x and
y attributes, and then add the desired style using CSS
inside the style attribute. To tweak the presentation of
the text, I have added a small tspan -- similar to a span
element in an HTML document -- which allows us to apply a slightly
different formatting for the "th" part of the street mark
(in this business little details are really important). SVG has many
fancy text options like aligning it to a curve path (see examples at
this Sun's web
site); these features are no doubt nice and useful for artistic
production, but try to avoid them when developing graphics to
represent data. They tend to clutter your information with unnecessary
decoration and distract the user.
Here we have another rule of thumb: don't use snazzy effects only because they are available. Communicating complex data in an efficient manner is your goal. XSLT and SVG are your tools. Put the tools to the service of your goal, not the other way around.
