Hacking Chart.js: A Crash Course in Down-and-Dirty Front End (Part 2)

Reading Time: 3 minutes

What’s going on? I wanted to make clean, elegant, simple charts to represent data about armed conflicts in Africa. I used the Chart.js javascript library to obtain some pretty graphs, but I added functionality to the graphs and then wrote about it here so you can do it, too. This is the second in a series of three posts, and it’s about creating a sensible, readable scale along the x axis of a line chart.

For more info on Chart.js, have a look at the first post in this three-post series. 

For looking at the data in the ACLED app, I wanted to be able to view violent events by the day, ranging back over an explicit period. The result would be a line chart:

Screen Shot 2014-09-30 at 3.02.37 PM

The problem was, when I tried to make the line chart span too large of a time period, the lines would show up…but the date labels along the bottom would become too numerous, and so would get squished together on top of each other to form a thick, illegible, greyish-white bar. So in order to have any idea what sorts of time periods we were talking about, I needed the ability to show chart labels less frequent than every single day. So, maybe something like this:

Screen Shot 2014-09-30 at 3.06.42 PM

This only shows the label for the first of each month. Like some of the other Chart.js hacks, this one involved a little string manipulation. In this case, the labels get passed into the chart javascript as an array. So the following code creates an array full of empty string labels except for the case of the first of the month, in which case it prints a formatted label:

Screen Shot 2014-09-24 at 9.12.33 PM

That gets passed into the javascript right here (along with the raw designation, without which the empty strings were confusing the computer):

Screen Shot 2014-09-24 at 9.13.03 PM


Easy. Quick. Also, clunky and kind of gross.

Later, I switched to this better implementation, which reduces the creation of @each_month to a few lines inside the controller method for yielding this page:

Screen Shot 2014-09-30 at 3.45.11 PM

This uses a few new turns of syntax (it’ll catch on) to do what we want. Translated into English, it sayeth:

.map: Create an array called @each_month. For each element in the array called @days,

Date.parse(day.to_s): parse that element to a string and,

ternary operator (the ? and : line): if it is at the beginning of the month, then inject into @each_month a string with that date (specifically just the month and year), otherwise inject into @each_month an empty string. 

I love learning new syntax like this (and also new ways to avoid loops, which this ternary operator kindly provides).

One comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.