Another Flare-inspired visualization, this one shows employment data for various jobs and job categories from Minnesota. Seasonal variations are apparent, such as the summer peaks in amusement parks (which coincides with dips in educational services!).
Color saturation is used to encode the population for each job, since the small multiples use non-aligned scales. This makes it easy to distinguish the one individual that worked in space research from the hundreds of thousands in manufacturing. This visualization also demonstrates the scale inversion interaction technique, showing the closest data point to the mouse.
Next: Focus + Context
<html>
<head>
<title>Minnesota Employment</title>
<script type="text/javascript" src="../protovis-r3.2.js"></script>
<script type="text/javascript" src="minnesota.js"></script>
</head>
<body>
<script type="text/javascript+protovis">
var w = 200,
h = 30,
numberFormat = pv.Format.number(),
dateFormat = pv.Format.date("%B %Y");
/* Color by maximum number of people employed in that job. */
var c = pv.Scale.log(minnesota, function(d) pv.max(d.values))
.range("#ccc", "#1f77b4");
/* Tile the visualization for each job. */
var vis = new pv.Panel()
.data(minnesota)
.width(w)
.height(h + 10)
.top(6)
.left(6)
.right(6)
.bottom(6);
/* A panel instance to store scales (x, y) and the mouseover index (i). */
var panel = vis.add(pv.Panel)
.def("i", -1)
.def("x", function(d) pv.Scale.linear(d.values, pv.index).range(0, w))
.def("y", function(d) pv.Scale.linear(0, pv.max(d.values)).range(0, h))
.bottom(10)
.events("all")
.event("mousemove", pv.Behavior.point(Infinity).collapse("y"));
/* The area. */
panel.add(pv.Area)
.data(function(d) d.values)
.fillStyle(function(d, p) panel.i() < 0 ? c(pv.max(p.values)) : "#2ca02c")
.left(function() panel.x()(this.index))
.height(function(d) panel.y()(d))
.bottom(0)
.event("point", function() panel.i(this.index))
.event("unpoint", function() panel.i(-1));
/* The x-axis. */
panel.add(pv.Rule)
.bottom(0);
/* The mouseover dot. */
panel.add(pv.Dot)
.visible(function() panel.i() >= 0)
.left(function() panel.x()(panel.i()))
.bottom(function(d) panel.y()(d.values[panel.i()]))
.fillStyle("#ff7f0e")
.strokeStyle(null)
.size(10);
/* The label: either the job name, or the month and value. */
panel.add(pv.Label)
.bottom(-1)
.textBaseline("top")
.left(function() panel.i() < 0 ? 0 : null)
.right(function() panel.i() < 0 ? null : 0)
.textAlign(function() panel.i() < 0 ? "left" : "right")
.textStyle(function() panel.i() < 0 ? "#999" : "#000")
.text(function(d) panel.i() < 0 ? d.name
: dateFormat(new Date(2000, panel.i() * 3, 1))
+ ": " + numberFormat(d.values[panel.i()]));
vis.render();
</script>
</body>
</html>