Maintained by: David J. Birnbaum (djbpitt@gmail.com)
Last modified:
2023-04-03T21:24:47+0000
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).
Here is one possible solution:
]]>
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.
The output should look something like: