Generate SVG with XSLT

With XSLT, you can create and alter SVG documents on the fly.

Scalable Vector Graphics [Hack #66] provides an interoperable framework for creating graphics that, as XML documents, can be easily stored, transported, displayed in a web browser, and integrated into web pages and other applications. Two-dimensional line art, charts, and art of all kinds are possible with SVG. This hack will walk you through a simple business application using SVG and XSLT.

SVG isn’t always simple markup, but using XSLT you can use simple markup, separate from SVG, that can be transformed or merged into more complex SVG markup. For example, let’s say that your company regularly produces charts that reflect quarterly sales figures. You can keep the sales data in a small XML document and then integrate it into SVG with XSLT.

sales-2004Q2.xml (Example 3-45) is a brief document that expresses sales figures for the Eastern United States as a percentage of a $100,000 USD target.

Example 3-45. sales-2004Q2.xml

<?xml version="1.0" encoding="UTF-8"?>
   
<sales>
 <region>
  <title>Eastern Region Quarterly Sales (Second/'04)</title>
  <key1 area="New York Area">.95</key1>
  <key2 area="Virginia Area">.89</key2>
  <key3 area="Maryland Area">.67</key3>
  <key4 area="Connecticut Area">.65</key4>
  <key5 area="Delaware Area">.45</key5>
 </region>
</sales>

With XSLT, you can merge this data with an SVG document that produces a bar graph using the stylesheet bar.xsl (Example 3-46).

Example 3-46. bar.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="sales">
<svg width="650" height="500">
 <g id="axis" transform="translate(0 500) scale(1 -1)">
  <line id="axis-y" x1="30" y1="20" x2="30" y2="450"
   style="fill:none;stroke:rgb(0,0,0);stroke-width:2"/>
  <line id="axis-x" x1="30" y1="20" x2="460" y2="20"
   style="fill:none;stroke:rgb(0,0,0);stroke-width:2"/>
 </g>

   <xsl:apply-templates select="region"/>

</svg>
</xsl:template>

<xsl:template match="region">
 <g id="bars" transform="translate(30 479) scale(1 -430)">
  <rect x="30" y="0" width="50" height="{key1}"
   style="fill:rgb(255,0,0);stroke:rgb(0,0,0);stroke-width:0"/>
  <rect x="100" y="0" width="50" height="{key2}"
   style="fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:0"/>
  <rect x="170" y="0" width="50" height="{key3}"
   style="fill:rgb(255,255,0);stroke:rgb(0,0,0);stroke-width:0"/>
  <rect x="240" y="0" width="50" height="{key4}"
   style="fill:rgb(0,255,255);stroke:rgb(0,0,0);stroke-width:0"/>
  <rect x="310" y="0" width="50" height="{key5}"
   style="fill:rgb(0,0,255);stroke:rgb(0,0,0);stroke-width:0"/>
 </g>
 <g id="scale" transform="translate(29 60)">
  <text id="scale1" x="0px" y="320px"
   style="text-anchor:end;fill:rgb(0,0,0);font-size:10;font-family:Arial">$25K
</text>
  <text id="scale2" x="0px" y="215px"
   style="text-anchor:end;fill:rgb(0,0,0);font-size:10;font-family:Arial">$50K
</text>
  <text id="scale3" x="0px" y="107.5px"
   style="text-anchor:end;fill:rgb(0,0,0);font-size:10;font-family:Arial">$75K
</text>
  <text id="scale4" x="0px" y="0px"
   style="text-anchor:end;fill:rgb(0,0,0);font-size:10;font-family:Arial">$100K
</text>
 </g>
 <g id="key">
  <rect id="key1" x="430" y="80" width="25" height="15"
   style="fill:rgb(255,0,0);stroke:rgb(0,0,0);stroke-width:1"/>
  <rect id="key2" x="430" y="100" width="25" height="15"
   style="fill:rgb(0,255,0);stroke:rgb(0,0,0);stroke-width:1"/>
  <rect id="key3" x="430" y="120" width="25" height="15"
   style="fill:rgb(255,255,0);stroke:rgb(0,0,0);stroke-width:1"/>
  <rect id="key5" x="430" y="140" width="25" height="15"
   style="fill:rgb(0,255,255);stroke:rgb(0,0,0);stroke-width:1"/>
  <rect id="key4" x="430" y="160" width="25" height="15"
   style="fill:rgb(0,0,255);stroke:rgb(0,0,0);stroke-width:1"/>
 </g>
  <text id="key1-text" x="465px" y="92px"
   style="fill:rgb(0,0,0);font-size:18;font-family:Arial">
   <xsl:value-of select="key1/@area"/>
  </text>
  <text id="key2-text" x="465px" y="112px"
   style="fill:rgb(0,0,0);font-size:18;font-family:Arial">
   <xsl:value-of select="key2/@area"/>
  </text>
  <text id="key3-text" x="465px" y="132px"
   style="fill:rgb(0,0,0);font-size:18;font-family:Arial">
   <xsl:value-of select="key3/@area"/>
  </text>
  <text id="key4-text" x="465px" y="152px"
   style="fill:rgb(0,0,0);font-size:18;font-family:Arial">
   <xsl:value-of select="key4/@area"/>
  </text>
  <text id="key5-text" x="465px" y="172px"
   style="fill:rgb(0,0,0);font-size:18;font-family:Arial">
   <xsl:value-of select="key5/@area"/>
  </text>
 <g id="title">
  <text x="325px" y="20px"
   style="text-anchor:middle;fill:rgb(0,0,0);font-size:24;font-family:Arial">
    <xsl:value-of select="title"/>
  </text>
 </g>
</xsl:template>
   
</xsl:stylesheet>

The template on line 4 matching sales sets up the SVG document, and the template on line 18 matching region fills it out. Lines 20, 22, 24, 26, and 28 use attribute value templates to include the content of the key1, key2, key3, key4, and key5 elements in sales-2004Q2.xml to set the height of the bars. The fill property, along with rgb(), controls the colors used. Play with the triplets in rgb() to change colors.

The value-of elements on lines 55, 59, 63, 67, and 71 grab the area attribute values on the key elements, placing this information on the right of the bars. The value-of on line 76 takes the content of the title element of the source and places it over the top of the bars.

Transform sales-2004Q2.xml with bar.xsl, saving the output to the file sales-2004Q2.svg, like this:

xalan -o sales-2004Q2.svg sales-2004Q2.svg bar.xsl

To see the result, open sales-2004Q2.svg in Netscape 7.1 with the Corel SVG plug-in installed (http://www.corel.com/svgviewer/), as shown in Figure 3-27.

sales-2004Q2.svg in Netscape 7.1 with Corel’s SVG Viewer

Figure 3-27. sales-2004Q2.svg in Netscape 7.1 with Corel’s SVG Viewer

See Also

  • Inspired by Sal Mangano’s XSLT Cookbook (O’Reilly), pages 324-332.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.113.197