In XSLT Exercise 3, you constructed an HTML table from survey data originally printed in a nineteenth-century table of interest to the Nell Nelson Project:
The Nelson team has encoded a version of this table in TEI markup called feature structures designed for binding related data together, and from which we extracted the HTML table data in our XSLT assignment. We now return to this file to plot the data again, writing XSLT to generate SVG in the form of a stacked bar graph. You may find it helpful to review your work and our solution to XSLT Exercise 3 as you begin this assignment.The source text can be found here: WSGATableCh1.xml if you misplaced the copy you worked with in XSLT Exercise 3. You should right-click on this link, download the file, and open it in <oXygen/>. (We will plan to use this file at least one more time on a JavaScript exercise, so once again, you may wish to keep this file handy.) (As usual, if you are downloading, please do not just click to open it in a browser and copy, which can add some browser rendering characters that will mess up your code; instead, you need to right click and download the file to save it to your machine.)
Reviewing the contents of the TEI XML file, notice how the survey data is bound together in elements and attributes.
Each <fs>
element holds a series of <f>
elements which contain a survey question and a series of responses including data in @n
attributes on the number of people who responded. Here is a sample of our TEI source coding:
<fs type="QandA"> <f name="question"> <string>Are there facilities for washing?</string> </f> <f name="note">Fourteen answered yes, but if caught washing are fined.</f> <f name="response" select="Yes" n="460"/> <f name="response" select="No" n="124"/> <f name="response" select="Blank" n="226"/> <f name="response" select="Yes_but_fined" n="14"/> </fs>
Because you are reading from a TEI file, we need to identify the TEI as our xpath-default-namespace (highlighted in purple below), and we need to indicate that we are outputting SVG in the SVG namespace (highlighted in green below. The output method is set to XML. So you should set your xsl:stylesheet
and xsl:output
statements thus:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xpath-default-namespace="http://www.tei-c.org/ns/1.0" exclude-result-prefixes="xs" xmlns="http://www.w3.org/2000/svg"> <xsl:output method="xml" indent="yes"/>
Your goal is to present an effective visual summary of one portion of these survey responses: only the questions that could be answered with a Yes
or a No
(which includes the one distinctive question that could be answered Yes but fined
). You will ultimately produce a stacked bar chart that represents the percentages of people who responded in each way to the twelve questions that involved Yes
or No
answers, which means that you will need to do some calculations in the XSLT you write. Here is a sample view of output we would like to produce, though your graph does not have to look exactly like ours. We chose to sort our questions by the quantities of people who answered Yes
, to present the questions and the survey data in order from those most frequently to least frequently answered with Yes
. You may choose to sort your data a different way, such as by the quantity of Blank (missing) or No
responses. You may, of course, also decide to scale and color your graph and bars differently than we did, and you will want to decide whether you prefer to use the SVG <rect>
element or the SVG <line>
element (which is what we used in our solution). While we leave it up to you to decide how you want to scale and color your graph or the fonts you want to use for your text, you will need to do the following:
Yesor
No. (For our purposes, you can ignore the other handful of survey questions that have a different set of responses.)
Yesto a particular survey question, you will need to divide the
@n
of Yesanswers by the
sum()
of all the @n
who responded to that particular question and multiply the result by 100 to make a percent value.<g>
(group) element in the upper right quadrant, to set our X axis and Y axis to meet at x=0 and y=0, and to plot all our y Values to start from a zero base point at the X axis and move up the screen into negative numbers. We then use the <g>
element to shift this a little to the right and down into visible and workable coordinate space on the display monitor, by simply setting the @transform
attribute with the translate()
function. To do this:
<g>
start tag as <g transform="translate(0, 600)">
will shift it down by 600 pixels (the first number is the amount to shift on the X axis and the second is the amount on the Y axis). You can hard-code the number of pixels to shift down, but a more elegant approach is to use XPath to calculate the height of the tallest bar and employ that calculation in setting the value for the shift. In our sample solution, note the <g transform="translate(30, 400)"> near the beginning, which shifts the image we’ve drawn a bit to the right (so that the percentage labels on the Y axis will be visible) and down (so that the whole chart will be visible).Yes(and there should be twelve of these), plot an X and a Y axis that is appropriate to hold all your bar plots, and label your Y axis in some way that demonstrates you are working with percent values. (You may wish to draw a slashed line of some kind at the 50% mark as we did to lay overtop of your graph, or draw faint lines to sit in the background (like in this clickable, interactive example from an Obdurodon project: http://pavlova.obdurodon.org/character_chart.xhtml). Use global variables to help you space your bars evenly across the X axis.
text
element formatting, and what attributes are used to control it. (There are a number that you might experiment with to rotate text and change its orientation, but we used the @style="writing-mode: tb;"
attribute to make the text run vertically down the page.) Take a look at Jakob Jenkov's SVG tutorial for a good resource for learning about the range of attributes you can apply to SVG text
and other SVG elements, and the various things they do. We find the @text-anchor
attribute especially helpful to anchor the text’s X and Y coordinates either in the start, end, or exact center of the text string.round()
or format-number()
functions to remove the decimal places, or just use one or two decimal points in the tenths or hundredths. Look up these functions in the Michael Kay book if you have it, or look at w3schools' examples of format-number() and round(), which simply takes a decimal number and rounds to the nearest integer. (For purposes of SVG plotting, you can have X or Y coordinates that go out to a large number of decimal places, so the only reason you have to think about rounding is that you may want to display numbers in a way that human readers will expect.)<xsl:sort>
on a particular response of your choice. We usually recommend that you sort on the values that you put at the base of your stacked bars, but you can sort on any that you wish, and you may sort on a value that is set in the middle or at the top of your plot as you prefer.Turn in your XSLT file. We will generate your SVG output ourselves by running your XSLT. Remember to save and open your SVG output in oXygen and in a web browser to be sure it is valid and that it is rendering as you think it should be.