State Population Mapping

The State Population demo is similar in some respects to the Hurrican demo in that it was made with GIS data for the map data and then some custome GIS work to extract the data from tables and generate the animation elements. Let's look at a couple of spects of it.

First off, there is simply the framework of the outlines of the 48 (lower) states as SVG shapes. As before, these were extracted from publicly available GIS files and converted to SVG.

Then there are 2 sources of data:

  • The relative proportion of the state's population to the overall population of the US
  • The proportion of the states's population relative to that state's total today

The first is used to shade the map (called a chlopleth map) as a thematic map using color (the typical ROYGB) with the most populus states being red and the least blue. In addition, both data-sets are used to create a graph in the lower-left of the graphic that shows a graph over time of the trends of the two data-sets. This graph is updated with the apprpriate state's data as the user mouses over the map.

So how is this done? The graph is drawn in the lower left quadrant of the map, below California:

<svg id="Graph" x="50" y="400" height="150" width="200" viewBox="1790 0 210 1" pointer-events="all" 
           preserveAspectRatio="none" stroke-width="0.02" overflow="visible">
    <g transform="matrix(1 0 0 -1 0 1)" font-family="'TimesNewRomanPSMT'" >
        <rect x="1790" y="0" height="1" width="210" fill="none" stroke="black" />
        <g fill="none" stroke="grey" stroke-width="0.001" >
            <line x1="1800" y1="0" x2="1800" y2="1" />
            <line x1="1850" y1="0" x2="1850" y2="1" />
            <line x1="1900" y1="0" x2="1900" y2="1" />
            <line x1="1950" y1="0" x2="1950" y2="1" />
            <line x1="1790" y1="0" x2="1790" y2="1" stroke="gold" stroke-width="1" >
                <animate attributeName="x1" dur="22s" fill="freeze" values="1790;2000" />
                <animate attributeName="x2" dur="22s" fill="freeze" values="1790;2000" />
            </line>
        </g>

        <use id="useStatePop" xlink:href="#CaliforniaPop" stroke="blue" fill="none" />
        <use id="useStateProp" xlink:href="#CaliforniaProp" stroke="red" fill="none"/>
        <use id="useStateName" xlink:href="#CaliforniaName" transform="matrix(2 0 0 -0.01 1790 1.05)"  fill="red" />

        <g fill="black" >
            <text transform="matrix(1 0 0 -0.01 1790 1)" text-anchor="end" baseline-shift="-30%" >1 </text>
            <text transform="matrix(1 0 0 -0.01 1790 0)" text-anchor="end"  baseline-shift="-30%">0 </text>
            <text transform="matrix(1 0 0 -0.01 2000 1)" text-anchor="start" baseline-shift="-30%" > 1</text>
            <text transform="matrix(1 0 0 -0.01 2000 0)" text-anchor="start"  baseline-shift="-30%"> 0</text>

            <text transform="matrix(1 0 0 -0.01 1800 0)" text-anchor="middle" baseline-shift="-150%">1800</text>
            <text transform="matrix(1 0 0 -0.01 1850 0)" text-anchor="middle" baseline-shift="-150%">1850</text>
            <text transform="matrix(1 0 0 -0.01 1900 0)" text-anchor="middle" baseline-shift="-150%">1900</text>
            <text transform="matrix(1 0 0 -0.01 1950 0)" text-anchor="middle" baseline-shift="-150%">1950</text>
            <text transform="matrix(1 0 0 -0.01 2000 0)" text-anchor="middle"  baseline-shift="-150%">2000</text>
        </g>
    </g>

    <set xlink:href="#useStatePop" attributeName="xlink:href" begin="Alabama.mouseover" to="#AlabamaPop" />
    <set xlink:href="#useStateProp" attributeName="xlink:href" begin="Alabama.mouseover" to="#AlabamaProp" />
    <set xlink:href="#useStateName" attributeName="xlink:href" begin="Alabama.mouseover" to="#AlabamaName" />
    ... 
</svg>

The animation lasts 22 seconds, one second for each decade from 1790 to 2010.

The first two animation elements simply move the timeline (gold line) indicator across the graph as time passes.

Then the three use elements point to the appropriate state's data to use to stroke the state's data on the graph and to draw the state's name. This is done by pointing to the actual data. Here is Alabama's for example (as usual a lot of data omitted for brevity).

<text id="AlabamaName">Alabama</text>
 <path id="AlabamaPop" d="M1790 0.000L1800 0.000L1810 0.000L1820 0.032L1830 0.070L1840 0.133L1850 0.174 ..." />
 <path id="AlabamaProp" d="M1790 0.000L1800 0.000L1810 0.000L1820 0.413L1830 0.696L1840 1.000L1850 0.962 ..." />

So when the user mouses over a given state, that state's data is pointed to by the use elements in the graph.

Finally, the colors of the states are animated over time by a single animation element that just updates the color every second:

<animate xlink:href="#Alabama" attributeName="fill" dur="22s" fill="freeze" values="#0101ff;#0101ff;#0101ff;#0150ff; ..." />

And that's it! Click on this link to see the actual rendered demo in all its growing glory!