One of the things which has bothered me ever since I took the dive into visualisation is the problem of interactivity. The aim of interacting with a visualisation is to drill down or explore areas of the visualisation which are (or seem) interesting. Put another way, we are essentially filtering the data from a visual standpoint. In most cases, mouse interactions may be sufficient. But what if I wanted to be able to filter the data programmatically and have the result reflected in the visualisation?
One way is to simply re-run the code which generates the visualisation each time we use a different filter. This is the simplest, and, in many cases, enough. In this case, the modification to the code is made in an offline fashion. What if we wanted to do the same, but while the program is running? This describes my attempt at one such implementation. Albeit still somewhat primitive, we’ll see where it ends up. For the purposes of demonstration, I used the Parallel Coordinates visualisation, which is available on GitHub. I’ll continue using Processing through Ruby-Processing for this description.
Because I intended to keep the Processing side of things a lightweight as possible, I did not go with trying to embed the PApplet in a larger Swing view. Instead, in the spirit of the Unix philosophy, I chose the metaphor of piping the input from somewhere else (it does not matter where) to the visualisation. This immediately suggested using some form of a queue: I chose RabbitMQ for this.
I also decided to move away from the Gems-in-a-jar approach that I’d been using while working with Ruby-Processing, and set up JRuby proper on my machine. That change mostly necessitated explicitly setting the GEM_HOME and GEM_PATH environment variables in the code.
With RabbitMQ, I set up a direct exchange with a non-durable queue, using the excellent ruby-amqp library. I had initially tried using the rabbitmq-jruby-client gem to set up a subscription on the visualisation side, but ran into object marshalling issues related to conflicting serialisation versions. Setting up ruby-amqp on both sides solved that issue.
The sending side (where the filtering logic comes from) needed to be able to take a Proc object as an input and convert it into a stringified form. This would go through the queue and be evaluated on the visualisation side, to determine the subset of data to be highlighted. For this, I used the excellent sourcify gem. Note that I did not install ParseTree with it: ParseTree installation requires RubyGems 1.8.0 or higher; updating my RubyGems (1.7.2) to that version messes up my gem paths for some inexplicable reason.
At the end of it, I pulled out the code for pushing stringified Proc objects onto the queue into a separate gem called lambda-queuer. The name’s a bit inappropriate, I guess, since it’s Proc objects and not strictly lambdas, but oh well…
Here’s a screenshot. The highlighted samples were indicated by the Proc object sent over the queue from the IRB session on the right.
Ultimately, what you get is a visualisation which can be driven both through direct interaction (via mouse), as well as using a scripting language (it could even evolve into a Domain Specific Language if you were so inclined).