Tuesday, January 13, 2015

So you want a dashboard?

I recently completed a project for Blue Cross Blue Shield of North Carolina in which we designed and developed a member engagement dashboard, called BlueConnect. Dashboards these days have quite a few features such as draggable tiles, responsive media queries for tablet and mobile devices, animated charts and graphics, third party API services, and maybe even social media integration. I have been swamped with work supporting a project such as this, but I wanted to take some time to jot down some notes and share some insights.

I won't get into the details on everything, but I will just share a few high level concepts. First, some general advice on code structure/team organization.

  • Make sure to leverage a version control system and agree on it first as a team. I highly recommend Vincent Driessen's git flow documented here.
  • Use a build/automation system like Grunt or Gulp. It will save you time at every step of the way and make your code optimized.
  • Choose a client side framework that is robust, and ideally supports testing. We went with Angular because of the widespread community support. Some Angular JS libraries we found useful:
  • For structuring your CSS, I highly recommend splitting your media queries into separate files so that they can be conditionally loaded, and modified for IE. We chose to organize these by breakpoint, and this helped tremendously with code organization.
Now, for the dashboard itself. 

  • First, decide on base tile sizes. Handling a multitude of asynchronous requests in a tile dashboard can be a nightmare if you don't have proper templating and a sound structural approach. For this reason, we first developed base templates upon which our actual content would be loaded, and that could be used for early DOM rendering and tile placement. This can easily be done using Angular's ng-repeat and ng-include directives. These base templates were constrained to "single-wide" and "double-wide" tile for our use case, but these could easily be expanded to as many variations as you need. I recommend choosing sizes that flow easily across different screens for best results, and if you want to meet smaller mobile devices like the iPhone 4, choose a tile size under 320px. Another nice thing about Angular's two way binding/ng-repeat, is that it will automatically re-render tiles quickly if you programmatically change the list (say from outside events, or a change in viewport size).
  • Choose a bin-packing library. These are useful for arranging items within a space in the most efficient way. There are a few of these out there, but the best one I've seen by far is Packery JS. These make your dashboard elements fit nicely, and provide support for things like draggability. There is some great examples of this with Angular here and here and here.
  • After the base content has loaded and you have initialized Packery, you'll want to render your content within your base template (possibly using ng-include or other Angular mechanisms). Ng-include supports variable templates, so we simply passed the name of our content templates in our tile array object. I recommend showing the user a loading spinner for any asynchronous loaded content (such as social media or third party feeds) in your base template. You can do this easily using Angular-Spinner and libraries such as imagesLoaded for any longer loading graphics. 
Lastly, consider animations for your app. These may require some special handling, but for simple animations, you can make use of Animate.css. We chose to add a delayed "fade In" effect for the tiles, which nicely presented them to the user as their content is loaded. Another useful library for animating graphs is Highcharts.js. This library certainly gives your application a dashboard "feel" as your user is presented with animated data charts.

There you have it...a dashboard is waiting ahead! If you have any trouble or questions, please feel free to contact me.