特定
- <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>
这样做
在我的机器上