TMK: SVG-Grafik erzeugen

Hallo,
ich habe eine XML-Datei, welche Informationen für das Erzeugen von Balkendiagrammen enthält. Diese infos enthalten die Höhe und die Farbe:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <datum col="green">400</datum>
    <datum col="yellow">300</datum>
    <datum col="green">50</datum>
    <datum col="blue">100</datum>
</data>

Daraus soll nun mittels einer XSLT-Transformation eine SVG-Grafik erzeugt werden. Ich habe die Transformation schon geschrieben, nur werden die Balken immer übereinander gezeichnet, da meine X-Position leider noch fix ist. Hier ist mein XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" />
 <xsl:template match="/">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600" height="600" width="800">
   <xsl:for-each select="data/datum">
    <polyline xmlns="http://www.w3.org/2000/svg">
     <xsl:attribute name="points">
             xsl:text0 0 0 </xsl:text><xsl:value-of select="."/>xsl:text 10 </xsl:text><xsl:value-of select="."/>xsl:text 10 0</xsl:text>
          </xsl:attribute>
          <xsl:attribute name="transform">
             xsl:texttranslate(100,500) scale(1,-1)</xsl:text>
          </xsl:attribute>
          <xsl:attribute name="style">
             xsl:textfill:</xsl:text><xsl:apply-templates select="@col"/>xsl:text;</xsl:text>
          </xsl:attribute>
    </polyline>
      </xsl:for-each>
  </svg>
 </xsl:template>
</xsl:stylesheet>

Kann mir jemand sagen, wie ich es umschreiben muss, dass für jeden Balken eine eigen X-Position generiert wird, also z.B. durch Addieren eines Offsets?

Ciao

  1. Hm, also das muesste in den w3c stehen. Aber du könntest dich ja auch andersrum an das Problem machen. installiere dir Inkscape (open source und ziemlich maechtig). Mal dir die Balekn so wie du sie magst und dann schaue dir den Code an. Kann man bei Inkscape direkt im Programm machen, wenn man auch die grafik offen hat, oder aber du speicherst es als svg und schaust dir dann den Code an und passt ihn an.

    Gruß, Holge r

  2. Hallo TMK,

    Kann mir jemand sagen, wie ich es umschreiben muss, dass für jeden Balken eine eigen X-Position generiert wird, also z.B. durch Addieren eines Offsets?

    Diesen Offset ermöglicht die Verwendung der Funktion position(), hier in kompakter Schreibweise umgesetzt (die Transformation ist nicht für jeden Balken separat nötig, ich habe diese auf eine umschließende Gruppe angewendet):

    <xsl:template match="/">  
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600" height="600" width="800">  
        <g transform="translate(100,500) scale(1,-1)">  
          <xsl:for-each select="data/datum">  
            <xsl:variable name="delta" select="(position() - 1) * 30"/>  
            <polyline points="{0+$delta},0 {0+$delta},{.} {10+$delta},{.} {10+$delta},0" fill="{@col}"/>  
          </xsl:for-each>  
        </g>  
      </svg>  
    </xsl:template>
    

    Ergebnis mit Deinen XML-Daten:

    <?xml version="1.0" encoding="UTF-8"?>  
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600" height="600" width="800">  
      <g transform="translate(100,500) scale(1,-1)">  
        <polyline points="0,0 0,400 10,400 10,0" fill="green" />  
        <polyline points="30,0 30,300 40,300 40,0" fill="yellow" />  
        <polyline points="60,0 60,50 70,50 70,0" fill="green" />  
        <polyline points="90,0 90,100 100,100 100,0" fill="blue" />  
      </g>  
    </svg>
    

    BTW: Die Kommasetzung im points-Attribut ist nicht Pflicht, aber in der gewählten Form ist die Punktzuordnung am besten lesbar, wenn man die drei möglichen Varianten vergleicht:

    points="0,0 0,400 10,400 10,0"
    points="0,0,0,400,10,400,10,0"
    points="0 0 0 400 10 400 10 0"

    Grüße,
    Thomas