How-to: a dojox Charting work experience timeline

When creating my last personal website, I decided I wanted to put the power of Dojo Charting to use in a work experience timeline. This timeline chart would would give a horizontal representation in width to how long I was at a job, with each job being a different color spanning the years as labeled underneath.

I currently rewrote this widget using Dojo 1.7.1, and as you can see on my main page - there is currently a bug with tooltips (handily fixed by Tom Trenka in trunk) that is causing the tooltip to hangout on the left side of the page.

We start with loading up all the dependencies for this widget

<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script> <script> require(["dojo/dom-class","dojox/charting/Chart", "dojox/charting/action2d/Tooltip","dojo/query", "dojox/charting/themes/Claro","dojox/charting/plot2d/Bars", "dojox/charting/axis2d/Default","dojo/domReady!"], function(domClass, Chart, Tooltip, query, theme) {

We grab dom-class to handle interacting with the widget and handling user events (such as clicking on a portion to change which job is displayed), but it is not necessary to display just the chart itself.

Notice that even though we load Bars and Default, we don't need to hold references to them in order to build the chart. Getting started, we create a chart:

var chart = new Chart("jobTimeline",{fill:null}).setTheme(theme). addAxis("x", { includeZero: true, fontColor:"black", labels: [{value: 0, text: "2002"}, {value: 1, text: "2003"}, {value: 2, text: "2004"}, {value: 3, text: "2005"}, {value: 4, text: "2006"}, {value: 5, text: "2007"}, {value: 6, text: "2008"}, {value: 7, text: "2009"}, {value: 8, text: "2010"}, {value: 9, text: "2011"}, {value: 10, text: "2012"} ], rotation: 45 }).

Lets step through some of the attributes shown here, we are first giving the chart it's new home: the jobTimeline domNode. Standard stuff. We set the theme to the chart, which will set default colors - then we create the x axis.

What is important to note is that we are setting the includeZero attribute to true. This makes sure that our label for the beginning of the chart is anchored at 2002 when rendered. You will also notice that the values for the labels aren't perfectly linear, this is because I didn't end up switching jobs each year - so only some years have labels to them.

Now here's the real trick, setting the y axis. After a little bit of experimentation, I found that setting the y axis 1 unit high was all I needed to do to give the impression of a time-line. If you are a clever reader, you'll remark that this causes the bars to stack upon one another - and you would be correct.

addAxis("y", {vertical: true, natural: true, labels: [{value:1, text: " "}]}). addPlot("default", {type: "Bars"}). addSeries("Series A", [1]). addSeries("Series B", [1.8]). addSeries("Series C", [2.5]). addSeries("Series D", [4.1]). addSeries("Series E", [5]). addSeries("Series F", [6.7]). addSeries("Series G", [9]). addSeries("Series H", [10]);

After adding the y axis, we add a plot to the default with a type of Bars. This is both where our dependencies "dojox/charting/plot2d/Bars", and "dojox/charting/axis2d/Default" come into play. You'll need to load Default as well as which type of plot you want - even if you don't need a reference to them. I go on to add a series for each job that I have held. The numbers given become important when you want to both track which job is being clicked on, as well as for the Tooltips to function correctly.

Only two lines are left to get our chart to render:

var anim4b = new Tooltip(chart, "default", {text: makeTooltip}); chart.render();

Ah ha you say, what is this "makeTooltip" that I am referencing? I am using a function to pass text values into the Tooltip:

makeTooltip = function(o) { var text; switch (o.x) { case 1: text = "Runzheimer, Intl - Intern"; break; case 1.8: text = "Web Developer - WRCHD"; break; ... case 9: text = "Academic Technology Developer - Learning Solutions UW-Madison"; break; case 10: text = "Software Engineer - Sitepen, inc."; break; } return text; };

This function takes the x value of the bar that you are hovering over, and grabs the text for that x value. This is why it was important to keep track of the value of each series you added.

Only one piece is left, event handling: clicking and hovering. This is accomplished using the connectToPlot event handler that ships with Chart. You pass it which plot you want to listen to and it uses a callback to let you customize your event handling.

chart.connectToPlot("default",function(evt) { var shape = evt.shape, type = evt.type; if(type == "onmouseover") { if(!shape.originalFill) { shape.originalFill = shape.fillStyle; } shape.setFill("lightblue"); } else if(type == "onmouseout") { shape.setFill(shape.originalFill); } else if(type == "onclick"){ x = evt.x; changeJob(x.toString(), domClass); } });

That's all there is to it, easy as pie! chart! Okay sorry for the pun.