XSLT-3.0-Code zur Umsetzung von XML-Wahldaten in ein SVG-Kreisdiagramm

[ Wahlseite | SVG-Ergebnis | Code-Download (10 KB) | Zeilennummern ein-/ausblenden ]

001 <?xml version="1.0" encoding="UTF-8"?>
002 <xsl:stylesheet version="3.0"
003   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
004   xmlns:fn="http://www.w3.org/2005/xpath-functions"
005   xmlns:xs="http://www.w3.org/2001/XMLSchema"
006   xmlns:math="http://www.w3.org/2005/xpath-functions/math"
007   exclude-result-prefixes="fn math xs">
008 
009   <!-- Beispielmaterial zum Thema XSLT/XPath / T. Meinike 2013 / http://datenverdrahten.de/
010        Umsetzung eines SVG-Kreisdiagramms mit XSLT / XPath 3.0 unter Verwendung der neuen
011        mathematischen Funktionen math:sin(), math:cos() und math:pi()
012 
013        Datenbasis:
014        Landtagswahl in Niedersachsen 2013
015        http://www.aktuelle-wahlen-niedersachsen.de/LW2013/Landtagswahl_2013.html -->
016 
017   <xsl:output method="xml" encoding="UTF-8" indent="yes" media-type="image/svg+xml"
018     doctype-public="-//W3C//DTD SVG 1.1//EN"
019     doctype-system="http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"/>
020 
021   <!-- Kreisvorgaben -->
022   <xsl:variable name="kreis_x" select="200"/>
023   <xsl:variable name="kreis_y" select="200"/>
024   <xsl:variable name="kreis_r" select="150"/>
025   <xsl:variable name="basislage" select="270"/>
026 
027   <!-- Startpunkt fuer Legende -->
028   <xsl:variable name="top" select="$kreis_y - $kreis_r"/>
029   <xsl:variable name="left" select="$kreis_x + $kreis_r + 50"/>
030 
031   <!-- Jahr zur Abfrage, aktuell '08' und '13' -->
032   <xsl:variable name="jahr" select="'13'"/>
033 
034   <!-- Text für die Überschrift -->
035   <xsl:variable name="info" select="fn:concat('Landtagswahl Niedersachsen 20', $jahr)"/>
036 
037   <!-- Summe gültiger Zweitstimmen -->
038   <xsl:variable name="summe" select="fn:sum(/wahlapplet/wahl[@jahr = $jahr]//gebiet/ergebnis[@kurz = 'GSTWVT']/stimmen)" as="xs:double"/>
039 
040   <!-- Parteinamen nach Anteil sortiert -->
041   <xsl:variable name="parteien" as="xs:string*">
042     <xsl:for-each-group select="/wahlapplet/wahl[@jahr = $jahr]//wvt[@button]" group-by="@kurz">
043       <xsl:sort select="fn:sum(/wahlapplet/wahl[@jahr = $jahr]//gebiet/wvt[@kurz = fn:current()/@kurz]/ergebnis[@kurz = 'STWVT']/stimmen)" data-type="number" order="descending"/>
044       <xsl:variable name="p" select="fn:current-group()[1]/@kurz"/>
045       <xsl:if test="$p != 'Sonstige'"> 
046         <xsl:value-of select="$p"/>
047       </xsl:if>
048     </xsl:for-each-group>
049     <!-- "Sonstige" unsortiert am Ende ausgeben -->
050     <xsl:text>Sonstige</xsl:text>
051   </xsl:variable>
052 
053   <!-- Summen der Zweitstimmen pro Partei -->
054   <xsl:variable name="werte" as="xs:double*">
055     <xsl:sequence select="for $p in $parteien return fn:sum(/wahlapplet/wahl[@jahr = $jahr]//gebiet/wvt[@kurz = $p]/ergebnis[@kurz = 'STWVT']/stimmen)"/>
056   </xsl:variable>
057   
058   <!-- Winkelanteile zu den Summen der Zweitstimmen pro Partei -->
059   <xsl:variable name="winkelanteil" select="for $w in $werte return $w div $summe * 360"/>
060   
061   <!-- Farbwerte der einzelnen Parteien -->
062   <xsl:variable name="farben" as="xs:string*">
063     <xsl:sequence select="for $p in $parteien return /wahlapplet/farben/ergebnisfarben[@ergebnis = $p]/hauptfarbe"/>
064   </xsl:variable>
065 
066   <!-- Haupttemplate -->
067   <xsl:template match="/">
068 
069     <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
070 
071       <!-- Überschrift -->
072       <text x="140" y="30" font-family="sans-serif" font-size="20" fill="#000"><xsl:value-of select="$info"/></text>
073 
074       <xsl:for-each select="$parteien">
075 
076         <!-- Zwischenvariablen -->
077         <xsl:variable name="i" select="fn:position()"/>
078         <xsl:variable name="startwinkel" select="$basislage + fn:sum(fn:subsequence($winkelanteil, 1, $i - 1))"/>
079         <xsl:variable name="endwinkel" select="$basislage + fn:sum(fn:subsequence($winkelanteil, 1, $i))"/>
080 
081         <!-- Startpunkt auf Kreisbahn -->
082         <xsl:variable name="punkt_xs" select="fn:round-half-to-even(math:cos($startwinkel * math:pi() div 180) * $kreis_r + $kreis_x, 2)"/>
083         <xsl:variable name="punkt_ys" select="fn:round-half-to-even(math:sin($startwinkel * math:pi() div 180) * $kreis_r + $kreis_y, 2)"/>
084 
085         <!-- Endpunkt auf Kreisbahn -->
086         <xsl:variable name="punkt_xe" select="fn:round-half-to-even(math:cos($endwinkel * math:pi() div 180) * $kreis_r + $kreis_x, 2)"/>
087         <xsl:variable name="punkt_ye" select="fn:round-half-to-even(math:sin($endwinkel * math:pi() div 180) * $kreis_r + $kreis_y, 2)"/>
088 
089         <!-- Flags für Kreissegment-Lage -->
090         <xsl:variable name="arcflags" select="if($winkelanteil[$i] le 180) then '0,1' else '1,1'"/>
091 
092         <g id="{fn:upper-case(fn:substring($parteien[$i], 1, 3))}">
093           <!-- Pfad erzeugen -->
094           <path d="M {$kreis_x},{$kreis_y} L {$punkt_xs},{$punkt_ys} A {$kreis_r},{$kreis_r} 0 {$arcflags} {$punkt_xe},{$punkt_ye} Z"
095             fill="{$farben[$i]}"/>
096           
097           <!-- Legende mit Beschriftung -->
098           <rect x="{$left}" y="{$top + $i * 25}" width="50" height="15" fill="{$farben[$i]}"/>
099           <text x="{$left + 60}" y="{$top + $i * 25 + 12}" font-family="sans-serif" font-size="12" fill="#000">
100             <xsl:value-of select="fn:concat($parteien[$i], ' [', fn:round-half-to-even($werte[$i] div $summe * 100, 1), ' %]')"/>
101           </text>
102 
103           <!-- Mouseover-Effekt -->
104           <set attributeName="opacity" attributeType="XML" to="0.5" begin="mouseover" end="mouseout"/>
105         </g>
106 
107       </xsl:for-each>
108 
109       <!-- Datenquelle (als XML und CSV am unteren Ende der Seite verlinkt) -->
110       <a xlink:href="http://www.aktuelle-wahlen-niedersachsen.de/LW2013/Landtagswahl_2013.html">
111         <text x="160" y="375" font-family="sans-serif" font-size="10" fill="#00C">XML-Datenquelle</text>
112       </a>
113 
114     </svg>
115 
116   </xsl:template>
117  
118 </xsl:stylesheet>

Code formatiert mit »Highlight 3.12«