<?xml version="1.0" encoding="utf-8"?> <!-- | MIT License | | Copyright 2014 White Magic Software, Inc. +--> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://exslt.org/math" extension-element-prefixes="math"> <xsl:variable name="PI" select="math:constant( 'PI', 33 )"/> <xsl:variable name="RADIANS" select="$PI div 180.0"/> <xsl:include href="colour.xsl"/> <!-- Pie chart width and height. --> <xsl:variable name="width" select="200"/> <xsl:variable name="height" select="$width"/> <xsl:template match="resources"> <xsl:apply-templates mode="piechart"/> </xsl:template> <xsl:template match="expenses"> <div class="expenses"> <xsl:apply-templates mode="piechart"/> <xsl:apply-templates select="dataset"/> </div> </xsl:template> <xsl:template match="//dataset/*[name()='data' or name()='footer']/value"> <div class="value"><xsl:value-of select="format-number(., '###,###')"/></div> </xsl:template> <!-- Convert XML data into a pie chart. --> <xsl:template match="dataset" mode="piechart"> <!-- Number of wedges. --> <xsl:variable name="wedges" select="count(data)"/> <!-- Calculate the sum of all wedge values. --> <xsl:variable name="total" select="sum(data//value)"/> <div class="chart"> <div class="graph"> <svg width="{$width}" height="{$height}" version="1.1" xmlns="http://www.w3.org/2000/svg"> <xsl:for-each select="data"> <xsl:apply-templates select="value" mode="piechart"> <xsl:with-param name="colour"> <xsl:call-template name="fill"> <xsl:with-param name="wedge" select="position()"/> <xsl:with-param name="wedges" select="$wedges"/> <xsl:with-param name="colour" select="$base_colour"/> </xsl:call-template> </xsl:with-param> <xsl:with-param name="total" select="$total"/> <xsl:with-param name="runningTotal" select="sum(preceding-sibling::data/value)"/> <xsl:with-param name="radius" select="$width * 0.5"/> </xsl:apply-templates> </xsl:for-each> </svg> </div> <!-- SVG 1.1 has no text flow abilities. --> <table class="legend" id="legend" name="legend"> <thead> <tr> <th colspan="2">Expense</th> <th>Amount</th> <th></th> </tr> </thead> <tbody> <xsl:for-each select="data//name"> <xsl:variable name="colour"> <xsl:call-template name="fill"> <xsl:with-param name="wedge" select="position()"/> <xsl:with-param name="wedges" select="$wedges"/> <xsl:with-param name="colour" select="$base_colour"/> </xsl:call-template> </xsl:variable> <xsl:variable name="amount" select="format-number(../value, '###,###')"/> <xsl:variable name="percent" select="format-number(../value div $total, '0.00%')"/> <tr class="wedge"> <td class="bullet"> <div class="bullet" style="background-color:{$colour}"/> </td> <td class="category"><xsl:value-of select="."/></td> <td class="amount"><xsl:value-of select="$amount"/></td> <td class="percent"><xsl:value-of select="$percent"/></td> </tr> </xsl:for-each> </tbody> <tfoot> <tr> <td></td> <td class="total">Total</td> <td class="footer"> <xsl:value-of select="format-number(footer/value, '###,###')"/> </td> </tr> </tfoot> </table> <div class="legend"> </div> </div> </xsl:template> <!-- | Creates a pie wedge path. | | http://www.svgopen.org/2003/papers/CreatingSVGPieChartsThroughWebService | http://jbkflex.wordpress.com/2011/07/28/creating-a-svg-pie-chart-html5 | http://www.codestore.net/store.nsf/unid/epsd-5dtt4l +--> <xsl:template match="value" mode="piechart"> <!-- Colour of the pie wedge. --> <xsl:param name="colour"/> <!-- Sum of all the wedge values. --> <xsl:param name="total"/> <!-- Sum of all preceding wedge values. --> <xsl:param name="runningTotal"/> <!-- Pie radius. --> <xsl:param name="radius"/> <!-- Hover text. --> <xsl:variable name="title" select="concat(../name,' (',format-number(., '###,###'),')')"/> <!-- Set the start and ending angles. --> <xsl:variable name="sa" select="360.0 * ($runningTotal div $total)"/> <xsl:variable name="ea" select="360.0 * (($runningTotal + .) div $total)"/> <!-- Calculate the starting Cartesian coordinate. --> <xsl:variable name="x1" select="math:sin( -$sa * $RADIANS )"/> <xsl:variable name="y1" select="math:sin( (-$sa - 90) * $RADIANS )"/> <!-- Calculate the ending Cartesian coordinate. --> <xsl:variable name="x2" select="math:sin( -$ea * $RADIANS )"/> <xsl:variable name="y2" select="math:sin( (-$ea - 90) * $RADIANS )"/> <!-- Wedges with angles that exceed 180 degrees must be marked. --> <xsl:variable name="sweep"> <xsl:choose> <xsl:when test="($ea - $sa > 180)">1</xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:variable> <!-- Ensure the path's d attribute fits on a printed page. --> <!-- Note: superfluous variables. --> <xsl:variable name="r" select="$radius"/> <xsl:variable name="x1r" select="$x1 * $r"/> <xsl:variable name="y1r" select="$y1 * $r"/> <xsl:variable name="x2r" select="$x2 * $r"/> <xsl:variable name="y2r" select="$y2 * $r"/> <!-- Create the wedge path. --> <path xmlns="http://www.w3.org/2000/svg" fill="{$colour}" title="{$title}" stroke="{$stroke_colour}" transform="translate({$radius},{$radius})" d="M 0 0 L {$x1r} {$y1r} A {$r} {$r} 0 {$sweep} 0 {$x2r} {$y2r} Z"/> </xsl:template> <xsl:template match="title" mode="piechart"> </xsl:template> </xsl:stylesheet>