Note: I no longer work for Esria. Some links here may be broken because I no longer maintain the community site there. Being an open source project, though, I still have the original source code, and I’ve made a copy available for download from my own blog for those interested.
Over the last week, I’ve been working on a new Flex component, a heatmap! For those unfamiliar, a heatmap is a form of data visualization that uses color on a two-dimensional plane to compare values. Most recently, in the Flex community, heatmaps have been made famous by Universal Mind’s Spatial Key application. After seeing that go live, I knew people would be interested in an open source heatmap component for Flex, so I put one together and dropped it on Esria’s open source and community site (broken link removed).
Overall, I found the process of building this component very straightforward. There are many similarities to my treemap component, but the heatmap is a bit simpler in many regards. One thing I particularly enjoyed about building the heatmap was that it required some pretty heavy optimization. Since it could potentially display massive data sets, manipulating the data provider and extracting the required numbers needs to be fast. I spent a lot of time diving into Flex Builder’s profiler. By the way, Jun Heider’s profiler session at 360Flex has some great info that helped me understand the profiler’s numbers better. I highly recommend checking it out.
In particular, I made a few good optimizations in some functions that could potentially run hundreds of thousands to even millions of times when preparing the data (basically, sorting a huge list of items). First, I made sure to access member variables directly. Usually, I’ll just use the public getter if it’s available, but it actually became a bottleneck when
Array.sort() needed make such a huge number of function calls. Next, since a sort function potentially has to access the same value over and over again, I set up Dictionary-based caches to retrieve an item’s position and weight without having to recalculate these values every time. Personally, I’ve always been a little wary of the Dictionary type, but lookups proved to be very fast. Finally, though it didn’t necessarily have the same impact as the other optimizations, I drew the heatmap using a Bitmap rather than a Graphics object.
In addition to raw code execution speed, I included a couple other features to aid in performance. First, a
sampleSize property lets you use every nth item in the data provider instead of every item. This won’t provide a complete picture of the data, obviously, but it will certain speed up the analysis by using a subset. Additionally, you can specify a
weightField or a
weightFunction. Normally, every item has a weight value of
1 used to determine the color of a region. Differing weight values can allow for more complex data, certainly, but it can also be used to combine multiple points together to form a smaller data set. For example, if you are using a region size of 30 pixels, you can combine all the items in the same region together since the heatmap won’t need more per-pixel position data. If your raw data has an item for every pixel in that 30×30 region, you’ll reduce the number of items in that region from 900 to just 1, but still have the same overall weight for that region. That can be a huge performance increase when you consider that this sort of reduction might be happening in every region on the heatmap. Moreover, by doing this on the backend, you’ll send fewer bytes to the client. Reduced bandwidth usage is always helpful.
The source code for the Flex HeatMap component is available under an MIT license. Be sure to check out the HeatMap API documentation (broken link removed) and look at the examples to get started.