Screen Shot

 

  1. The XML File Structure

    This article basically shows how to generate bar/column charts using an extensible stylesheet template and an XML source file. For our example, we will use fictitional sales data from ACME Sales department.

    Our XML file looks like the file structure below:

    <?xml version="1.0" ?>
    <root text="1" value="2">
        
    <title>ACME Profits for 2000</title>
        
    <headers>
             
    <header>Product</header>
             
    <header>Sales</header>
        
    </headers>
        
    <records>
             
    <record>
                  
    <field>Gold</field>
                  
    <field>10000000</field>
             
    </record>         
             
    <record>
                  
    <field>Platinum</field>
                  
    <field>11000005.95</field>
             
    </record>
              ...         
        
    </records>
    </root>

    Our goal is to create a bar chart that looks like the screen shot above


     
  2. The bar chart templates

                  
         <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        
    <xsl:variable name="root" select="/root" />
        
    <xsl:variable name="text" select="$root/@text" />
        
    <xsl:variable name="value" select="$root/@value" />
        
    <xsl:variable name="colors" select="document('colors.xml')/colors" />
        
    <xsl:variable name="barWidth" select="30" />
        
    <xsl:variable name="maxValue" select="20000000" />
        
    <xsl:variable name="maxHeight" select="300" />
        
    <xsl:variable name="ratio" select="number($maxHeight div $maxValue)" />
        
    <xsl:template match="root">
             
    <table width="*" height="{$maxHeight + 20}" align="center" cellspacing="0" cellpadding="0" border="0">
                  
    <xsl:apply-templates select="title" />
                  
    <tr>
                       
    <td align="bottom">
                            
    <xsl:apply-templates select="records" />
                       
    </td>
                       
    <td width="20"></td>
                       
    <td>
                            
    <xsl:call-template name="graph-key">
                                 
    <xsl:with-param name="keys" select="$root/records" />
                            
    </xsl:call-template>
                       
    </td>
                  
    </tr>
             
    </table>
        
    </xsl:template>
        
        
        
    <xsl:template match="records">
             
    <table height="100%" cellspacing="0" cellpadding="0" border="0">
                  
    <tr>
                       
    <xsl:apply-templates />
                  
    </tr>
             
    </table>
        
    </xsl:template>
        
    <xsl:template match="record">
             
    <xsl:call-template name="bars-template">
                  
    <xsl:with-param name="bars" select="." />
                  
    <xsl:with-param name="barIndex" select="position()" />
             
    </xsl:call-template>
        
    </xsl:template>
        
    <!--*********bars template************-->
        
    <xsl:template name="bars-template">
             
    <xsl:param name="bars" />
             
    <xsl:param name="barIndex" />
             
    <xsl:variable name="bar" select="$bars/field[number($value)]" />
             
    <xsl:if test="number($barIndex) = 1">
                  
    <td valign="bottom" style="border-right:1px solid black;">
                       
    <xsl:call-template name="bar-start" />
                  
    </td>
             
    </xsl:if>
             
    <xsl:for-each select="$bar">
                  
    <xsl:variable name="barValue" select="." />
                  
    <td valign="bottom">
                       
    <xsl:call-template name="bar-template">
                            
    <xsl:with-param name="height" select="round($barValue * $ratio)" />
                            
    <xsl:with-param name="color" select="$colors/color[number($barIndex)]" />
                       
    </xsl:call-template>
                  
    </td>
             
    </xsl:for-each>
             
    <xsl:if test="number($barIndex)=last()">
                  
    <td valign="bottom">
                       
    <xsl:call-template name="bar-template" />
                  
    </td>
             
    </xsl:if>
        
    </xsl:template>
        
    <!-- ****************************bar template ******************-->
        
    <xsl:template name="bar-template">
             
    <xsl:param name="height" />
             
    <xsl:param name="color" />
             
    <table height="{$height}" cellspacing="0" cellpadding="0" border="0">
                  
    <tr>
                       
    <td height="{$height}" bgcolor="{$color}" width="{$barWidth}"></td>
                  
    </tr>
                  
    <tr>
                       
    <td width="{$barWidth}">
                            
    <span style="font-size:5pt;border-right:1px solid black;border-top:1px solid black;width:{$barWidth};height:1;"></span>
                       
    </td>
                  
    </tr>
             
    </table>
        
    </xsl:template>
        
    <!-- **************************** bar start ******************-->
        
    <xsl:template name="bar-start">
             
    <table height="{$maxHeight}" cellspacing="0" cellpadding="0" border="0">
                  
    <tr>
                       
    <td height="{$maxHeight}" width="{$barWidth}" >
                       
                       
    </td>
                  
    </tr>
                  
    <tr>
                       
    <td width="{$barWidth}">
                            
    <span style="font-size:5pt;border-top:1px solid black;width:{$barWidth};height:1;"></span>
                       
    </td>
                  
    </tr>
             
    </table>
        
    </xsl:template>
        
    <!-- **************************** graph keys ******************-->
        
    <xsl:template name="graph-key">
             
    <xsl:param name="keys" />
             
    <xsl:variable name="key" select="$keys/record" />
             
    <table>
                  
    <xsl:for-each select="$key">
                       
    <xsl:variable name="index" select="position()" />
                       
    <xsl:variable name="caption" select="field[number($text)]" />
                       
    <xsl:variable name="amount" select="field[number($value)]" />
                       
    <xsl:variable name="color" select="$colors/color[$index]" />
                       
    <tr>
                            
    <td width="10" bgcolor="{$color}"></td>
                            
    <td>
                                 
    <xsl:value-of select="$caption" />
                            
    </td>
                            
    <td>
                                 
    <xsl:value-of select="format-number($amount,'$#,#00.00')" />
                            
    </td>
                       
    </tr>
                  
    </xsl:for-each>
             
    </table>
        
    </xsl:template>
    </xsl:stylesheet>


  3. Article source code(JavaScript/XSL)