| | xmlns:svg="http://www.w3.org/2000/svg"> |
| | |
| | - <!-- Globals --> |
| | - <xsl:variable name="PI">3.14159265358979323846</xsl:variable> |
| | - <xsl:variable name="precision">0.0001</xsl:variable> |
| | + <xsl:include href="math.xsl" /> |
| | |
| | + <xsl:variable name="base_colour" select="'46A5E5'" /> |
| | + |
| | <!-- Convert XML data into a Pie Chart. --> |
| | <xsl:template match="dataset" mode="piechart"> |
| | - |
| | <xsl:variable name="pie_width">100</xsl:variable> |
| | <xsl:variable name="pie_height" select="$pie_width - $PI" /> |
| | |
| | <!-- Number of pie pieces --> |
| | <xsl:variable name="pieces" select="count(data)" /> |
| | |
| | <!-- Calculate the total value for all pieces --> |
| | <xsl:variable name="total" select="sum(//value)" /> |
| | - |
| | + |
| | <div class="chart"> |
| | <svg:svg width="30%" height="30%" viewBox="0 0 {$pie_width} {$pie_height}" version="1.1"> |
| | <svg:g stroke-width="0" fill="#000" stroke="#000"> |
| | <xsl:for-each select="data"> |
| | <xsl:variable name="piece" select="position()" /> |
| | |
| | - <!-- Calculate Fill Color --> |
| | + <!-- Calculate pie piece colour --> |
| | <xsl:variable name="fill"> |
| | <xsl:call-template name="fill"> |
| | <xsl:with-param name="piece" select="$piece" /> |
| | <xsl:with-param name="pieces" select="$pieces" /> |
| | + <xsl:with-param name="colour" select="$base_colour" /> |
| | </xsl:call-template> |
| | </xsl:variable> |
 |
| | |
| | <!-- Fill the pie piece. --> |
| | - <svg:path fill="{$fill}" title="{$percent}" stroke="none" d="{concat('M',$x+$rx,' ',$y+$ry,'L',$x+$rx+$rx*$c2,' ',$y+$ry+$ry*$s2,'A',$rx,' ',$ry,' 0 ',$opt,' 1 ',$x+$rx + $rx * $c,' ',$y+$ry +$ry*$s,'z')}" /> |
| | + <svg:path fill="{$fill}" title="{$percent}" stroke="white" stroke-width="0.5" d="{concat('M',$x+$rx,' ',$y+$ry,'L',$x+$rx+$rx*$c2,' ',$y+$ry+$ry*$s2,'A',$rx,' ',$ry,' 0 ',$opt,' 1 ',$x+$rx + $rx * $c,' ',$y+$ry +$ry*$s,'z')}" /> |
| | </xsl:for-each> |
| | </xsl:for-each> |
 |
| | <svg:svg width="30%" height="30%" viewBox="0 0 {$legend_width} {$legend_height}" version="1.1"> |
| | <xsl:for-each select="//name"> |
| | - <!-- Calculate Fill Color --> |
| | + |
| | + <!-- Select legend colour for corresponding pie piece --> |
| | <xsl:variable name="fill"> |
| | <xsl:call-template name="fill"> |
| | <xsl:with-param name="piece" select="position()" /> |
| | <xsl:with-param name="pieces" select="$pieces" /> |
| | + <xsl:with-param name="colour" select="$base_colour" /> |
| | </xsl:call-template> |
| | </xsl:variable> |
 |
| | </svg:svg> |
| | </div> |
| | - |
| | </xsl:template> |
| | |
| | - <xsl:template name="sine"> |
| | - <xsl:param name="deg" /> |
| | - <xsl:param name="radians"> |
| | - <xsl:value-of select="$deg div 180 * $PI" /> |
| | - </xsl:param> |
| | - <xsl:param name="answer"> |
| | - <xsl:value-of select="$radians" /> |
| | - </xsl:param> |
| | - <xsl:param name="loc">1</xsl:param> |
| | - <xsl:param name="fract"> |
| | - <xsl:value-of select="$radians" /> |
| | - </xsl:param> |
| | - <xsl:variable name="fract2" select="-1 * $fract * $radians * $radians div ($loc *2 * ($loc * 2 + 1))" /> |
| | - <xsl:choose> |
| | - <xsl:when test="$fract2 < $precision and $fract2 > -$precision"> |
| | - <xsl:value-of select="$answer" /> |
| | - </xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:call-template name="sine"> |
| | - <xsl:with-param name="radians" select="$radians" /> |
| | - <xsl:with-param name="answer" select="$answer + $fract2" /> |
| | - <xsl:with-param name="loc" select="$loc+1" /> |
| | - <xsl:with-param name="fract" select="$fract2" /> |
| | - </xsl:call-template> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | - </xsl:template> |
| | - |
| | - <xsl:template name="fill"> |
| | + <!-- http://en.wikipedia.org/wiki/HSL_and_HSV --> |
| | + <xsl:template name="fill"> |
| | <xsl:param name="piece" /> |
| | <xsl:param name="pieces" /> |
| | + <xsl:param name="colour" select="'8A56E2'" /> |
| | + |
| | + <xsl:variable name="r"> |
| | + <xsl:call-template name="hex2dec"> |
| | + <xsl:with-param name="hex" select="substring( $colour, 1, 2 )" /> |
| | + </xsl:call-template> |
| | + </xsl:variable> |
| | + <xsl:variable name="g"> |
| | + <xsl:call-template name="hex2dec"> |
| | + <xsl:with-param name="hex" select="substring( $colour, 3, 2 )" /> |
| | + </xsl:call-template> |
| | + </xsl:variable> |
| | + <xsl:variable name="b"> |
| | + <xsl:call-template name="hex2dec"> |
| | + <xsl:with-param name="hex" select="substring( $colour, 5, 2 )" /> |
| | + </xsl:call-template> |
| | + </xsl:variable> |
| | |
| | - <xsl:variable name="range9"> |
| | - <xsl:choose> |
| | - <xsl:when test="$pieces > 9">9</xsl:when> |
| | - <xsl:otherwise> |
| | - <xsl:value-of select="$pieces" /> |
| | - </xsl:otherwise> |
| | - </xsl:choose> |
| | + <xsl:variable name="alpha" select="(2 * $r - $g - $b) * 0.5" /> |
| | + <xsl:variable name="beta" select="0.86602540378 * ($g - $b)" /> |
| | + |
| | + <xsl:variable name="base_hue"> |
| | + <xsl:call-template name="atan2"> |
| | + <xsl:with-param name="x" select="$alpha" /> |
| | + <xsl:with-param name="y" select="$beta" /> |
| | + </xsl:call-template> |
| | </xsl:variable> |
| | - <xsl:variable name="hue" select="((($piece -1) mod $range9) div $range9 div 3.0 + (($piece -1) mod 3) div 3.0) * 0.85" /> |
| | - <xsl:variable name="saturation" select="1.0 - (floor(($piece -1) div $range9 * 0.5) mod 2) * 0.5 " /> |
| | - <xsl:variable name="brightness" select="0.8 - floor(($piece -1+$range9) div $range9 * 0.5) div (($pieces+$range9) div $range9 * 0.5) * 0.4" /> |
| | - <xsl:variable name="b" select="floor($brightness * 255 + 0.5)" /> |
| | - <xsl:variable name="h" select="floor(($hue - floor($hue)) * 6.0)" /> |
| | - <xsl:variable name="f" select="$h - floor($h)" /> |
| | - <xsl:variable name="p" select="floor($brightness * (1.0 - $saturation) * 255 + 0.5)" /> |
| | - <xsl:variable name="q" select="floor($brightness * (1.0 - $saturation * $f) * 255 + 0.5)" /> |
| | - <xsl:variable name="t" select="floor($brightness * (1.0 - ($saturation * (1.0 - $f))) * 255 + 0.5)" /> |
| | + |
| | + <xsl:variable name="chroma"> |
| | + <xsl:call-template name="sqrt"> |
| | + <xsl:with-param name="n" select="($alpha * $alpha) + ($beta * $beta)" /> |
| | + </xsl:call-template> |
| | + </xsl:variable> |
| | + |
| | + <xsl:variable name="value"> |
| | + <xsl:variable name="max_rg"> |
| | + <xsl:call-template name="max"> |
| | + <xsl:with-param name="a" select="$r" /> |
| | + <xsl:with-param name="b" select="$g" /> |
| | + </xsl:call-template> |
| | + </xsl:variable> |
| | + <xsl:variable name="max_gb"> |
| | + <xsl:call-template name="max"> |
| | + <xsl:with-param name="a" select="$g" /> |
| | + <xsl:with-param name="b" select="$b" /> |
| | + </xsl:call-template> |
| | + </xsl:variable> |
| | + <xsl:call-template name="max"> |
| | + <xsl:with-param name="a" select="$max_rg" /> |
| | + <xsl:with-param name="b" select="$max_gb" /> |
| | + </xsl:call-template> |
| | + </xsl:variable> |
| | + |
| | + <xsl:variable name="saturation"> |
| | + <xsl:if test="$value = 0">0</xsl:if> |
| | + <xsl:if test="$value != 0"><xsl:value-of select="$chroma div $value" /></xsl:if> |
| | + </xsl:variable> |
| | + |
| | + <xsl:variable name="h_rotate" select="($base_hue + ((240 div $pieces) * $piece) mod 240)"></xsl:variable> |
| | + <xsl:variable name="h_prime" select="$h_rotate div 60.0" /> |
| | + <xsl:variable name="h_mod" select="$h_prime mod 2 - 1" /> |
| | + <xsl:variable name="h_abs" select="($h_mod >= 0) * $h_mod - not($h_mod >= 0) * $h_mod" /> |
| | + |
| | + <xsl:variable name="x" select="$chroma * (1 - $h_abs)" /> |
| | + <xsl:variable name="m" select="$value - $chroma" /> |
| | + <xsl:variable name="c" select="$chroma" /> |
| | + |
| | + <xsl:variable name="cm" select="round( $c + $m )" /> |
| | + <xsl:variable name="xm" select="round( $x + $m )" /> |
| | + <xsl:variable name="zm" select="round( 0 + $m )" /> |
| | + |
| | <xsl:choose> |
| | - <xsl:when test="$h = 0">rgb(<xsl:value-of select="$b" />,<xsl:value-of select="$t" />,<xsl:value-of select="$p" />)</xsl:when> |
| | - <xsl:when test="$h = 1">rgb(<xsl:value-of select="$q" />,<xsl:value-of select="$b" />,<xsl:value-of select="$p" />)</xsl:when> |
| | - <xsl:when test="$h = 2">rgb(<xsl:value-of select="$p" />,<xsl:value-of select="$b" />,<xsl:value-of select="$t" />)</xsl:when> |
| | - <xsl:when test="$h = 3">rgb(<xsl:value-of select="$p" />,<xsl:value-of select="$q" />,<xsl:value-of select="$b" />)</xsl:when> |
| | - <xsl:when test="$h = 4">rgb(<xsl:value-of select="$t" />,<xsl:value-of select="$p" />,<xsl:value-of select="$b" />)</xsl:when> |
| | - <xsl:when test="$h = 5">rgb(<xsl:value-of select="$b" />,<xsl:value-of select="$p" />,<xsl:value-of select="$q" />)</xsl:when> |
| | + <xsl:when test="0 <= $h_prime and $h_prime < 1"> |
| | + <xsl:value-of select="concat('rgb(', $cm, ',', $xm, ',', $zm, ')' )" /> |
| | + </xsl:when> |
| | + <xsl:when test="1 <= $h_prime and $h_prime < 2"> |
| | + <xsl:value-of select="concat('rgb(', $xm, ',', $cm, ',', $zm, ')' )" /> |
| | + </xsl:when> |
| | + <xsl:when test="2 <= $h_prime and $h_prime < 3"> |
| | + <xsl:value-of select="concat('rgb(', $zm, ',', $cm, ',', $xm, ')' )" /> |
| | + </xsl:when> |
| | + <xsl:when test="3 <= $h_prime and $h_prime < 4"> |
| | + <xsl:value-of select="concat('rgb(', $zm, ',', $xm, ',', $cm, ')' )" /> |
| | + </xsl:when> |
| | + <xsl:when test="4 <= $h_prime and $h_prime < 5"> |
| | + <xsl:value-of select="concat('rgb(', $xm, ',', $zm, ',', $cm, ')' )" /> |
| | + </xsl:when> |
| | + <xsl:when test="5 <= $h_prime and $h_prime < 6"> |
| | + <xsl:value-of select="concat('rgb(', $cm, ',', $zm, ',', $xm, ')' )" /> |
| | + </xsl:when> |
| | + <xsl:otherwise> |
| | + <xsl:value-of select="concat('rgb(', $cm, ',', $xm, ',', $zm, ')' )" /> |
| | + </xsl:otherwise> |
| | </xsl:choose> |
| | </xsl:template> |
| | + |
| | </xsl:stylesheet> |
| | |