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.