Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/delibero.git
<?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 &gt; 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>