Digital humanities


Maintained by: David J. Birnbaum (djbpitt@gmail.com) [Creative Commons BY-NC-SA 3.0 Unported License] Last modified: 2016-11-08T15:13:32+0000


SVG assignment #1 solution

Overview

Your task is to use the data from a mythical Best Stooge Ever contest to draw (by hand) an SVG bar chart of the results. In XML terms, the scores are:

<results>
    <stooge name="Curly">50</stooge>
    <stooge name="Larry">35</stooge>
    <stooge name="Moe">15</stooge>
</results>

For your bar chart, you’ll want to draw an x axis and y axis (using the SVG <line> element), three bars of different colors (using the SVG <rect> element), and labels on the axes or the bars for the stooges and the numerical values of their vote counts (using the SVG <text> element).

One solution

Here is one possible solution:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <!-- x and y axes -->
    <line x1="20" y1="205" x2="170" y2="205" stroke="black" stroke-width="2"/>
    <line x1="20" y1="205" x2="20" y2="0" stroke="black" stroke-width="2"/>
    <!-- labels for Y axis -->
    <text x="13" y="23" text-anchor="end">50</text>
    <text x="13" y="43" text-anchor="end">45</text>
    <text x="13" y="63" text-anchor="end">40</text>
    <text x="13" y="83" text-anchor="end">35</text>
    <text x="13" y="103" text-anchor="end">30</text>
    <text x="13" y="123" text-anchor="end">25</text>
    <text x="13" y="143" text-anchor="end">20</text>
    <text x="13" y="163" text-anchor="end">15</text>
    <text x="13" y="183" text-anchor="end">10</text>
    <text x="13" y="203" text-anchor="end">5</text>
    <!-- horizontal ticks on Y axis -->
    <line x1="15" x2="18" y1="18" y2="18" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="38" y2="38" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="58" y2="58" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="78" y2="78" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="98" y2="98" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="118" y2="118" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="138" y2="138" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="158" y2="158" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="178" y2="178" stroke="black" stroke-width="1"/>
    <line x1="15" x2="18" y1="198" y2="198" stroke="black" stroke-width="1"/>
    <!-- rectangular data bars, with name labels -->
    <rect x="20" y="5" width="40" height="200" fill="green" stroke="black" stroke-width="1"/>
    <text x="40" y="225" text-anchor="middle">Curly</text>
    <rect x="70" y="65" width="40" height="140" fill="blue" stroke="black" stroke-width="1"/>
    <text x="90" y="225" text-anchor="middle">Larry</text>
    <rect x="120" y="145" width="40" height="60" fill="red" stroke="black" stroke-width="1"/>
    <text x="140" y="225" text-anchor="middle">Moe</text>
</svg>

We find it difficult to calculate the X and Y positions when the two axes don’t intersect at 0,0 and when the Y values increase as we move down the Y axis (since humans expect Y values to decrease as we move down). We can make the arithmetic more human-friendly by drawing the graph at 0,0 (which pushes the labels on the Y axis off the left edge, so that they have negative X values). Even better, we can make the Y values negative, so that they grow up (into the invisible upper right quadrant), and we can then shift the entire image down and to the right by using a @transform attribute with a translate() function on a <g> (= group) element that contains all of the lines and rectangles and text. Here’s how that looks (see whether you don’t also find the numbers on this version easier to understand, and to plot, than in the first version):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <g transform="translate(30, 250)">
        <line x1="0" y1="0" x2="150" y2="0" stroke="black" stroke-width="2"/>
        <line x1="0" y1="0" x2="0" y2="-210" stroke="black" stroke-width="2"/>
        <line x1="-3" x2="3" y1="-20" y2="-20" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-40" y2="-40" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-60" y2="-60" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-80" y2="-80" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-100" y2="-100" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-120" y2="-120" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-140" y2="-140" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-160" y2="-160" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-180" y2="-180" stroke="black" stroke-width="1"/>
        <line x1="-3" x2="3" y1="-200" y2="-200" stroke="black" stroke-width="1"/>
        <text x="-8" y="-15" text-anchor="end">5</text>
        <text x="-8" y="-35" text-anchor="end">10</text>
        <text x="-8" y="-55" text-anchor="end">15</text>
        <text x="-8" y="-75" text-anchor="end">20</text>
        <text x="-8" y="-95" text-anchor="end">25</text>
        <text x="-8" y="-115" text-anchor="end">30</text>
        <text x="-8" y="-135" text-anchor="end">25</text>
        <text x="-8" y="-155" text-anchor="end">40</text>
        <text x="-8" y="-175" text-anchor="end">45</text>
        <text x="-8" y="-195" text-anchor="end">50</text>
        <rect x="0" y="-200" width="40" height="200" fill="green" stroke="black" stroke-width="1"/>
        <text x="20" y="15" text-anchor="middle">Curly</text>
        <rect x="60" y="-140" width="40" height="140" fill="blue" stroke="black" stroke-width="1"/>
        <text x="80" y="15" text-anchor="middle">Larry</text>
        <rect x="120" y="-60" width="40" height="60" fill="red" stroke="black" stroke-width="1"/>
        <text x="140" y="15" text-anchor="middle">Moe</text>
    </g>
</svg>

The output should look like:

5 10 15 20 25 30 35 40 45 50 Curly Larry Moe