Digital humanities

Maintained by: David J. Birnbaum ( [Creative Commons BY-NC-SA 3.0 Unported License] Last modified: 2015-11-07T20:19:51+0000

SVG assignment #3 answers


The basic task of SVG assignment 2 was to create an SVG bar graph of the democratic results of the 2012 US presidential election. See the assignment page for a more detailed description, suggestions, and a link to the input data in XML form. See also our posted solution. For SVG assignment 3 we asked you to enhance your answer to #2 by using variables, and also by including additional information.

Sample solution

The XSLT that we used to produce our JavaScript-enhanced enhanced output is below. Note the extensive use of variables and calculated values. This output embeds the SVG inside HTML (that is, it isn’t stand-alone SVG of the sort that we’ve been creating so far), and it needs the CSS and JavaScript for completely correct display and interactive functionality.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl=""
    xmlns="" version="2.0" xmlns:xs=""
    <xsl:output indent="yes"/>
    <xsl:template match="/">
        <xsl:variable name="sorted" as="node()+">
            <xsl:for-each select="//state">
                <xsl:sort select="candidate[@party='Democrat'] div sum(candidate)"
                <xsl:copy-of select="current()"/>
        <xsl:variable name="barInterval" select="15"/>
        <xsl:variable name="barHeight" select="300"/>
                <title>Election results</title>
                <link rel="stylesheet" type="text/css" href=""/>
                <link rel="stylesheet" type="text/css" href="style.css"/>
                <link rel="stylesheet" type="text/css" href="election.css"/>
                <script type="text/javascript" src="election.js">//</script>
                <h1>Results of 2012 US presidential election</h1>
                <p>Data scraped from <a
                    Click on a bar to see the votes for that state.</p>
                <div id="svg-wrap">
                    <svg xmlns="" height="375">
                        <g transform="translate(30, 330)">
                            <line x1="20" x2="20" y1="0" y2="-320" stroke="black" stroke-width="1"/>
                            <line x1="20"
                                x2="{count(//state)*$barInterval + sum(//state/@elec)*2 + 20}"
                                y1="0" y2="0" stroke="black" stroke-width="1"/>
                            <text x="10" y="5" text-anchor="end">0%</text>
                            <text x="10" y="{5 - $barHeight div 2}" text-anchor="end">50%</text>
                            <text x="10" y="{5 - $barHeight}" text-anchor="end">100%</text>
                            <xsl:for-each select="$sorted">
                                <xsl:variable name="statePos" select="position()-1"/>
                                <xsl:variable name="xPosition"
                                    select="$statePos*$barInterval + sum($sorted[position() lt ($statePos + 1)]/@elec)*2 + 22"/>
                                <xsl:variable name="totalVotes" select="sum(candidate)"/>
                                <xsl:variable name="elec" select="@elec"/>
                                <xsl:variable name="acro" select="@acro"/>
                                <g id="{$acro}" class="wrapper">
                                    <text x="{$xPosition + ($elec)}" y="20" text-anchor="middle">
                                        <xsl:value-of select="$acro"/>
                                    <text x="{$xPosition + ($elec)}" y="35" text-anchor="middle">
                                        <xsl:value-of select="$elec"/>
                                    <xsl:for-each select="candidate">
                                        <xsl:variable name="percentage"
                                            select="current() div $totalVotes"/>
                                        <xsl:variable name="color">
                                                <xsl:when test="@party='Democrat'">blue</xsl:when>
                                                <xsl:when test="@party='Republican'">red</xsl:when>
                                                <xsl:when test="@party='Libertarian'"
                                                <xsl:when test="@party='Green'">green</xsl:when>
                                        <rect x="{$xPosition}"
                                            y="{-($percentage+(sum(../candidate[@party lt current()/@party]) div $totalVotes))*$barHeight}"
                                            stroke="black" stroke-width=".5" fill="{$color}"
                                            width="{$elec*2}" height="{($percentage*$barHeight)}"/>
                            <line x1="20"
                                x2="{count(//state)*$barInterval + sum(//state/@elec)*2 + 20}"
                                y1="-{$barHeight div 2}" y2="-{$barHeight div 2}" stroke="black"
                                opacity="0.5" stroke-dasharray="8 4" stroke-width="1"/>
                <h2>Votes for <span id="current-state">PA</span></h2>
                <table id="results" border="1">
                    <xsl:for-each select="//state">
                        <xsl:variable name="total" select="sum(candidate)"/>
                        <xsl:variable name="elec" select="@elec"/>
                        <tbody id="tbody-{@acro}">
                            <xsl:if test="not(@acro = 'PA')">
                                <xsl:attribute name="style">display: none;</xsl:attribute>
                            <xsl:for-each select="candidate">
                                <xsl:sort select="@party" order="descending"/>
                                <xsl:variable name="pct" select=". div $total" as="xs:double"/>
                                <tr class="{@party}">
                                    <xsl:if test="($pct * 100) gt 50">
                                        <xsl:attribute name="style"
                                        <xsl:value-of select="@party"/>
                                        <xsl:value-of select="format-number(.,'#,###')"/>
                                        <xsl:value-of select="format-number($pct,'0.00%')"/>
                            <tr style="font-weight: bold;">
                                    <xsl:value-of select="format-number($total,'#,###')"/>
                                <td>Electoral: <xsl:value-of select="@elec"/></td>
                    <tr style="font-weight: bold; visibility:hidden">
                        <td>Electoral: 55</td>