Pixel based heatmap with html5 canvas.

Related tags

Maps heatcanvas
Overview

heatcanvas

Note that this project is no longer active maintained. Please let me know(file an issue or send me email) if you are interested in taking over it.

CDNJS

This is a simple heatmap api based on HTML5 canvas. A heat map is a graphical representation of data where the values taken by a variable in a two-dimensional table are represented as colors, according to Wikipedia.

You can find an interactive demo at http://sunng87.github.com/heatcanvas

Available via bower

bower install heatcanvas

Webpack Build

npm run webpack

This will generate a build in the /dist folder. This includes the main heatcanvas.js, the heatcanvas-worker.js Web Worker script, and specific versions for 51 Maps, Baidu Maps, Google Maps, Leaflet Maps, and OpenLayers.

To use, import into an HTML document using a script tag. The imports will be available at HeatCanvas, HeatCanvas51Layer, HeatCanvasBaiduLayer, HeatCanvasOverlayView, HeatCanvasLeaflet, and HeatCanvasOpenLayers respectively.

Usage

1. Create the HeatCanvas object

You can pass the canvas element object or its id to the constructor:

var heatmap = new HeatCanvas("canvasId");

2. Add some data

Add value to point (x,y) in canvas coordinate system.

heatmap.push(x, y, value);

3. Render the map

Call the render function on heatmap to draw it.

heatmap.render();

We use a simple formula to determine value of a pixel, by its distance to a point that holds data:

v = f(d)

The first two optional parameters of render define the formula.

  • step

  • degree

    v = Σ(datai - step * ddegree)

A set of constants are predefined for degree:

  • HeatCanvas.LINEAR
  • HeatCanvas.QUAD
  • HeatCanvas.CUBIC

For the third parameter of render, you can define a custom function to define color of pixels. For instance, we can use a mono-hue color scheme by this function:

var colorscheme = function(value){
    return [0.3, 0.75, value, 1];
}
heatmap.render(null, null, colorscheme);

The value for this function is guaranteed in (0,1].

4. Remove everything we just created

Call clear to erase the canvas and remove all data cached in heatmap instance.

heatmap.clear();

GoogleMap extension

HeatCanvas can be used as an OverlayView in GoogleMaps API V3.

Simply use the Map instance to create an HeatCanvasOverlayView

var heatmap = new HeatCanvasOverlayView(map, options);

Additional options available:

  • step, same as described in HeatCanvas.render
  • degree, same as described in HeatCanvas.render
  • colorscheme, same as described in HeatCanvas.render
  • opacity, the opacity of overlay view, [0,1]

Add data to map:

heatmap.pushData(latitude, longitude, value);

The map will be rendered automatically.

OpenLayers extension

Also we have a OpenLayer extension for you to embed heat map in your custom map application and OpenStreetMap.

The usage is still similar to GoogleMaps. First, construct your heat map layer with a name, OpenLayers map instance, layer options and HeatCanvas options:

var heatmap = new OpenLayers.Layer.HeatCanvas("HeatCanvas", map, {},
        {'step':0.3, 'degree':HeatCanvas.QUAD, 'opacity':0.8});

Add data to layer:

heatmap.pushData(latitude, longitude, value);

Add layer to map:

map.addLayer(heatmap);

Other extensions

There are also HeatCanvas extensions for:

  • Baidu Map (demo)
  • Cloudmade Leaflet (demo)

These extensions share similar API mentioned above. You can browse the source code of our demos to get detail.

License

HeatCanvas is released according to MIT License.

Thanks

  • @lbt05 for his patches on GoogleMap extension and BaiduMap implementation
  • @dazuma for his suggestion to speed up canvas rendering.
Comments
  • a set of complicated optimizations

    a set of complicated optimizations

    No silver bullet, but a bunch of techniques.

    • be cache friendly
    • be processor branch predictor friendly
    • less memory allocations
    • don't compute unnecessary
    • use effective functions
    • something else?

    Be cache friendly

    Processors do not like cache misses. Try to organize data in proper way. During rendering we need them to go row by row -- let's fill them such a way: outer cycles go by rows (y), inner cycles -- by columns (x).

    Less memory allocations

    Object-based value allocated memory regularly (if (data[pos]) ... else data[pos] = v;). Computing large heatmap turned out to be not really a computing, but a memory allocation (and garbage collection!). Replace object with once-allocated array.

    Be branch predictor friendly

    Try to use as few conditional operators as you can.

    • check borders once, and use highly optimized function, that doesn't check borders. Leave complicated checks for circles that cross image border.
    • allocate all memory once, fill it with zeroes, get rid of if (data[pos]) data[pos] += v; else data[pos] = v;
    • use array, not an object for values. It's less memory effective for "empty" heatmaps, especially on large screens, but it speeds up well-filled heatmaps dramatically.
    • compute loop ranges as precise, as possible.

    Don't compute unnecessary

    • don't compute if (dx^2 + dy ^2 < radius ^2). Compute correct range for each scanline. ~1/4 inner iterations less.
    • circles are supersymmetric, compute weight once, use it for 8 points! -- 8 times less Math.pow(dist, degree) computations!
    • don't cross borders :)
    • compute main offsets, alter them with ++ or +=; Sorry, less semantic, but more efficient than data[x + y * params.width] :(

    Use effective functions

    Math.min, and Math.max are more semantic, but if (x < min) min = x and ternary operator are much, much more effective. Replace "for in" with "for" in rendering. ~400 ms -> 60-80 ms. Just a price, i pay for serializing / deserializing heatmap data to communicate with worker.

    Something, i forgot?

    All these and previous optimizations allowed me to speed my heatmaps (15K points, with high peaks) up by 10-12 times. Now it takes ~1 second including data transfer to and from worker.

    opened by se-ti 7
  • making heatcanvas work with modern leaflet version

    making heatcanvas work with modern leaflet version

    Hi! I enjoyed using ancient version your plugin with ancient LeafLet version (0.7) for many years. But when i tried to migrate to actual versions of both plugin and Leaflet, it turned out they fail with several errors.

    I spent some time debugging, and made it work.

    Hope, this fixes issue #34, and probably even #27, and #32

    Serge.

    opened by se-ti 4
  • Heatmap.leaflet ignores layer controls

    Heatmap.leaflet ignores layer controls

    In my app I have something like this

    App.markerLayer = new L.MarkerClusterGroup();
    App.heatmapLayer = new L.TileLayer.HeatCanvas({
      map: App.map
    });
    .....
    App.map.addLayer(App.markerLayer);
    App.map.addLayer(App.heatmapLayer);
    var mapLayers = {
      "Markers": App.markerLayer,
      "Heatmap": App.heatmapLayer
    };
    L.control.layers(mapLayers).addTo(App.map);
    

    This adds both the marker layer and heatmap layer to the layer controls which show as radio buttons. When switching to only the Marker layer, the heatmap layer does not disappear (i.e there is no show/hide facility with it)

    Screen Shot 2013-01-09 at 10 22 15

    enhancement 
    opened by tanepiper 4
  • Demo not working anymore (?)

    Demo not working anymore (?)

    Hi all! I've clicked on the demo link in the README but it's not working anymore. Are you aware of that?

    http://sunng87.github.com/heatcanvas

    I was just interested in add an operational demo link from this page:

    https://leafletjs.com/plugins.html

    Thank you so much for your work on this plugin! :)

    opened by valerio-bozzolan 3
  • Why is the rest of the map darkened?

    Why is the rest of the map darkened?

    The HeatMap looks great, but when placed over a base layer it significantly darkens the map such that it's difficult to see what's going on underneath. I'm using the default opacity of 0.6.

    It seems like the Heatmap.Canvas is writing black for all the places that don't have data. Is that accurate? Is there a way to turn that off?

    Thanks.

    opened by FunkMonkey33 3
  • SECURITY_ERR: DOM Exception 18

    SECURITY_ERR: DOM Exception 18

    I was trying to create a small example oh Heatcanvas using Leaflet, however I always get a "SECURITY_ERR: DOM Exception 18" on heatcanvas.js:37 when I try to add the heatmap layer to my map.

    I used the exact same code as the Leaflet HeatCanvas demo. Anyone has any hints on what am I doing wrong?

    I'm using Google Chrome v21. Thanks for any feedback.

    opened by ffleandro 3
  • Speed up canvas rendering using putImageData

    Speed up canvas rendering using putImageData

    Hi,

    I had actually written something similar for one of my projects. Just wanted to pass on a suggestion based on what I had done.

    Currently, you're rendering by calling context.fillRect() for each pixel. This can actually get quite slow. You might consider manipulating an ImageData directly. Call context.createImageData() to get an offscreen ImageData object. Then you can set pixels simply by setting rgba values in the data array. Finally, render the entire image back to the canvas using context.putImageData(). It generally turns out many, many times faster than the thousands of fillRect calls.

    The downside is that you can't use the css-like syntax to set colors; you have to set raw rgba values numerically. But it may be a worthwhile trade-off.

    opened by dazuma 2
  • simple optimizations (unknown speed up for computation, 800 ms -> 400 ms for rendering)

    simple optimizations (unknown speed up for computation, 800 ms -> 400 ms for rendering)

    Trying not to do the job, we don't really need. As soon as heatmap values are scaled to [0;1] segment to get color, we can use data[pos] / step instead of data[pos], and replace var v = data - params.step * Math.pow(dist, degree); with var v = data - Math.pow(dist, degree); in inner cycles;

    Similarly, we can get rid of Math.sqrt in inner cycles, using squared distance, instead of distance and replacing Math.pow(dist, degree); with Math.pow(distSquared, degree / 2);

    Sorry, i didn't perform isolated measurements for these changes.

    Using palette replaces complex color-conversion computations during rendering with fast division, rounding and 1 index access.

    512 values uniformly distributed between 0 and 1 produce, due to rounding, a palette with ~440 different colors. This seems to be good enough by itself, and can be increased, but 200K uniformly distributed values generate a palette with just ~940 colors. So, 512 seems to be a good constant.

    opened by se-ti 1
  • Resizable and fullscreen-able leaflet HeatCanvas

    Resizable and fullscreen-able leaflet HeatCanvas

    Also fixes a couple of bugs (see commit comments). Minor optimization: terminate running worker, if we are sure, it was started with outdated source data.

    This is the last preliminary pull request. The following will contain speed optimization. Which one to start with: simple rendering optimization or complicated computational one?

    opened by se-ti 1
  • Vastly improve the Webpack build

    Vastly improve the Webpack build

    Vastly improve the Webpack build.

    Add npm run webpack command.

    Add documentation for Webpack to README.md

    Split the different variant builds into separate webpack outputs.

    Make the library components available at variables like HeatCanvas.

    Fix a strict mode failure (Webpack implies "use strict";)

    .gitignore node_modules/

    opened by johansen 1
  • Incorrect use of variable in Leaflet extension

    Incorrect use of variable in Leaflet extension

    Leaflet extension use a 'map' global variable, which works at demo page, but not real map. As a result, a following error occurs (from my Chromium JS console): Uncaught ReferenceError: map is not defined L.TileLayer.HeatCanvas.L.Class.extend.initialize heatcanvas-leaflet.js:27 NewClass leaflet-src.js:162

    // Next part is my page callback (anonymous function) index.php:96 jQuery.Callbacks.fire jquery.js:1046 jQuery.Callbacks.self.fireWith jquery.js:1164 jQuery.extend.ready jquery.js:435 DOMContentLoaded

    Hope it to be fixed soon. Thanks.

    opened by Obramko 1
  • missing script webpack!!

    missing script webpack!!

    I'm trying to install heatcanvas but running npm run webpack gives an error missing script webpack

    I tried to npm install webpack but that didn't resolve the earlier issue. Any idea?

    opened by Abeer-Alsaiari 0
  • Uncaught Error: The provided object is not a Layer.  with leaflet 1.3.1

    Uncaught Error: The provided object is not a Layer. with leaflet 1.3.1

     var heatmap = new L.TileLayer.HeatCanvas({}, {
            'step': 0.5,
            'degree': HeatCanvas.LINEAR,
            'opacity': 0.7
        });
    // inside a loop
    heatmap.pushData(a.coord.lat, a.coord.lon, a.main.temp);
    //
    map.addLayer(heatmap);
    

    I have checked in console the heatmap object is there with the data and coordinates, when adding to map it gives the above error.

    opened by neogeomat 0
  • Uncaught TypeError: Cannot read property '_leaflet_id' of undefined(…)

    Uncaught TypeError: Cannot read property '_leaflet_id' of undefined(…)

    Hi, I have faced this problem with leaflet while using this plugin,Is there any way to fix it? thanks. here is error leaflet.js:5 Uncaught TypeError: Cannot read property '_leaflet_id' of undefined(…)stamp @ leaflet.js:5_on @ leaflet.js:5on @ leaflet.js:5whenReady @ leaflet.js:6addLayer @ leaflet.js:6(anonymous function) @ sc.js:42i

    sc.js:42 is this code

    map.addLayer(heatmap);

    thanks very much

    opened by am2222 0
  • Black to Transparent Background

    Black to Transparent Background

    Sunng87,

    I really love your work with this heatcanvas. The results look fantastic on our maps. I have one thing I need a little help with:

    Similar to https://github.com/sunng87/heatcanvas/issues/13, I really need to overlay your heat canvas over a map where its features are visible. We place other features on our maps, such as custom pins and polygons, that need to work in conjunction with the heatmap functionality.

    We've had some success stemming from implementing the suggestions found in https://github.com/sunng87/heatcanvas/issues/13, but this is the best we've done:

    2013-09-17_06-52-30

    What we need is something, that in the end, looks more like this:

    2013-09-17_06-57-10

    (Please note, we took this from heatmap.js examples, which are also quite good. We just prefer your method for various reasons.) Please let us know if you can provide some guidance. Also, please not that we are a professional shop, so we do pay for custom work. If this will be a lot of your time, we would be willing to discuss compensation.

    Sincerely,

    Jim

    opened by fastport 5
  • How to refresh layer with Leaflet/OSM

    How to refresh layer with Leaflet/OSM

    How do I refresh my heatmap with new data in a Leaflet/OSM environment?

    I can successfully build the map using: heatmap = new L.TileLayer.HeatCanvas...

    and can load the map using: for (var i in MapData) { console.log('data'); heatmap.pushData(MapData[i][0], MapData[i][1], MapData[i][2]) }

    My problem is I do not know how to clear the heatmap and load new data.

    I have tried using heatmap.clear(), but this seems to have no effect as everytime I push data into the heatmap it simply adds to the existing data.

    Does anyone know how to basically clear the data from a heatmap, load new data in, and redraw the map?

    opened by mikekay01 5
Owner
Ning Sun
Programmer, at work and at home. Open source enthusiast. Linux user. Favourite languages: Clojure, Rust
Ning Sun
The smallest, simplest and fastest JavaScript pixel-level image comparison library

pixelmatch The smallest, simplest and fastest JavaScript pixel-level image comparison library, originally created to compare screenshots in tests. Fea

Mapbox 5.1k Jan 8, 2023
The NASA WorldWind Javascript SDK (WebWW) includes the library and examples for creating geo-browser web applications and for embedding a 3D globe in HTML5 web pages.

Web WorldWind New versions of WorldWind released Web WorldWind 0.10.0 and WorldWind Java 2.2.0 are now available on GitHub. The new version of Web Wor

NASA WorldWind 770 Jan 1, 2023
A web based data mining tool for OpenStreetMap using the Overpass API.

overpass turbo https://overpass-turbo.eu/ – stable version https://tyrasd.github.io/overpass-turbo/ – latest version This is a GUI for testing and dev

Martin Raifer 607 Dec 29, 2022
Responsive, interactive and more accessible HTML5 canvas elements. Scrawl-canvas is a JavaScript library designed to make using the HTML5 canvas element a bit easier, and a bit more fun!

Scrawl-canvas Library Version: 8.5.2 - 11 Mar 2021 Scrawl-canvas website: scrawl-v8.rikweb.org.uk. Do you want to contribute? I've been developing thi

Rik Roots 227 Dec 31, 2022
Usage Heatmap for Shiny with heatmap.js

shinyHeatmap The goal of {shinyHeatmap} is to provide a free and local alternative to more advanced user tracking platform such as Hotjar. {shinyHeatm

RinteRface 15 Dec 21, 2022
HTML5 Canvas Gauge. Tiny implementation of highly configurable gauge using pure JavaScript and HTML5 canvas. No dependencies. Suitable for IoT devices because of minimum code base.

HTML Canvas Gauges v2.1 Installation Documentation Add-Ons Special Thanks License This is tiny implementation of highly configurable gauge using pure

Mykhailo Stadnyk 1.5k Dec 30, 2022
Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. I

Fabric.js 23.6k Jan 3, 2023
Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. I

Fabric.js 23.6k Jan 3, 2023
Konva.js is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.

Konva Konva is an HTML5 Canvas JavaScript framework that enables high performance animations, transitions, node nesting, layering, filtering, caching,

konva 8.7k Jan 8, 2023
(IDW) Interpolated Heatmap Layer for mapbox-gl

Mapbox :: Interpolated Heatmap(s) InterpolateHeatmapLayer is a minimalist JavaScript library for rendering temperature maps (or interpolate heatmaps)

Vinayak Kulkarni 13 Dec 15, 2022
A simple Calendar Heatmap for jQuery

Calendar Heat Map This jQuery plugin allows to conveniently display data like contributions on a day by day basis, indicating the count by colors. Ins

Sebastian 38 Jul 5, 2022
Statistics plugin for RemNote that will give you some helpful numbers, charts and heatmap for your knowledge base.

RemNote statistics plugin Features This plugin will give you the following statistics: Retention rate Number of cards due in future Type of buttons yo

Henrik 3 Sep 9, 2022
🔥 JavaScript Library for HTML5 canvas based heatmaps

heatmap.js Dynamic Heatmaps for the Web. How to get started The fastest way to get started is to install heatmap.js with bower. Just run the following

Patrick Wied 5.9k Jan 2, 2023
Warp drive is a lightweight jQuery plugin that helps you create a cool, interactive, configurable, HTML5 canvas based warp drive/starfield effect.

Warp drive jQuery plugin (jquery-warpdrive-plugin) Preview Description Warp drive is a lightweight jQuery plugin that helps you create a cool, interac

Niklas 51 Nov 15, 2022
Open source rich text editor based on HTML5 and the progressive-enhancement approach. Uses a sophisticated security concept and aims to generate fully valid HTML5 markup by preventing unmaintainable tag soups and inline styles.

This project isn’t maintained anymore Please check out this fork. wysihtml5 0.3.0 wysihtml5 is an open source rich text editor based on HTML5 technolo

Christopher Blum 6.5k Jan 7, 2023
Open source rich text editor based on HTML5 and the progressive-enhancement approach. Uses a sophisticated security concept and aims to generate fully valid HTML5 markup by preventing unmaintainable tag soups and inline styles.

This project isn’t maintained anymore Please check out this fork. wysihtml5 0.3.0 wysihtml5 is an open source rich text editor based on HTML5 technolo

Christopher Blum 6.5k Dec 30, 2022
React + Canvas = Love. JavaScript library for drawing complex canvas graphics using React.

React Konva React Konva is a JavaScript library for drawing complex canvas graphics using React. It provides declarative and reactive bindings to the

konva 4.9k Jan 9, 2023
A simple project to refresh on the usage of js canvas and getContext('2d') to create four interactive squares on the canvas when hovered changes color.

A simple project to refresh on the usage of js canvas and getContext('2d') to create four interactive squares on the canvas when hovered changes color. Can also be clicked to work on mobile devices.

DandaIT04 1 Jan 1, 2022
Canvas rendering library, Sprite manipulation of canvas

el-canvas Canvas rendering library, Sprite manipulation of canvas hello world <div id="app"><div></div></div> yarn add elem-canvas or npm i

null 15 Apr 13, 2022
The smallest, simplest and fastest JavaScript pixel-level image comparison library

pixelmatch The smallest, simplest and fastest JavaScript pixel-level image comparison library, originally created to compare screenshots in tests. Fea

Mapbox 5.1k Jan 8, 2023