<?xml version="1.0" encoding="UTF-8"?>
             
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:rs ="http://jena.hpl.hp.com/2003/03/result-set#"
                xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                xmlns="http://www.w3.org/2000/svg">
   
   <xsl:output method="xml" version="1.0" encoding="utf-8" 
               indent="yes" omit-xml-declaration="no" 
               doctype-public="-//W3C//DTD SVG 1.1//EN"
               doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"/>
   
   <!-- This Pie Chart -->
   
   <xsl:variable name="rx">180</xsl:variable>
   <xsl:variable name="ry">90</xsl:variable>
   <xsl:variable name="cx">380</xsl:variable>
   <xsl:variable name="cy">160</xsl:variable>
   <xsl:variable name="pieHeight">20</xsl:variable>
   
   <xsl:variable name="sliceCount">
      <xsl:value-of select="count(/results/group)" />
   </xsl:variable>
   
   <xsl:variable name="grandTotal">
      <xsl:value-of select="/results/count" />
   </xsl:variable>
   
   <xsl:template name="getSize">
      <xsl:param name="doc"       />
      <xsl:param name="index"     />
      
      <xsl:variable name="sliceSize"  select="/results/group[position() = $index]/count" />
      <xsl:variable name="percentage" select="round(100.0 * $sliceSize div $grandTotal)" />
      <xsl:value-of select="$percentage" />
   </xsl:template>
   
   <xsl:template name="getLabel">
      <xsl:param name="doc"       />
      <xsl:param name="index"     />
      
      <xsl:variable name="label"      select="/results/group[position() = $index]/name" />
      <xsl:value-of select="$label" />
   </xsl:template>
   
   <!-- General -->
   
   <xsl:variable name="calctable" select="document('calctable.xml')/calctable" />
   <xsl:variable name="bottomSlice">
      <xsl:call-template name="detectBottom">
         <xsl:with-param name="doc" select="/" />
      </xsl:call-template>
   </xsl:variable>
   <xsl:variable name="leftSize">
      <xsl:call-template name="summer">
         <xsl:with-param name="doc"   select="/"               />
         <xsl:with-param name="start" select="1"                />
         <xsl:with-param name="end"   select="$bottomSlice - 1" />
      </xsl:call-template>
   </xsl:variable>
   
   
   <xsl:template match="/">
      <svg width="100%" height="100%" version="1.1" onload="init(evt)" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
         <g stroke="gray" stroke-width="1">
            <xsl:call-template name="drawRaster" />
         </g>
         
         <xsl:call-template name="drawLegend">
            <xsl:with-param name="doc" select="/" />
            <xsl:with-param name="index" select="1" />
         </xsl:call-template>
         
         <text id="textLabel" x="300" y="50" font-weight="bold"> 
            <xsl:text> </xsl:text>
         </text>
         
         <text id="textLabel" x="50" y="320"> 
            <xsl:text>Hold your mouse over the slice to see more details.</xsl:text>
         </text>
         
         <g stroke="black" stroke-width="2">
            <xsl:call-template name="draw3DGraph">
               <xsl:with-param name="doc" select="/" />
            </xsl:call-template>
            <xsl:call-template name="draw2DGraph">
               <xsl:with-param name="doc" select="/" />
            </xsl:call-template>
         </g>
         
         <script type="text/javascript"><![CDATA[
            
            var svgDoc;
            var statusBar;
            
            function init(evt) {
               svgDoc    = evt.target.ownerDocument;
               statusBar = svgDoc.getElementById('textLabel').firstChild;
            }
            
            function activateSlice(evt) {
               statusBar.nodeValue  = evt.target.getAttribute('title');
            }
            
         ]]></script>
 
      </svg>
   </xsl:template>
   
   <!-- Raster --> 
   
   <xsl:template name="drawRaster">
      <xsl:call-template name="drawRasterR">
         <xsl:with-param name="current" select="0" />
         <xsl:with-param name="max"     select="20" />
      </xsl:call-template>
   </xsl:template>
   
   <xsl:template name="drawRasterR">
      <xsl:param name="current" />
      <xsl:param name="max"     />
      
      <path>
         <xsl:attribute name="id">line<xsl:value-of select="100 - $current * 100 div $max" /></xsl:attribute>
         <xsl:attribute name="d">M 0,<xsl:value-of select="$current * 18" /> L 650,<xsl:value-of select="$current * 18" /></xsl:attribute>
      </path>
      
      <xsl:if test="$current &lt; $max">
         <xsl:call-template name="drawRasterR">
            <xsl:with-param name="current" select="$current + 1" />
            <xsl:with-param name="max"     select="20" />
         </xsl:call-template>
      </xsl:if>
   </xsl:template>
   
   <!-- 3D Graph --> 
   
   <xsl:template name="draw3DGraph">
      <xsl:param name="doc" />
      
      <xsl:call-template name="draw3DGraphR">
         <xsl:with-param name="doc"        select="$doc" />
         <xsl:with-param name="leftTrack"  select="0"    />
         <xsl:with-param name="rightTrack" select="0"    />
         <xsl:with-param name="index"      select="1"    />
      </xsl:call-template>
      
   </xsl:template>
   
   <xsl:template name="draw3DGraphR">
      <xsl:param name="doc"    />
      <xsl:param name="leftTrack"  />
      <xsl:param name="rightTrack"  />
      <xsl:param name="index"  />
      
      <xsl:if test="$index &lt;= $sliceCount">
         <xsl:variable name="size">
            <xsl:call-template name="getSize">
               <xsl:with-param name="doc"   select="$doc"   />
               <xsl:with-param name="index" select="$index" />
            </xsl:call-template>
         </xsl:variable>
         
         <xsl:variable name="color">
            <xsl:value-of select="concat('rgb(', (160 + $index * 30) mod 256, ',', (0 + $index * 90) mod 256, ',', (0 + $index * 40) mod 256, ')')" />
         </xsl:variable>
         
         <xsl:choose>
            <xsl:when test="($index mod 2 = 0 or $leftTrack+$size &gt; 50) and $rightTrack+$size &lt;= 50">
               <xsl:if test="$size &gt; 0">
                  <xsl:call-template name="drawSlice3D">
                     <xsl:with-param name="start" select="(75 + $rightTrack)         mod 100" />
                     <xsl:with-param name="end"   select="(75 + $rightTrack + $size) mod 100" />
                     <xsl:with-param name="color" select="$color" /> 
                  </xsl:call-template>
               </xsl:if>
               
               <xsl:call-template name="draw3DGraphR">
                  <xsl:with-param name="doc"        select="$doc"              />
                  <xsl:with-param name="leftTrack"  select="$leftTrack"        />
                  <xsl:with-param name="rightTrack" select="$rightTrack+$size" />
                  <xsl:with-param name="index"      select="$index+1"          />
               </xsl:call-template>
            </xsl:when>
            <xsl:when test="($index mod 2 = 1 or $rightTrack+$size &gt; 50) and $leftTrack+$size &lt;= 50">
               <xsl:if test="$size &gt; 0">
                  <xsl:call-template name="drawSlice3D">
                     <xsl:with-param name="start" select="(75 - ($leftTrack + $size)) mod 100" />
                     <xsl:with-param name="end"   select="(75 - ($leftTrack))         mod 100" />
                     <xsl:with-param name="color" select="$color" /> 
                  </xsl:call-template>
               </xsl:if>
               
               <xsl:call-template name="draw3DGraphR">
                  <xsl:with-param name="doc"        select="$doc"             />
                  <xsl:with-param name="leftTrack"  select="$leftTrack+$size" />
                  <xsl:with-param name="rightTrack" select="$rightTrack"      />
                  <xsl:with-param name="index"      select="$index+1"         />
               </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
               <xsl:if test="$size &gt; 0">
                  <xsl:call-template name="drawSlice3D">
                     <xsl:with-param name="start" select="(75 + $rightTrack)         mod 100" />
                     <xsl:with-param name="end"   select="(75 + $rightTrack + $size) mod 100" />
                     <xsl:with-param name="color" select="$color" /> 
                  </xsl:call-template>
               </xsl:if>
               
               <xsl:call-template name="draw3DGraphR">
                  <xsl:with-param name="doc"        select="$doc"              />
                  <xsl:with-param name="leftTrack"  select="$leftTrack"        />
                  <xsl:with-param name="rightTrack" select="$rightTrack+$size" />
                  <xsl:with-param name="index"      select="$index+1"          />
               </xsl:call-template>
            </xsl:otherwise>
         </xsl:choose>
      
      </xsl:if>
      
   </xsl:template>
   
   <xsl:template name="drawSlice3D">
      <xsl:param name="start" />
      <xsl:param name="end" />
      <xsl:param name="color" />
      
      <xsl:variable name="sx" select="round($rx * $calctable/point[@number=$start]/x + $cx)" />
      <xsl:variable name="sy" select="round($ry * $calctable/point[@number=$start]/y + $cy)" />
      <xsl:variable name="ex" select="round($rx * $calctable/point[@number=$end]/x   + $cx)" />
      <xsl:variable name="ey" select="round($ry * $calctable/point[@number=$end]/y   + $cy)" />
      
      <xsl:variable name="difference">
         <xsl:choose>
            <xsl:when test="$end - $start &lt; 0"><xsl:value-of select="(100 - $start) + $end" /></xsl:when>
            <xsl:otherwise><xsl:value-of select="$end - $start" /></xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <xsl:variable name="largeSweep">
         <xsl:choose>
            <xsl:when test="$difference &gt; 50">1</xsl:when>
            <xsl:otherwise>0</xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
    
      <xsl:if test="$sy &lt; $cy or $ey &lt; $cy">
         <path>
            <xsl:attribute name="style">fill:<xsl:value-of select="$color" />;</xsl:attribute>
            <xsl:attribute name="d">
               <xsl:value-of select="concat(
                  ' M ', $sx, ' ', $sy,
                  ' L ', $sx, ' ', $sy + $pieHeight,
                  ' A ', $rx, ' ', $ry, ' 0 ', $largeSweep ,' 1 ', $ex, ' ', $ey + $pieHeight,
                  ' L ', $ex, ' ', $ey,
                  ' A ', $rx, ' ', $ry, ' 0 ', $largeSweep ,' 0 ', $sx, ' ', $sy,
                  ' z '
               )" />
            </xsl:attribute>
         </path>
      </xsl:if>
      
      <xsl:variable name="fx">
         <xsl:choose>
            <xsl:when test="$sy &lt; $ey"><xsl:value-of select="$sx" /></xsl:when>
            <xsl:otherwise><xsl:value-of select="$ex" /></xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <xsl:variable name="fy">
         <xsl:choose>
            <xsl:when test="$sy &lt; $ey"><xsl:value-of select="$sy" /></xsl:when>
            <xsl:otherwise><xsl:value-of select="$ey" /></xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <xsl:variable name="lx">
         <xsl:choose>
            <xsl:when test="$sy &lt; $ey"><xsl:value-of select="$ex" /></xsl:when>
            <xsl:otherwise><xsl:value-of select="$sx" /></xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <xsl:variable name="ly">
         <xsl:choose>
            <xsl:when test="$sy &lt; $ey"><xsl:value-of select="$ey" /></xsl:when>
            <xsl:otherwise><xsl:value-of select="$sy" /></xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <xsl:call-template name="drawSide3D">
         <xsl:with-param name="px" select="$fx" />
         <xsl:with-param name="py" select="$fy" />
         <xsl:with-param name="color" select="$color" />
      </xsl:call-template>
      
      <xsl:call-template name="drawSide3D">
         <xsl:with-param name="px" select="$lx" />
         <xsl:with-param name="py" select="$ly" />
         <xsl:with-param name="color" select="$color" />
      </xsl:call-template>
      
      <xsl:if test="not($sy &lt; $cy or $ey &lt; $cy)">
         <path>
            <xsl:attribute name="style">fill:<xsl:value-of select="$color" />;</xsl:attribute>
            <xsl:attribute name="d">
               <xsl:value-of select="concat(
                  ' M ', $sx, ' ', $sy,
                  ' L ', $sx, ' ', $sy + $pieHeight,
                  ' A ', $rx, ' ', $ry, ' 0 ', $largeSweep ,' 1 ', $ex, ' ', $ey + $pieHeight,
                  ' L ', $ex, ' ', $ey,
                  ' A ', $rx, ' ', $ry, ' 0 ', $largeSweep ,' 0 ', $sx, ' ', $sy,
                  ' z '
               )" />
            </xsl:attribute>
         </path>
      </xsl:if>
      
   </xsl:template>
   
   <xsl:template name="drawSide3D">
      <xsl:param name="px" />
      <xsl:param name="py" />
      <xsl:param name="color" />
      
      <path>
         <xsl:attribute name="style">fill:<xsl:value-of select="$color" />;</xsl:attribute>
         <xsl:attribute name="d">
            <xsl:value-of select="concat(
               ' M ', $cx, ' ', $cy,
               ' L ', $px, ' ', $py,
               ' L ', $px, ' ', $py + $pieHeight,
               ' L ', $cx, ' ', $cy + $pieHeight,
               ' z '
            )" />
         </xsl:attribute>
      </path>
   </xsl:template>
   
   <!-- 2D Graph -->
   
   <xsl:template name="draw2DGraph">
      <xsl:param name="doc" />
      
      <xsl:call-template name="draw2DGraphR">
         <xsl:with-param name="doc"        select="$doc" />
         <xsl:with-param name="leftTrack"  select="0"    />
         <xsl:with-param name="rightTrack" select="0"    />
         <xsl:with-param name="index"      select="1"    />
      </xsl:call-template>
      
   </xsl:template>
   
   <xsl:template name="draw2DGraphR">
      <xsl:param name="doc"    />
      <xsl:param name="leftTrack"  />
      <xsl:param name="rightTrack"  />
      <xsl:param name="index"  />
      
      <xsl:if test="$index &lt;= $sliceCount">
         <xsl:variable name="size">
            <xsl:call-template name="getSize">
               <xsl:with-param name="doc"   select="$doc"   />
               <xsl:with-param name="index" select="$index" />
            </xsl:call-template>
         </xsl:variable>
         
         <xsl:variable name="label">
            <xsl:call-template name="getLabel">
               <xsl:with-param name="doc"   select="$doc" />
               <xsl:with-param name="index" select="$index" />
            </xsl:call-template>
         </xsl:variable>
         
         <xsl:variable name="color">
            <xsl:value-of select="concat('rgb(', (160 + $index * 30) mod 256, ',', (0 + $index * 90) mod 256, ',', (0 + $index * 40) mod 256, ')')" />
         </xsl:variable>
         
         <xsl:choose>
            <xsl:when test="($index mod 2 = 0 or $leftTrack+$size &gt; 50) and $rightTrack+$size &lt;= 50">
               <xsl:call-template name="drawSlice">
                  <xsl:with-param name="start" select="(75 + $rightTrack)         mod 100" />
                  <xsl:with-param name="end"   select="(75 + $rightTrack + $size) mod 100" />
                  <xsl:with-param name="label" select="concat($label, ': ', $size, '%')" />
                  <xsl:with-param name="color" select="$color" /> 
               </xsl:call-template>
               
               <xsl:call-template name="draw2DGraphR">
                  <xsl:with-param name="doc"        select="$doc"              />
                  <xsl:with-param name="leftTrack"  select="$leftTrack"        />
                  <xsl:with-param name="rightTrack" select="$rightTrack+$size" />
                  <xsl:with-param name="index"      select="$index+1"          />
               </xsl:call-template>
            </xsl:when>
            <xsl:when test="($index mod 2 = 1 or $rightTrack+$size &gt; 50) and $leftTrack+$size &lt;= 50">
               <xsl:call-template name="drawSlice">
                  <xsl:with-param name="start" select="(75 - ($leftTrack + $size)) mod 100" />
                  <xsl:with-param name="end"   select="(75 - ($leftTrack))         mod 100" />
                  <xsl:with-param name="label" select="concat($label, ': ', $size, '%')" />
                  <xsl:with-param name="color" select="$color" /> 
               </xsl:call-template>
               
               <xsl:call-template name="draw2DGraphR">
                  <xsl:with-param name="doc"        select="$doc"             />
                  <xsl:with-param name="leftTrack"  select="$leftTrack+$size" />
                  <xsl:with-param name="rightTrack" select="$rightTrack"      />
                  <xsl:with-param name="index"      select="$index+1"         />
               </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
               <xsl:call-template name="drawSlice">
                  <xsl:with-param name="start" select="(75 + $rightTrack)         mod 100" />
                  <xsl:with-param name="end"   select="(75 + $rightTrack + $size) mod 100" />
                  <xsl:with-param name="label" select="concat($label, ': ', $size, '%')" />
                  <xsl:with-param name="color" select="$color" /> 
               </xsl:call-template>
               
               <xsl:call-template name="draw2DGraphR">
                  <xsl:with-param name="doc"        select="$doc"              />
                  <xsl:with-param name="leftTrack"  select="$leftTrack"        />
                  <xsl:with-param name="rightTrack" select="$rightTrack+$size" />
                  <xsl:with-param name="index"      select="$index+1"          />
               </xsl:call-template>
            </xsl:otherwise>
         </xsl:choose>
      
      </xsl:if>
      
   </xsl:template>
   
   <xsl:template name="drawSlice">
      <xsl:param name="start" />
      <xsl:param name="end" />
      <xsl:param name="color" />
      <xsl:param name="label" />
      
      <xsl:variable name="sx" select="round($rx * $calctable/point[@number=$start]/x + $cx)" />
      <xsl:variable name="sy" select="round($ry * $calctable/point[@number=$start]/y + $cy)" />
      <xsl:variable name="ex" select="round($rx * $calctable/point[@number=$end]/x   + $cx)" />
      <xsl:variable name="ey" select="round($ry * $calctable/point[@number=$end]/y   + $cy)" />
         
      <xsl:variable name="difference">
         <xsl:choose>
            <xsl:when test="$end - $start &lt; 0"><xsl:value-of select="(100 - $start) + $end" /></xsl:when>
            <xsl:otherwise><xsl:value-of select="$end - $start" /></xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <xsl:variable name="largeSweep">
         <xsl:choose>
            <xsl:when test="$difference &gt; 50">1</xsl:when>
            <xsl:otherwise>0</xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <path onmouseover="activateSlice(evt)">
         <xsl:attribute name="style">fill:<xsl:value-of select="$color" />;</xsl:attribute>
         <xsl:attribute name="title"><xsl:value-of select="$label" /></xsl:attribute>
         <xsl:attribute name="d">
            <xsl:value-of select="concat(
               ' M ', $cx, ' ', $cy,
               ' L ', $sx, ' ', $sy,
               ' A ', $rx, ' ', $ry, ' 0 ', $largeSweep ,' 1 ', $ex, ' ', $ey,
               ' z '
            )" />
         </xsl:attribute>
      </path>
   </xsl:template>
   
   <!-- Utilities -->
   
   <xsl:template name="summer">
      <xsl:param name="doc" />
      <xsl:param name="start" />
      <xsl:param name="end" />
      
      <xsl:variable name="size">
         <xsl:call-template name="getSize">
            <xsl:with-param name="doc"   select="$doc" />
            <xsl:with-param name="index" select="$start" />
         </xsl:call-template>
      </xsl:variable>
      
      <xsl:choose>
         <xsl:when test="$size = 0 or $start &gt;= $end">
            <xsl:value-of select="$size" />
         </xsl:when> 
         <xsl:otherwise>
            <xsl:call-template name="summer">
               <xsl:with-param name="doc"   select="$doc" />
               <xsl:with-param name="start" select="$start+1" />
               <xsl:with-param name="end"   select="$end" />
            </xsl:call-template>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
   
   <xsl:template name="detectBottom">
      <xsl:param name="doc" />
      
      <xsl:call-template name="detectBottomR">
         <xsl:with-param name="doc"   select="$doc"   />
         <xsl:with-param name="sofar" select="0" />
         <xsl:with-param name="index" select="1" />
      </xsl:call-template>
   </xsl:template>
   
   <xsl:template name="detectBottomR">
      <xsl:param name="doc"   />
      <xsl:param name="sofar" />
      <xsl:param name="index" />
      
      <xsl:variable name="size">
         <xsl:call-template name="getSize">
            <xsl:with-param name="doc"   select="$doc" />
            <xsl:with-param name="index" select="$index" />
         </xsl:call-template>
      </xsl:variable>
      
      <xsl:variable name="totalSize" select="$sofar + $size" />
      
      <xsl:choose>
         <xsl:when test="$totalSize &gt;= 50">
            <xsl:value-of select="$index" />
         </xsl:when>
         <xsl:otherwise>
            <xsl:call-template name="detectBottomR">
               <xsl:with-param name="doc"   select="$doc"   />
               <xsl:with-param name="sofar" select="$totalSize" />
               <xsl:with-param name="index" select="$index+1" />
            </xsl:call-template>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>


   <!-- Legend -->   
   <xsl:template name="drawLegend">
      <xsl:param name="doc"   />
      <xsl:param name="index" />
      
      <!-- Init variable values which will be used to draw the legend -->
      <xsl:variable name="boxHeight">
         <xsl:value-of select="16" />
      </xsl:variable>
      <xsl:variable name="color">
         <xsl:value-of select="concat('rgb(', (160 + $index * 30) mod 256, ',', (0 + $index * 90) mod 256, ',', (0 + $index * 40) mod 256, ')')" />
      </xsl:variable>
      <xsl:variable name="boxY">
         <xsl:value-of select="(37 + ($index * ($boxHeight + 2)))" /> 
      </xsl:variable>
      <xsl:variable name="labelY">
         <xsl:value-of select="($boxY + $boxHeight - 2)" />
      </xsl:variable>
      
      <xsl:if test="$index &lt;= $sliceCount">
      <!-- Draw colored box and label -->
         <rect x="10" width="20" rx="5">
            <xsl:attribute name="y"><xsl:value-of select="$boxY" /></xsl:attribute>
            <xsl:attribute name="height"><xsl:value-of select="$boxHeight" /></xsl:attribute>
            <xsl:attribute name="style">fill:<xsl:value-of select="$color" />; stroke:black; stroke-width:1</xsl:attribute>
         </rect>
         
         <text x="40">
            <xsl:attribute name="y"><xsl:value-of select="$labelY" /></xsl:attribute>
            <xsl:attribute name="style">file:black</xsl:attribute>
            <xsl:call-template name="getLabel">
               <xsl:with-param name="doc"   select="$doc" />
               <xsl:with-param name="index" select="$index" />
            </xsl:call-template>
         </text>
         
         <!-- Handle next part of the legend -->
         <xsl:call-template name="drawLegend">
            <xsl:with-param name="doc" select="/" />
            <xsl:with-param name="index" select="($index + 1)" />
         </xsl:call-template>
      </xsl:if>
   </xsl:template>

   
</xsl:stylesheet>


