High Performance JS heatmaps
You might have encountered heatmaps for data visualization before. There is a fabulous library, heatmap.js, which brings that capability to draw them to javascript. There is only one problem, it is not exactly fast. Sometimes that doesn't matter. But if you have hundreds of thousands of data points to plot, or need realtime performance, it gets tricky. To solve that I've written a little engine using WebGL for drawing heatmaps.
Update:
- Andrei Gheorghe is using the heatmap for a cool predator webcam effect
- Patrick Martin integrated the heatmap for Leap motion finger tracking awesome!
Contents
Screenshot

Live Version
The mouse movement is used to draw the map in realtime. Click into the canvas to erase it.
Performance
You can draw around 500'000 individual data points per second in realtime. Around 10'000 per frame are no problem. The way it works is that points to draw are recorded into a position buffer (10k points) and when you call heatmap.update() (or when the buffer is full) it draws these points with WebGL by additively blending them into an off-screen floating point texture.
Quality
The heat is updated/recorded as a height in an off-screen floating point texture. Conversion to a color display is done as a second step. Due to this mechanism the quality is fairly good (compared to methods using byte precisions).
Usage
Instantiate a new heatmap, errors can be one of:
- "Webgl is not supported"
- "No floating point texture support"
- "Floating point render target not supported"
- "Shader Compile Error: ..."
- "Shader Link Error: ..."
try{ var heatmap = createWebGLHeatmap({canvas: yourCanvas}); } catch(error){ // handle the error }
Add a data point.
- x and y relative to the canvas in pixels
- size in pixels (radius)
- intensity between 0 and 1
heatmap.addPoint(x, y, size, intensity);
Draw queued data points:
heatmap.update()
Display the heatmap
heatmap.display()
Multiply all values in the heatmap by a number (useful for decay)
heatmap.multiply(0.995)
Clamp all values in the heatmap to between two values:
heatmap.clamp(0.0, 1.0)
Blur all values a little:
heatmap.blur()
Sourcecode
You can find the code for the library and an example page on github.
Caveats
Due to this being WebGL it will not run for everybody (please consult the statistics page for up to date numbers).
It also requires floating point textures and floating point texture render targets, which not everybody has.
There might also be problems with shaders on certain platforms.



