Animating Web Socket Data

Over the years I have learned many things about why companies build applications.  There is the standard e-commerce site for example, which allows a company to sell its goods to a broad audience they may have never originally been able to reach.  Behind the firewall of an e-commerce site then is typically a dashboard application, which allows managers and marketers to watch purchasing trends and learn how to execute better in the future.

Historically, however, this has been a job of refreshing the data occasionally to see the latest.  This lag can introduce missed opportunities for the business – especially when the data being monitored relates to a single event (e.g. special sales).  With Web Sockets, this data can now become real-time information, and allow for more immediate decision making.

The subsequent question then becomes how to best visualize that data to provide the necessary information.  This is a whole area of research, but one thing I have found that always puts a smile on executives’ faces is animation.  Animating data is a fairly basic programming task once you know how to do it, but if you are new to this world of real-time data, you might dismiss it as an extra, when it is really a low-hanging fruit to a dazzling win.

Web Socket Connection

The first step to visualizing real-time data is understanding how to access the real-time data in the first place.  Luckily, web standards are here to save the day with Web Sockets.  This specification has been in a working state for years, but has recently moved on to the “request for comments” (RFC) stage.  This means it is unlikely to change significantly moving forward, and that you can start leveraging it in your projects.

And to be sure, the only parts that have changed at all in the past year have been around the server implementation and handshake details, that you the web developer don’t need to think about.  The client API you implement in JavaScript from the browser has been baked for some time.

From JavaScript, you will find a new class to use named WebSocket.  This is a first-class data type along the lines of String, Number, Math, etc.  When you instantiate the class via the “new” keyword, you must pass the IP and port to which the socket will connect.  Per the specification, the URI prefix of “ws” should be used (as opposed to “http”).  At the end of the day however, Web Sockets are an upgrade to the HTTP protocol that happens during the handshake.

Note that as soon as you instantiate the class, the process of connecting begin.  If you are interested in knowing when you are officially connected, the WebSocket class fires an “onopen” event, which you can map to a function.

There is also the corresponding “onclose” event for when the connection is closed.  Keep in mind here that unlike HTTP, for which the connection is terminated once all the data has been delivered, that Web Sockets are an open connection.  This connection can be closed on the client by calling the WebSocket.close() method, but it can also be closed by the server for any number of reasons (e.g. security concerns).

Web Socket Messages

Web Sockets have the ability to handle a variety of types of data in anticipation that connections may not always come from the browser.  For example, the specification allows for binary messages.  JavaScript is rapidly evolving however, and there is some hope for binary support in the language in the not too distant future.  For now you will be limited to text messages.

Regardless of the data type, now or in the future, sending a message is as easy as calling WebSocket.send() and passing along the data you want to go across the wire to the server.  As an example, this could be valuable for telling the server that you want to add additional data to be monitored, or that your application is in a state to really only be interested in a subset of a larger data feed.

I’ve been working with a fellow Adobe Developer Evangelist, Andrew Trice, on this topic and he has a great example of how this might work, when it might be important, and how to implement the details.

Getting messages is a matter of handling the incoming event “onmessage”, which gets passed an event object with many interesting properties.  While those properties still seem to vary slightly per implementation, the “data” property on that object is what we will be interested in accessing for the purposes of this example.

Some Charting Options

The area of canvas-based charting has seen explosive growth in the past year alone.  There are a number of great options that can cater to your specific needs.  One word of caution here is to find the charting abilities that best suit your needs, and that this may not be the biggest, baddest charting framework on the block.  Especially in the context of delivery to tablets, sometimes the closer you can get to the basic the better off you will be – especially in terms of performance.

A few years ago, when I start looking into charting options for my projects, I found that PlotKit worked wonderfully.  It has a great look and feel right out of the box, thus providing a great user experience with very little effort.  PlotKit however hasn’t been updated for a long time.

Blue bar chart using PlotKit

Another charting library I have used in the past, and that I will use for this example, is RGraph.  The RGraph API reminds me a lot of NET syntax, so it may be more approachable to programmers, but I’ve also found it harder to get a polished look and feel out of the available customization properties.

Red bar chart rendered with RGraph

And if you are jQuery-inclined, you might look at jqPlot.  This library strikes a nice balance between features and customization, and in the classic jQuery approach, it gets you started with minimal effort and flexes its customization features by exposing tons of features after the fact.  Again, however, when you consider performance on mobile devices, any library that abstracts another should be tested thoroughly.

Teal bar chart rendered with jqPlot

Animating Charts

In order to animate charts, you’re going to want to first figure out how much data you can reasonably display on the screen.  This could be adjusted by the user via the user interface down the road, but you will want to find a happy medium as a starting point.  For the purposes of this example, I will assume that we want to show 100 data points at any given time.

Keep in mind that when animating data, each element also represents how much history the user can view.  Sometimes more data isn’t necessarily better data.  The human mind needs to be able to digest what it is seeing.  That may be more or less than 100 data points for your use-case.

From a programming perspective, this means setting up an Array of 100 elements in a scope that can be accessed by other parts of your code.  When a new message arrives, get the data point(s) you are interested in visualizing, and then Array.splice( 0, 1 ) the first element off the array, and Array.push( event.data ) onto the end.  Then you want to redraw the data.

This is an interesting aspect of working with Canvas.  Once something has been rendered to the canvas, it becomes part of the overall bitmap data on the screen.  There are no discrete display objects to work with independently.  Even if your chosen library abstracts data points in a manner such that you can work with them directly and have the chart updated, chances are that it is redrawing the vast majority of the canvas space anyways.

Whether you are working with discrete points, or using the array method I show in the above code snippet, the important part is in moving the data down the chain.  You can’t just add onto the end.  You want to keep the same number of data points and change the values they reflect directly.  Over time, this will create the illusion of the data sliding in from the right to the left – also known as animation.  To move the chart the other way, put the new data in at the first element (zero) and splice off the end of the array.

Conclusion

This really just scratches the surface of the types of data visualizations that are possible with this technique.  Bar charts, lines, high-low points, and even pie charts render some visually impressive results with relative ease.  And again, keep in mind that the experience of the user matters.  This few extra lines of code, makes a big impact on the user, and in my experience, most marketers will love you for the effort over forcing them to refresh the data, or wait for updates of HTTP polling.

0 Comments

Trackbacks/Pingbacks

  1. Andrew Trice » Blog Archive » Toying with Realtime Data & Web Sockets - [...] Hoyt track down an issue with a websockets example that he was putting together. Kevin has a great writeup ...

Submit a Comment

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>