Digital humanities


Maintained by: David J. Birnbaum (djbpitt@gmail.com) [Creative Commons BY-NC-SA 3.0 Unported License] Last modified: 2023-04-03T21:24:47+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:




    
    
    
    
    
    
    
    
    
    
    
    
    
    
    90
    80
    70
    60
    50
    40
    30
    20
    10
    
    
    Curly
    
    Larry
    
    Moe
]]>

Most of this is self-explanatory, but the part that might be new is the @stroke-linecap attribute on the axis <line> elements. Without that setting, the axis lines don’t meet smoothly because the position values of a line describe the middle of the line in terms of its stroke-width, so a 2px-wide line extends 1px to either side of the specified position value. You can see the effect if you increase the stroke width (here to a value of 10):


    
    
    
]]>

Adding the @stroke-linecap attribute with the value "square" fixes the problem. Don’t think it doesn’t matter with a thin line, though; it’s visible even with thin lines, even if not as conspicuously as with thick ones, and attention to these sorts of details is part of the difference between a professional job and a careless one.

It’s convenient to draw the X and Y axes as separate SVG <line> elements because we think of them as two lines, and as long as we remember to use the @stroke-linecap attribute to ensure that they meet squarely we’ll get the output we want. As an alternative, though, we could use the SVG <polyline> element. The <polyline> element draws connected line segments, so instead of the two <line> elements for the axes we could have used just the single following <polyline> element:

]]>

The value of the @points attribute is a sequence of X, Y coordinates, with the X and Y values separated by commas and the coordinate pairs separated by spaces. The example above says to start by drawing a line segment from 205,200 to 25,200 (this is the X axis) and then continue from 25,200 with a segment to 25,0 (this is the Y axis). One advantage of using <polyline> is that you don’t have to think about specifying @stroke-linecap where your X and Y axes meet, since polyline line segments are naturally connected smoothly. But because polylines can be used to describe shapes that might be filled, you do have to specify a "none" value for the @fill attribute. (Try removing it to see the effect.) You can read more about <polyline> at https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polyline.

Sample output

The output should look something like:

90 80 70 60 50 40 30 20 10 Curly Larry Moe