Monday, May 28, 2012

jQuery Mobile Charts

The Plot Chart
Numeric data quickly becomes difficult for us humans to understand. Once the number of rows or columns in a table passes two or three, the meaning quickly becomes harder to grasp. The easiest way to give meaning to numeric data is to display it as a chart. Unfortunately jQuery Mobile doesn't have any built-in charting capabilities and to the best of my knowledge there isn't a jQuery Mobile charting plug-in available. But lucky for us, jQuery Mobile is built on top of jQuery and there are several charting plug-ins available for it. 

My requirements for a charting library are pretty simple:
  1. Free and open source
  2. Compatible across the three mobile platforms I support: iOS, Android, Windows Phone 7
One of my favorite JavaScript charting libraries is "Raphael". I have used it on desktop projects previously but it was quickly out of the running. Raphael uses SVG, which isn't supported well across mobile platforms.

Next I googled, "jQuery charts". Nearly 3 million websites were returned, so I knew I was going to find something. Close to the top of the list was the following link: 1st Web Designer. The post there listed six jQuery charting plug-ins: 
  1. GraphUp
  2. jQuery Visualize
  3. Highcharts
  4. Flot
  5. jQuery Sparklines
  6. jqPlot
After doing a bit of analysis, I decided to run with jqPlot. This is not to say that the other packages aren't good, it is just that I was able to understand jqPlot's examples quicker than the others and it met all of my requirements. For your own needs, please try out the libraries, they may meet your needs better than they had mine.

jqPlot

There are two methods for generating graphics in HTML5, canvas and SVG. 
Canvas is like a bitmap and JavaScript can render graphics to it. SVG's use of vector graphics makes it seem ideal for a charting library, the problem is that SVG is not as well supported as canvas and it is not available on 2.x Android or any WP7. jqPlot uses HTML5 canvas. 

The jqPlot library is huge. It has an immense number of features. But it is not a bloated pig, it is smartly architected. Rather than force you to download a lot of charts and features you won't use, it, itself is composed of a large number of plug-ins, I counted 26 of them. This means you only download the plug-ins you want to use.

I could spend weeks explaining all of the features of jqPlot, unfortunately I don't have the time for that. Instead I am going to give you a quick walk through my demo app and explain anything interesting along the way. 

JQMCharts on iPhone, Android, and WP7
index.html

Everything starts with the markup page, index.html. It contains four jQuery Mobile pages:
  1. page1 - the home page for the app
  2. pageBarChart - the bar chart page
  3. pagePieChart - the pie chart page
  4. pagePlotChart - the plot chart page
Page 1 is strictly a markup page. There isn't any JavaScript for the page since the only thing it does is link to the other pages. Which is something jQuery Mobile handles innately without the need of JavaScript.


pageBarChart

pageBarChart is where things begin to get interesting. It consist of an empty <div> which will hold the chart once it is rendered, a button to refresh the chart, and three sliders to change the values of the chart. The initial version of this page didn't have a refresh button. On the iPhone the rendering of the chart was fast enough that it could be done interactively. Unfortunately the same wasn't true under Android and WP7. Android was close, but WP7 was downright sluggish. So I removed the code hooking the input change event, added a button, and hooked the click event for the button. While not as nice as watching the chart change dynamically, it isn't too bad. This was yet another reminder of why it is important to test on all supported devices.

The JavaScript bound to the page is in the manageBarChart function. It handles to events, "pageshow" and "pagehide". It uses these events to hook and unhook events respectively. It also holds to private methods, updateChart and showChart. UpdateChart grabs the values of each of the sliders, then calls showChart. ShowChart renders the chart. One interesting thing with jqPlot is that it doesn't automatically clear the canvas when you call it successively. Instead if you want to clear the canvas, you call its replot method with clear and resetAxes equal to true.  (resetAxes allows the charting to scale itself appropriately)

pagePieChart

pagePieChart is very similar to pageBarChart. The call to jqPlot is different and that it doesn't call replot. Since the pie chart isn't using any labels or axis, successive redraws overwrite each other without leaving garbage behind, so the replot call isn't needed.  



pagePlotChart

The final page is pagePlotChart. It follows the pattern established in the other pages with the notable exception being the updateChart method. I decided to modify the method I use to grab the data from the sliders. 

Here I don't limit the number of sliders. Instead I interrogate all of the sliders on the page successively for their value, convert it to an integer, then push it and the index into an array. This allows us to add or remove sliders without the need to change the rendering code. The "$.mobile.activePage" limits the jQuery selector to the context of the current page. I should probably make the selector of the find method, "input", more narrow so that it only finds the sliders, but it works for this example since the only input tags on the page are sliders.

One other thing which is different is the, $.mobile.silentScroll(), call. Since there are six sliders on the page and scrolling down to the bottom one, normally slides the chart off the top of the page, I added this call in order to bring the chart back on the page when the refresh button is hit.

Summary

That is all for this post. This post is the first where the code is hosted on GitHub. So be sure to check out all of the repos I have there. Each general ties into a blog post. Over the next few days I will be moving all of my tutorial code to it. Using GitHub, which ties into my IDE, WebStorm which makes easy to add fixes and updates to code.

My next posts will be on how to convert my JQMCalculator tutorial to a PhoneGap (Cordova) app for iOS and how to create a twitter app in jQuery Mobile.