How are those cool heat maps on the Internet plotted? I believe you are also curious. In this paper, canvas will be used as a drawing example to explain the principle of calorimetry.

transparency

We often come across the concept of transparency, such as opacity in CSS, alpha in RGBA color, globalAlpha in Canvas, etc.

They typically range from 0 to 1, with 0 being completely transparent and 1 being opaque, and the smaller the value, the more transparent.

Transparency overlay

Consider a question: what is the opacity of a rectangle with a opacity of 0.2 superimposed on a rectangle with a opacity of 0.6?

The result can be seen in the following example, which prints the superimposed transparency (divided by 255) using the Canvas getImageData method

See the Pen canvas-opacity by linghuam (@linghuam) on CodePen.

Many people’s first impression may be 0.8, in fact, this is a kind of natural understanding. The right idea is as follows:

Assuming transparency is defined as the transmittance of the glass, alpha=0.2 means that when a beam of light hits the glass, 20% of the light bounces back (the portion of light that enters your eye) and 80% passes through, so what we see is blurry. Similarly, alpha=0 means all the light has gone through, so we can’t see anything, alpha=1 means all the light has been reflected, so we can see everything.

So the superposition of alpha=0.2 and alpha=0.6 is equivalent to the superposition of two glasses. 80% of the light from the first glass penetrates, and 40% of the light from the second glass penetrates. In this way, how much light will be reflected after passing through the two glasses? 1*0.2 + (1-0.2)*0.6 = 0.68, so the final opacity is 0.68 instead of 0.8.

The following article summarizes its calculation formula: superposition of two translucent colors

Principle of thermograph

In fact, the thermal map is rendered according to the size and overlay of transparency.

Our first dataset is an array of objects, each element containing {x, y, value} attributes. We first find the maximum value Max from this group of values, and then use the value of value/ Max to represent transparency, so that we can draw small circles with different transparency on the canvas. At first, these circles are black and white, so the next step needs to color according to different transparency.

Looking at the MAPV source code, it implements an Intensity class that is used to achieve a gradient for different transparencies.

First, he created a 256 * 1 canvas, and then used canvas createLinearGradient to fill in the gradient, so that a transparency value can correspond to a color value on the canvas. The getImageData method is used to get the corresponding color value based on transparency.

Intercept part of the core code:

// Create a 256*1 canvas and fill it with gradients
Intensity.prototype.initPalette = function () {

    var gradient = this.gradient;

    var canvas = new Canvas(256.1);

    var paletteCtx = this.paletteCtx = canvas.getContext('2d');

    var lineGradient = paletteCtx.createLinearGradient(0.0.256.1);

    for (var key in gradient) {
        lineGradient.addColorStop(parseFloat(key), gradient[key]);
    }

    paletteCtx.fillStyle = lineGradient;
    paletteCtx.fillRect(0.0.256.1);

}

// Use the transparency value to get the corresponding color
Intensity.prototype.getImageData = function (value) {

    var imageData = this.paletteCtx.getImageData(0.0.256.1).data;

    if (value === undefined) {
        return imageData;
    }

    var max = this.max;
    var min = this.min;

    if (value > max) {
        value = max;
    }

    if (value < min) {
        value = min;
    }

    var index = Math.floor((value - min) / (max - min) * (256 - 1)) * 4;

    return [imageData[index], imageData[index + 1], imageData[index + 2], imageData[index + 3]];
}
Copy the code

Of course, in order to make the thermal map look better, the author uses canvas shadowBlur to achieve an edge blur effect.

At this point, the realization principle of the thermal diagram is introduced, the following is a small Demo I do according to this principle:

See the Pen canvas-heatmap by linghuam (@linghuam) on CodePen.

The resources

  • Mapv heat map
  • heatmapjs