SciChart.js JavaScript 2D Charts API > 2D Chart Types > The Uniform Heatmap Series Type
The Uniform Heatmap Series Type

Uniform Heatmaps can be created using the UniformHeatmapRenderableSeries type.

The JavaScript Heatmap Chart Example can be found in the SciChart.Js Examples Suite on Github, or our live demo at demo.scichart.com

Fast, Realtime JavaScript Heatmap Charts by SciChart.js

Create a Uniform Heatmap

Uniform heatmaps are extremely fast, lightweight series types for rendering two dimensional data as a heatmap or spectrogram. The UniformHeatmapRenderableSeries type should be used in conjunction with a UniformHeatmapDataSeries when you simply want to specify a Step in the X,Y direction (each cell is the same size).

To create a Javascript Heatmap Chart with SciChart.js, use the following code:

JavaScript Line Chart
Copy Code
import { NumericAxis } from "scichart/Charting/Visuals/Axis/NumericAxis";
import { SciChartSurface } from "scichart";
import { UniformHeatmapDataSeries } from "scichart/Charting/Model/UniformHeatmapDataSeries";
import { UniformHeatmapRenderableSeries } from "scichart/Charting/Visuals/RenderableSeries/UniformHeatmapRenderableSeries";
import { HeatmapColorMap } from "scichart/Charting/Visuals/RenderableSeries/HeatmapColorMap";
import { zeroArray2D } from "scichart/utils/zeroArray2D";

const { sciChartSurface, wasmContext } = await SciChartSurface.create(divElementId);
sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext));
// Generate some data for the heatmap series. We require 2-dimensional array of numbers (number[][] in Typescript)
const initialZValues: number[][] = generateData(WIDTH, HEIGHT, 200, 0, MAX_SERIES);

// Create a Heatmap Data-series. Pass the heatValues as a number[][] to the UniformHeatmapDataSeries
const heatmapDataSeries = new UniformHeatmapDataSeries(wasmContext, 100, 1, 100, 1, initialZValues);
// Create a Heatmap RenderableSeries with the color map. ColorMap.minimum/maximum defines the values in
// HeatmapDataSeries which correspond to gradient stops at 0..1
const heatmapSeries = new UniformHeatmapRenderableSeries(wasmContext, {
    dataSeries: heatmapDataSeries,
    colorMap: new HeatmapColorMap({
        minimum: 0,
        maximum: 200,
        gradientStops: [
            { offset: 0, color: "#00008B" },
            { offset: 0.2, color: "#6495ED" },
            { offset: 0.4, color: "#006400" },
            { offset: 0.6, color: "#7FFF00" },
            { offset: 0.8, color: "#FFFF00" },
            { offset: 1.0, color: "#FF0000" },
        ],
    }),
});
// Add heatmap to the chart
sciChartSurface.renderableSeries.add(heatmapSeries);

// ...

// This function generates data for the heatmap series example
// because data-generation is not trivial, we generate once before the example starts
// so you can see the speed & power of SciChart.js
function generateData(width: number, height: number, cpMax: number, index: number, maxIndex: number): number[][] {
    // Helper function which creates an empty 2D array filled with zeros
    const zValues = zeroArray2D([height, width]);

    // math.round but to X digits
    function roundTo(number: number, digits: number) {
        return parseFloat(number.toFixed(digits));
    }
    const angle = roundTo(Math.PI * 2 * index, 3) / maxIndex;
    // fill the 2D array with values. The mathematical formula here is simply to provide a nice demo
    for (let x = 0; x < width; x++) {
        for (let y = 0; y < height; y++) {
            const v =
                (1 + roundTo(Math.sin(x * 0.04 + angle), 3)) * 50 +
                (1 + roundTo(Math.sin(y * 0.1 + angle), 3)) * 50 * (1 + roundTo(Math.sin(angle * 2), 3));
            const cx = width / 2;
            const cy = height / 2;
            const r = Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy));
            const exp = Math.max(0, 1 - r * 0.008);
            const zValue = v * exp + Math.random() * 50;
            zValues[y][x] = zValue > cpMax ? cpMax : zValue;
        }
    }
    return zValues;
}

In the code above:

  • We create an empty 2D array (number[][]) using the helper function zeroArray2D. This is filled with values in the generateData function
  • A UniformHeatmapDataSeries instance is created with xStart, xStep, yStart, yStep values = 100, 1, 100, 1. This means the heatmap starts at X,Y = 100,100 and each cell is 1 on the axis.
  • We set the Colormap, which maps colors to heat values in the dataseries.
  • A UniformHeatmapRenderableSeries instance is created and added to the sciChartSurface.renderableSeries collection.

Updating Heatmaps

Updating Data in a Heatmap

The heatmap is supposed to be fully dynamic, enabling real-time graphics. The UniformHeatmapRenderableSeries however does not support append, insert, update, remove functions like other DataSeries do. You can however update the data and force a refresh simply by updating the data passed in. To do this, use the following code:

Example Title
Copy Code
import { UniformHeatmapDataSeries } from "scichart/Charting/Model/UniformHeatmapDataSeries";
import { zeroArray2D } from "scichart/utils/zeroArray2D";

// Create an empty 2D array of size height & width
const initialZValues: number[][] = zeroArray2D([height, width]);
// Create a Heatmap Data-series. Pass the heatValues as a number[][] to the UniformHeatmapDataSeries
const heatmapDataSeries = new UniformHeatmapDataSeries(wasmContext, 0, 1, 0, 1, initialZValues);

// ...

// Later, update the data
initialZValues[5][6] = 123.4;

// Tell SciChart the data has changed
heatmapDataSeries.notifyDataChanged()

// You can also load an entirely new array with the function UniformHeatmapDataSeries.setZValues
const newZValues: number[][];
heatmapDataSeries.setZValues(newZValues);

Updating the XStep, XStart, YStep, YStart

At the time of writing we have no way to update the xStep, xStart, yStep, yStart properties of a UniformHeatmapDataSeries once it has been created, but a workaround was posted at the SciChart Forum.

Heatmap Color Maps 

Converting Data-Values to Colors (Defining a Color Map)

Conversion of data value into color is defined by the property UniformHeatmapRenderableSeries.colorMap. The ColorMap is type HeatmapColorPalette. You can define a custom Color Palette in JavaScript as follows:

Defining a Heatmap ColorMap
Copy Code
import { UniformHeatmapDataSeries } from "scichart/Charting/Model/UniformHeatmapDataSeries";
import { UniformHeatmapRenderableSeries } from "scichart/Charting/Visuals/RenderableSeries/UniformHeatmapRenderableSeries";
import { HeatmapColorMap } from "scichart/Charting/Visuals/RenderableSeries/HeatmapColorMap";

const heatmapSeries = new UniformHeatmapRenderableSeries(wasmContext, {
    dataSeries: heatmapDataSeries,
    colorMap: new HeatmapColorMap({
        minimum: 0, // min value in the zValues (data) to map to offset 0 in the colormap
        maximum: 200, // max value in the zValues (data) to map to offset 1 in the colormap
        gradientStops: [
            { offset: 0, color: "#00008B" }, // Corresponds to ZValue <= minimum
            { offset: 0.2, color: "#6495ED" },
            { offset: 0.4, color: "#006400" },
            { offset: 0.6, color: "#7FFF00" },
            { offset: 0.8, color: "#FFFF00" },
            { offset: 1.0, color: "#FF0000" }, // Corresponds to ZValue >= maximum
        ],
    }),
});

What this means:

  • The GradientStop at Offset = 0 with Color = "#00008B" corresponds to the HeatmapColorMap.minimum value of 0
  • The GradientStop at Offset = 1 with Color = "#FF0000" corresponds to HeatmapColorMap.maximum value of 200.
  • Data within this range will be blended according to the gradient stops between 0 and 1
  • Data outside this range will be clamped to the minimum or maximum colors in the HeatmapColorMap

Defining how Data-values outside of ColorMap range are drawn

By default when defining a HeatmapColorMap any values that fall outside the range are clipped to the edges of the colormap. e.g. in the above example data falling outside of the range 0-200 is clipped to color "#00008B" and "#FF0000" respectively.

What if you wanted to have values below zero as transparent? This can be done easily via the HeatmapColorMap:

Defining a Heatmap ColorMap
Copy Code
import { UniformHeatmapDataSeries } from "scichart/Charting/Model/UniformHeatmapDataSeries";
import { UniformHeatmapRenderableSeries } from "scichart/Charting/Visuals/RenderableSeries/UniformHeatmapRenderableSeries";
import { HeatmapColorMap } from "scichart/Charting/Visuals/RenderableSeries/HeatmapColorMap";

const heatmapSeries = new UniformHeatmapRenderableSeries(wasmContext, {
    dataSeries: heatmapDataSeries,
    colorMap: new HeatmapColorMap({
        minimum: 0, // min value in the zValues (data) to map to offset 0 in the colormap
        maximum: 200, // max value in the zValues (data) to map to offset 1 in the colormap
        gradientStops: [
                { offset: 0, color: "Transparent" }, // Set the zero value as Transparent. Corresponds to zValue <= minimum
                { offset: 0.01, color: "#00008B" }, // Set a very small value here at 1% for zValue near minimum 
                { offset: 0.2, color: "#6495ED" },
                { offset: 0.4, color: "#006400" },
                { offset: 0.6, color: "#7FFF00" },
                { offset: 0.8, color: "#FFFF00" },
                { offset: 1.0, color: "#FF0000" }
        ],
    }),
});

This results in the following output:

 

 

Max Heatmap Size and Tiling Heatmaps

In SciChart.js the maximum heatmap size (NxM size of the 2-dimensional array) is determined by WebGL gl.MAX_TEXTURE_SIZE. This will be a different value depending on the GPU hardware, the browser and operating system. On a Windows PC Running in Chrome gl.MAX_TEXTURE_SIZE is 16,384 x 16,384 but could be as low as 2048 x 2048 on other devices.

For viewing massive heatmaps, SciChart.js allows tiling of heatmaps by placing multiple UniformHeatmapRenderableSeries onto the same SciChartSurface. Each heatmap can be positioned using xStart, xStep, yStart, yStep constructor parameters. This allows you to render very large datasets in browser and is how one of our users achieved this output: medical imaging using SciChart's heatmap feature.

See Also