特定
<root> <item> <detail>100</detail> <detail>200</detail> </item> <item> <detail>50</detail> <detail>100</detail> </item> </root>
我如何将这些数据变成一个简单的SVG条形图? (没有什么花哨,只有四个酒吧代表数字之间的关系)
这样的东西
(我知道这两个项目之间没有分离,但是让我们说我将使它们变成不同的颜色,前两个蓝色的第二个红色)
这里有一个例子,有更多的钟声和口哨:
>它会自动缩放到最大高度
>它使用CSS来设计元素
>它具有用于条的宽度和间距的可配置参数
它使用更多的惯用XSLT,而不仅仅是一堆嵌套的for-each循环
用你的输入这段代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" > <xsl:output indent="yes" cdata-section-elements="style" /> <xsl:param name="width" select="40" /><!-- width of bars --> <xsl:param name="space" select="10" /><!-- space between bars and items --> <xsl:variable name="max-y" select="//detail[not(//detail > .)][1]" /> <xsl:template match="root"> <svg> <defs> <style type="text/css"><![CDATA[ g.bar text { font-family: Arial; text-anchor: middle; fill: white; } g.bar rect { fill: black; } ]]></style> </defs> <g transform="translate(10,10)"> <xsl:apply-templates select="item" /> </g> </svg> </xsl:template> <xsl:template match="item"> <xsl:variable name="prev-item" select="preceding-sibling::item" /> <g class="item" id="item-{position()}" transform="translate({ count($prev-item/detail) * ($width + $space) + count($prev-item) * $space })"> <xsl:apply-templates select="detail" /> </g> </xsl:template> <xsl:template match="detail"> <xsl:variable name="idx" select="count(preceding-sibling::detail)" /> <xsl:variable name="pos" select="$idx * ($width + $space)" /> <g class="bar"> <rect x="{$pos}" y="{$max-y - .}" height="{.}" width="{$width}" /> <text x="{$pos + $width div 2.0}" y="{$max-y - $space}"> <xsl:value-of select="."/> </text> </g> </xsl:template> </xsl:stylesheet>
产生
<svg xmlns="http://www.w3.org/2000/svg"> <defs> <style type="text/css"><![CDATA[ g.bar text { font-family: Arial; text-anchor: middle; fill: white; } g.bar rect { fill: black; } ]]></style> </defs> <g transform="translate(10,10)"> <g class="item" id="item-1" transform="translate(0)"> <g class="bar"> <rect x="0" y="100" height="100" width="40"/> <text x="20" y="190">100</text> </g> <g class="bar"> <rect x="50" y="0" height="200" width="40"/> <text x="70" y="190">200</text> </g> </g> <g class="item" id="item-2" transform="translate(110)"> <g class="bar"> <rect x="0" y="150" height="50" width="40"/> <text x="20" y="190">50</text> </g> <g class="bar"> <rect x="50" y="100" height="100" width="40"/> <text x="70" y="190">100</text> </g> </g> </g> </svg>
这样做
在我的机器上