Presenting at DC’s World Usability Day Event

November 13th, 2008

Today is World Usability Day, and this year’s theme is transportation. I’ll be presenting the work I’ve been doing at the CATT Lab at DC’s local Usability Day event. The title of my poster is Real-time and Historic Incident Visualization Using Timelines, and it describes an application that allows users to understand everything that has been done to manage an accident scene by presenting all of the events along a timeline.

There are seven other people from the CATT Lab presenting their work as well. The majority of that work is in the realm of information visualization. If that’s your thing, and you’re in DC today, stop by the American Institute of Architects and see what we’ve been up to.

Happy World Usability Day, everyone.

Adding hints to Flex 3 MXML tags

November 5th, 2008

ColdFusion tags can be annotated with the hint attribute, effectively creating a surrogate for single line comments. This is something I’ve wanted to be able to do in MXML for a while, and I’m glad to see the Gumbo specs include this feature in the form of private attributes.  If you can’t wait for Flex 4, you can apply this monkey patch to add hints in your Flex 3 MXML.

For those new to monkey patching, the technique allows you to rewrite classes from the framework or from swcs by defining your own class with the same fully-qualified name. Through the magic of inheritance, any changes to a class will cascade down to its subclasses. To create hints we just need to add a do-nothing public setter method called “hint” somewhere where it will be inherited by the entire SDK.  If we could change the source for Object we’d be done, but we can’t so we’re going to have to patch a couple of files.  Practically every file in the SDK has the line

include "../core/Version.as";

so that’s our best starting point. Create a directory structure for the mx.core package in your main source directory and copy the SDK’s Version.as into that directory. Add the line

public function set hint(value:String):void {}

to the copy. This isn’t going to change anything immediately because the compiled classes are still using the old Version.as, but this step makes the rest of the patch completely painless. To get the change to go through we have to grab a copy of each of the classes we want to add hints to and place them along side the patched Version.as.

Most MXML tags describe components, so grab FlexSprite.as from the SDK source and place it in the same directory as the new Version.as. Without editing FlexSprite.as you can now say

<mx:Panel hint="The compiler is cool with this." />

Sadly, FlexSprite isn’t the base class for everything that can be declared in MXML, so there are a couple of other classes you’ll need to grab if you want hints for them too. A few good candidates for this patch are mx.styles.CSSSytleDeclaration, mx.effects.Effect, and the entire mx.states package. I’m not going to try and patch everything, so if you use this technique and the compiler complains about the absence of the hint property, just grab the source for whatever class needs patching and put it in the patched mx package.

Parallel Coordinates Plot in Flex

October 13th, 2008

I spent the past few weekends writing a parallel coordinates plot.   For the uninitiated, parallel coordinates plots are used to show the relationships between items in a multidimensional dataset.  Three dimensional data points can be difficult enough to visualize on a two dimensional screen, and when you throw even more dimensions into the problem, things just get nasty.  Parallel coordinate plots mitigate this problem by rendering each of the n axes parallel to each other and each data point as a series of line segments corresponding to where the point would appear in n-dimensional space.  So the point (3, 10, 7, 6) would be rendered like this:

Here’s a little example application using the period table of elements as a data source.  If you’re interested in the details of the implementation you can check out the source.

When I started the project I was concerned that using the charting classes as a base would bulk up the code and ultimately hinder performance, so while the MXML that defines the plot is reminiscent of the charting components, the base is actually UIComponent.  I’ve left plenty of room for extension in the classes that make up the plot.  It’s licensed under MIT, so if you want a different renderer for each axis, you got it.  If you want to draw loops instead of straight lines between the axes, go for it.  I’m going to add the project to my repository, so if you’re interested in any updates that I make to the code, you can check there.

If you need variety, two of the other members of the Fervor team have started open source projects for their own flavors of PCP.  (Swapping the acronym “PCP” in for “parallel coordinates plot” makes sentences more interesting, don’t you think?)  PCPlot belongs to Dasha and contains the code more or less as it appeared in Fervor.  FlexPC is a project Krist started with a couple of developers he met through a flexcoders post about PCP, but that project is still in the planning stage.

Memory leak caused by setTimeout

September 5th, 2008

I have a Cairngorm-based application that polls a server for data every few seconds.  To do this I have a command that initiates the server request, and in the result handler I set a timeout.  When that timeout is up, I dispatch the event that is responsible for kicking off the command in the first place.  It looks something like this:

public class PollServerCommand
{
   public function execute(event:CairngormEvent):void
   {
      // Create and call delegate 
   }
 
   public function result(data:Object):void
   {
      // Process data...
      setTimeout(2000,poll);
   }
 
   private function poll():void
   {
      var pollEvent:PollEvent = new PollEvent();
      pollEvent.dispatch();
   }
}

This results in lots of commands being created, but in theory the garbage collector should be cleaning up the old ones every so often.  Well, that’s not really the case.  While profiling my app, I noticed that every polling command I created stayed in memory.  The solution?  Swapping out the calls to setTimeout for instances of the Timer class like so…

public function result(data:Object):void
{
   var pollTimer:Timer = new Timer(2000,1);
   pollTimer.addEventListener(TimerEvent.TIMER,poll);
   pollTimer.start();
}
 
private function poll(event:TimerEvent):void
{
   var pollEvent:PollEvent = new PollEvent();
   pollEvent.dispatch();
}

I’ve always known that the Timer class was preferred over setTimeout, but now I know why. Can anyone from the Flash Player Team shed some light on why setTimeout is keeping these objects alive?

HeatMap added to Google Code Repository

August 26th, 2008

I’ve started a Google Code repository for all of my little experiments.  At the moment it just has the HeatMap component, but — baring any unforeseen circumstances — it will soon flourish.  You can check it out here.

HeatMapping the Spread of WalMart

August 11th, 2008

I recently came across a post on FlowingData with a visualization showing the growth of the WalMart chain over the years.  It’s very well done, but all those icons really clutter up the map.  The fact that they’re semi-transparent makes it possible to distinguish the dense areas from the sparse ones, but it’s difficult to tell those intermediate shades of green apart from one another.  It sure would be nice if the color varied across the map instead… heat maps to the rescue!

I’ve put together my own animation of the WalMart dataset using ModestMaps and the HeatMap component.  The visualization is most impressive when you’ve zoomed in far enough to see all of the major roadways converging on the large cities.  From there you can watch as WalMart takes over the urban areas, turning them red hot while leaving the less populated areas (relatively) cold and blue.

Unfortunately my dataset is somewhat incomplete.  The version I grabbed from Thomas Holmes has addresses for each store, but the geocoding service I used failed to convert about 100 of those addresses to latitude and longitude values.  If anyone can point me towards the complete dataset, I would love to add those missing stores to the visualization.

Before I close I want to give a nod to Universal Mind.  Last week they released SpatialKey, a heavy-duty temporal-spatial visualization tool that really shows off the strengths of heat mapping.  They’ve taken a crack at the WalMart data set as well, and it’s impressive to say the least.  Congratulations on your launch, UM.

Icons by famfamfam.com

How to make heat maps in Flex

July 6th, 2008

Last semester I worked with Darya Filippova, Joonghoon Lee, Andreea Olea, and Krist Wongsuphasawat on a project for Ben Shneiderman’s Information Visualization course.  We took a subset of the accident data collected by the CATT Lab and built a tool to help figure out why certain stretches of road have a higher number of accidents than others.  We developed a number of visualizations to achieve this goal.  My major contribution was the heat map.

I’ve only seen a few Flex apps that use heat maps to show clusters of data, and I’ve never come across any source code.  Corunet has a blog post detailing their server-side heat map algorithm, and I ported it to Actionscript.  I’ve continued to play around with the code since the semester ended, making it more efficient, extensible, etc., and I think it’s about time it saw the light of day.

The application below traces your mouse movements, storing the x and y positions in an ArrayCollection which is fed to the heat map.  The size of the collection is capped at 1000 points because I didn’t want to blow up anyone’s browser, but any machine that can actually run a web browser shouldn’t run into any problems with that many points.

You can view the source here.

The algorithm isn’t all that complex, and the functions built into the BitmapData class take care of a lot of the dirty work.  Basically, a circle with a gradient fill is drawn for each point in the collection.  The gradient ranges from black on the edge to blue in the center.  Bluer regions represent areas that have had more “influence” than others.  The exact shade of blue used in the center is dependent upon the maximum number of coincident points.  As this number increases, the relative influence each point has decreases, preventing the entire heat map from being rendered as a supersaturated mass.  The BitmapData’s threshold method is used to convert the black-blue image to a fully colored heat map.

The HeatMap class is driven by an ArrayCollection of Objects, and the Objects are mapped to the screen coordinates based on their x and y values if they exist. Because not everything has an x and y value, the HeatMap has a transformationFunction property which is used to project objects to screen coordinates. Also, a weightFunction property is available which allows weights to be assigned on a per-object basis. The usage of these to functions is similar to that of the dataFunction property in the charting classes.

That’s all there is to it.  The source is pretty well documented, so you can get the nitty gritty details there.

Update (August 25, 2008)

I’ve added the HeatMap component to my Google Code repository, so the source shown here isn’t the most up-to-date.  Rather than continually update this post when I make a change, I’ll let the most current revision speak for itself.

The HeatMap, and all of my future opensource work will be licensed under the MIT license.

Hello, Flex Community

June 27th, 2008

I’ve been doing Flex development for a while now, and I think it’s about time I started participating in the community.  I’ll be posting all kinds of Flex-related work, so something interesting is bound to pop up eventually.

Who am I?  I’m a computer science graduate student at the University of Maryland, College Park, and my research focuses on human-computer interaction and information visualization. I’m currently working at the CATT Lab, writing software that allows users to manage and explore real-time and archived transportation data.

That’s me in a nutshell.  Fun experiments to follow.  See you next time.