使用XSLT和SVG从XML创建条形图 - 缩放条形图

时间:2014-07-15 18:31:30

标签: xml xslt svg

我是XSLT和SVG的新手,已经做了很多研究。我在这里看到了一些看起来很接近我需要帮助的答案,但不太适合我。任何帮助将不胜感激。

我从一个看起来像这样的SQL数据库中提取XML文件:

<Report>
  <Title>Step Status Sums Report</Title>
  <RESULTS>
    <ROW>
      <PASSED>2784</PASSED>
      <FAILED>73</FAILED>
      <CAUTION>29</CAUTION>
      <BLOCKED>27</BLOCKED>
      <NOTRUN>3776</NOTRUN>
    </ROW>
  </RESULTS>
</Report>

通过在线项目管理工具,我只能使用xslt版本1.0和SVG转换此数据。

我想要的东西:一个简单的条形图(顺便说一下,这些数据会随着不同的项目而变化 - 所以不一定是这个特定的数据。)

这就是我所尝试过的,我知道这可能看起来像一个糟糕的结构,因为我试图在网上看到类似的东西。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns="http://www.w3.org/2000/svg">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/RESULTS">
  <svg width="650" height="500">
  <g id="axis" transform="translate(0 500) scale(1 -1)">
  <line id="axis-y" x1="30" y1="20" x2="30" y2="450" style="fill:none;stroke:rgb(0,0,0);stroke-width:2"/>
  <line id="axis-x" x1="30" y1="20" x2="460" y2="20"  style="fill:none;stroke:rgb(0,0,0);stroke-width:2"/>
  </g>  
  <xsl:for-each select="ROW">
   <g id="bars" transform="translate(30 479) scale(1 -430)">
    <rect x="30" y="0" width="50" height="{PASSED}"  style="fill:rgb(81,223,13);stroke:rgb(0,0,0);stroke-width:0"/>     
    <rect x="100" y="0" width="50" height="{FAILED}"  style="fill:rgb(224,12,12);stroke:rgb(0,0,0);stroke-width:0"/>  
    <rect x="170" y="0" width="50" height="{CAUTION}"  style="fill:rgb(245,136,37);stroke:rgb(0,0,0);stroke-width:0"/>  
    <rect x="240" y="0" width="50" height="{BLOCKED}"  style="fill:rgb(248,241,7);stroke:rgb(0,0,0);stroke-width:0"/>  
    <rect x="310" y="0" width="50" height="{NOTRUN}"  style="fill:rgb(180,180,180);stroke:rgb(0,0,0);stroke-width:0"/>  
  </g> 

    <g id="ROW">
      <rect id="PASSED" x="430" y="80" width="25" height="15"  style="fill:rgb(81,223,13);stroke:rgb(0,0,0);stroke-width:1"/>
      <rect id="FAILED" x="430" y="100" width="25" height="15"  style="fill:rgb(224,12,12);stroke:rgb(0,0,0);stroke-width:1"/>
      <rect id="CAUTION" x="430" y="120" width="25" height="15"  style="fill:rgb(245,136,37);stroke:rgb(0,0,0);stroke-width:1"/>
      <rect id="BLOCKED" x="430" y="140" width="25" height="15"  style="fill:rgb(248,241,7);stroke:rgb(0,0,0);stroke-width:1"/>
      <rect id="NOTRUN" x="430" y="160" width="25" height="15"  style="fill:rgb(180,180,180);stroke:rgb(0,0,0);stroke-width:1"/>
  </g>
    <text id="PASSED-text" x="465px" y="92px"  style="fill:rgb(0,0,0);font-size:18;font-family:Arial">  
        <xsl:value-of select="PASSED"/> - Passed  </text>  
    <text id="FAILED-text" x="465px" y="112px"  style="fill:rgb(0,0,0);font-size:18;font-family:Arial">  
        <xsl:value-of select="FAILED"/> - Failed </text>  
    <text id="key3-text" x="465px" y="132px"  style="fill:rgb(0,0,0);font-size:18;font-family:Arial">  
        <xsl:value-of select="CAUTION"/> - Caution </text>  
    <text id="key4-text" x="465px" y="152px"  style="fill:rgb(0,0,0);font-size:18;font-family:Arial">  
        <xsl:value-of select="BLOCKED"/> - Blocked </text>  
    <text id="key5-text" x="465px" y="172px"  style="fill:rgb(0,0,0);font-size:18;font-family:Arial">  
        <xsl:value-of select="NOTRUN"/> - Not Run </text> 
  <g id="title">
      <text x="325px" y="20px"  style="text-anchor:middle;fill:rgb(0,0,0);font-size:24;font-family:Arial">
      <xsl:value-of select="title"/>  </text>
  </g>
 </xsl:for-each>
 </svg>
 </xsl:template>
</xsl:stylesheet>

如图表图片所示:enter image description here

酒吧没有拉到正确的高度。一切都显然没有正确缩放,我只是不知道该怎么做。

1 个答案:

答案 0 :(得分:3)

这可能有更好的方法,但这里有一个快速解决方法:

<xsl:template match="/">

<xsl:variable name="max">
    <xsl:for-each select="Report/RESULTS/ROW/*">
        <xsl:sort select="." data-type="number" order="descending"/>
        <xsl:if test="position()=1">
            <xsl:value-of select="."/>
        </xsl:if>
    </xsl:for-each>
</xsl:variable>

<svg width="650" height="500">
  <g id="axis" transform="translate(0 500) scale(1 -1)">
  <line id="axis-y" x1="30" y1="20" x2="30" y2="450" style="fill:none;stroke:rgb(0,0,0);stroke-width:2"/>
  <line id="axis-x" x1="30" y1="20" x2="460" y2="20"  style="fill:none;stroke:rgb(0,0,0);stroke-width:2"/>
  </g>  
  <xsl:for-each select="Report/RESULTS/ROW">
   <g id="bars" transform="translate(30 479) scale(1 -430)">
    <rect x="30" y="0" width="50" height="{PASSED div $max}"  style="fill:rgb(81,223,13);stroke:rgb(0,0,0);stroke-width:0"/>     
    <rect x="100" y="0" width="50" height="{FAILED div $max}"  style="fill:rgb(224,12,12);stroke:rgb(0,0,0);stroke-width:0"/>  
    <rect x="170" y="0" width="50" height="{CAUTION div $max}"  style="fill:rgb(245,136,37);stroke:rgb(0,0,0);stroke-width:0"/>  
    <rect x="240" y="0" width="50" height="{BLOCKED div $max}"  style="fill:rgb(248,241,7);stroke:rgb(0,0,0);stroke-width:0"/>  
    <rect x="310" y="0" width="50" height="{NOTRUN div $max}"  style="fill:rgb(180,180,180);stroke:rgb(0,0,0);stroke-width:0"/>  
  </g> 
...