Note: We just pushed out an update to the data table that includes a third tab for assistant coach salaries. I have updated my blog post to include links to two additional data files but otherwise have not discussed this new tab. If you are reviewing my JavaScript code, however, you may find it more helpful to look at the fnFormatAsstDetails function used by this new tab rather than the fnFormatDetails function discussed below. The code in this function is less complex because the assistant coach data lacked some of the challenges found in the head coach data.
In my last blog post, I talked about how I built a jQuery DataTable with expandable accordion rows to run with a USA Today story to highlight NCAA football coach salaries. If you check out the DataTable, you’ll see that when you expand a row, you get a picture of the head coach and up to five years of salary data. You’ll also see a dynamically generated Google chart that maps salary data and compares it with the median salaries of other coaches.
In this blog post, I’ll talk about how I embedded that Google chart.
DataTables is a jQuery plugin that enables you to create a richly interactive and highly customizable HTML table which users can sort and filter. Allan Jardine’s open-source software is extremely complex yet simple to use, and he has attracted a large following of users over the years who have built just about every kind of DataTable imaginable. The code is regularly updated and very well documented, with tons of examples, and Jardine frequently chimes in when someone posts a question on the DataTables forums. At USA Today, we routinely throw up a data table to run with a story in as little as 20 minutes.
If you’d like to download all the source code and JSON data files for the NCAA coaches DataTable, click here to get the .htm file and here, here, here, here and here to get the data files.
I got good feedback on the Google chart and was encouraged to blog about it. You’ll be happy to know it was not at all difficult. It’s also not elegant. The JavaScript function that fires when the user clicks a row to expand just builds a long string of html that is rendered once that string is returned by the function. That html code includes a dynamically generated <img> tag that houses the Google chart.
The html for an expanding row and, with it, the Google chart <img> tag is constructed in the fnFormatDetails function, which is about 300 lines of code. All but about 25 lines of that code are used to create the Google chart.
If that discourages you, read on because chances are good you can develop a Google chart of your own with far less code. In fact, if you hard-coded those image tags in your data, you’d need almost no JavaScript code at all!
In this case, the dataset posed some challenges that required some fairly heavy client-side JavaScript code to handle. For example, all coaches have salary data for 2011 but not necessarily as far back as 2006. (In fact, we don’t have any salary data at all for 2008.) In order to plot a line from 2006 through 2011, I had to have data points for every year. That meant the code had to calculate average salaries for missing years. I also added code to put markers over all salaries that were not calculated.
Finally, and most importantly, the chart graphs median salaries for whatever conference the coach is in as well as median salaries overall. Those complexities led to the heavy coding.
(Note: During development, I considered shifting gears and handling all these calculations on the server so I could output a JSON file that had all the data for the Google chart preset, leaving little or no calculations for the browser to do client-side and greatly simplifying the JavaScript. I’m still leaning toward this route for future data releases, but I also think a little client-side defensive coding is beneficial as well. In the end, I did not see any significant performance hit by making the browser calculate the Google chart data.)
To get started, I first used the Google Chart wizard to create a mock up of one of the Google charts. Once I had that, I copied the code generated by the wizard and started picking apart the various parameters to see what they were doing and how they were set.
Once I did that, the JavaScript code was just a simple matter of dynamically generating an<img> tag like this:
<img src=”http://chart.apis.google.com/chart?cht=lxy&chxt=y,x,x
&chs=475×200&chco=b40000,00529B,3B7C25&chg=-1,25,1,1
&chls=2&chds=0,1300000
&chd=t:-1|755370,571500,674000,776500,743500,889095|
-1|600950,561405,630702,700000,752000,822188|
-1|827504,920000,935000,950000,1111502,1272500
&chm=o,730000,0,0,7|o,730000,0,1,7|o,730000,0,3,7|o,730000,0,4,7|
o,730000,0,5,7|s,00529B,1,0,7|s,00529B,1,1,7|s,00529B,1,3,7|
s,00529B,1,4,7|s,00529B,1,5,7|d,3B7C25,2,0,9|d,3B7C25,2,1,9|
d,3B7C25,2,3,9|d,3B7C25,2,4,9|d,3B7C25,2,5,9
&chxl=0:|$0|$1,300,000|1:|||||||2:|2006|2007|2008|2009|2010|2011″ />
To generate a chart that looks like this:
Note that seven of the 11 lines in the chart definition are for the chd and chm parameters. These are the parameters that map the data
and the data point markers. You’ll also see if you look at the JavaScript code that assembling these two parameters took the most work. Most of the other parameters just took hard-coded values. A few, such as chxl, required a small amount of code to produce. (For this parameter, you can see that I just looped through an array of salaries and built the chxl parameter during that iteration.)
The only semi-challenging part about this parameter was creating dollar figures to label the y-axis that included $-signs and comma separators. Elsewhere in the code, I looped through the three arrays of coach salaries (for the coach, the conference and all coaches combined) to determine the upper limit of the salary range and assigned that value to the variable maxsalrng. I used the salbit variable to keep track of the remainder of the salary that remained to be formatted as the code executed. Then I formatted the upper range like this:
// Begin building chxl parameter
var chxl = ‘&chxl=0:|$0|$’;
if (maxsalrng > 999999) { chxl += Math.floor(maxsalrng / 1000000).toString() + ‘,’ };
if (maxsalrng > 999) {
salbit = Math.floor((maxsalrng – (Math.floor(maxsalrng / 1000000) * 1000000)) / 1000);
if (salbit < 100) { chxl += ’0′ };
if (salbit < 10) { chxl += ’0′ };
chxl += salbit.toString() + ‘,’;
};
salbit = maxsalrng – (Math.floor(maxsalrng / 1000) * 1000);
if (salbit < 100) { chxl += ’0′ };
if (salbit < 10) { chxl += ’0′ };
chxl += salbit.toString() + ‘|’;
You can see that adding a Google chart to a jQuery data table is a simple, straightforward process that requires very little coding, depending on how much of that chart must be dynamically generated client-side. It’s a convenient way to visualize your data and provide a small, clean graphic that can break up a sea of numbers.
Have fun, good luck and Happy Coding!