XSLT Conversion to Scalable Vector Graphics
If you want to try this file, copy and paste the code
into a file called nutrition_svg.xslt in the
nutrition directory. (See Linux and Windows setup
instructions.)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"
doctype-public="-//W3C//DTD SVG 1.0//EN"
doctype-system="http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"https://alistapart.com/>
<xsl:key name="category" match="nutrition/daily-values/*"
use="local-name()"https://alistapart.com/>
<xsl:template match="nutrition">
<xsl:variable name="n">
<xsl:choose>
<xsl:when test="count(food)*25+40 < 400">400</xsl:when>
<xsl:otherwise>
<xsl:value-of select="count(food)*25 + 40"https://alistapart.com/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<svg width="600" height="{$n}"
viewBox="0 0 600 0 {$n}">
<script type="text/ecmascript">
<![CDATA[
var currId = "0";
function show( id )
{
var obj;
if (id != currId)
{
obj = document.getElementById( "graph" + currId );
obj.setAttribute( "visibility", "hidden");
if (currId != 0)
{
obj = document.getElementById( "rect" + currId );
obj.setAttribute( "fill", "#eeeeff" );
}
obj = document.getElementById( "graph" + id );
obj.setAttribute( "visibility", "visible");
obj = document.getElementById( "rect" + id );
obj.setAttribute( "fill", "#ffff00");
currId = id;
}
}
// ]]>
</script>
<xsl:comment>Draw axes</xsl:comment>
<g transform="translate(40,20)">
<path d="M0 0 L0 200 200 200
M -3 0 h6 M -3 20 h6 M -3 40 h6 M -3 60 h6
M -3 80 h6 M -3 100 h6 M -3 120 h6 M -3 140 h6
M -3 160 h6 M -3 180 h6" style="stroke:black; fill:none;"https://alistapart.com/>
<g style="font-size: 8pt; text-anchor:end">
<text x="-5" y="5">100%</text>
<text x="-5" y="45">80%</text>
<text x="-5" y="85">60%</text>
<text x="-5" y="125">40%</text>
<text x="-5" y="165">20%</text>
<text x="-5" y="205">0%</text>
</g>
<g style="font-size: 8pt; writing-mode: tb;">
<text x="25" y="205">Total Fat</text>
<text x="75" y="205">Sat. Fat</text>
<text x="125" y="205">Cholesterol</text>
<text x="175" y="205">Sodium</text>
</g>
</g>
<xsl:comment>Preliminary instructions</xsl:comment>
<g transform="translate(40,20)" id="graph0">
<text x="50" y="50">Click a food to see
<tspan x="50" y="70">its data.</tspan></text>
</g>
<xsl:apply-templates select="food"https://alistapart.com/>
</svg>
</xsl:template>
<xsl:template match="food">
<xsl:comment>Display the name of the food</xsl:comment>
<g onclick="show({position()})">
<rect id="rect{position()}"
x="300" width="250" height="20" fill="#eeeeff"
style="stroke:black;">
<xsl:attribute name="y"><xsl:value-of
select="(position() * 25) - 15"https://alistapart.com/></xsl:attribute>
</rect>
<text x="425" style="font-size: 10pt; text-anchor:middle;">
<xsl:attribute name="y"><xsl:value-of
select="(position() * 25) - 15 + 14"https://alistapart.com/></xsl:attribute>
<xsl:value-of select="name"https://alistapart.com/>
</text>
</g>
<xsl:comment>Create a hidden graph for that food</xsl:comment>
<g id="graph{position()}" visibility="hidden"
transform="translate(40,20)">
<xsl:call-template name="draw-bar">
<xsl:with-param name="number" select="0"https://alistapart.com/>
<xsl:with-param name="node" select="total-fat"https://alistapart.com/>
</xsl:call-template>
<xsl:call-template name="draw-bar">
<xsl:with-param name="number" select="1"https://alistapart.com/>
<xsl:with-param name="node" select="saturated-fat"https://alistapart.com/>
</xsl:call-template>
<xsl:call-template name="draw-bar">
<xsl:with-param name="number" select="2"https://alistapart.com/>
<xsl:with-param name="node" select="cholesterol"https://alistapart.com/>
</xsl:call-template>
<xsl:call-template name="draw-bar">
<xsl:with-param name="number" select="3"https://alistapart.com/>
<xsl:with-param name="node" select="sodium"https://alistapart.com/>
</xsl:call-template>
</g>
</xsl:template>
<xsl:template name="draw-bar">
<xsl:param name="number"https://alistapart.com/>
<xsl:param name="node"https://alistapart.com/>
<xsl:variable name="pct">
<xsl:value-of
select="round(100 * $node div key('category',name($node)))"https://alistapart.com/>
</xsl:variable>
<rect width="25">
<xsl:attribute name="x"><xsl:value-of
select="12.5 + $number*50"https://alistapart.com/></xsl:attribute>
<xsl:attribute name="y"><xsl:value-of
select="200 - $pct*2"https://alistapart.com/></xsl:attribute>
<xsl:attribute name="height"><xsl:value-of
select="$pct * 2"https://alistapart.com/></xsl:attribute>
<xsl:choose>
<xsl:when test="$pct <= 50">
<xsl:attribute name="style">fill:green;</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="style">fill:red;</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</rect>
<text style="font-size:8pt; text-anchor: middle;">
<xsl:attribute name="x"><xsl:value-of
select="25 + $number * 50"https://alistapart.com/></xsl:attribute>
<xsl:attribute name="y"><xsl:value-of
select="195 - $pct*2"https://alistapart.com/></xsl:attribute>
<xsl:value-of select="$pct"https://alistapart.com/><xsl:text>%</xsl:text>
</text>
</xsl:template>
</xsl:stylesheet>
