If you want to learn about heatmaps. this demo shows you how to create a JavaScript Heatmap Chart using SciChart.js, our 5-star rated JavaScript Chart Component.
import {
HeatmapColorMap,
HeatmapLegend,
MouseWheelZoomModifier,
NumericAxis,
SciChartSurface,
UniformHeatmapDataSeries,
UniformHeatmapRenderableSeries,
zeroArray2D,
ZoomExtentsModifier,
ZoomPanModifier,
} from "scichart";
import { appTheme } from "./appTheme";
const MAX_SERIES = 100;
const WIDTH = 300;
const HEIGHT = 200;
// Draws a Heatmap chart in real-time
export const drawExample = async (rootElement: string | HTMLDivElement) => {
// Create a SciChartSurface
const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
theme: appTheme.SciChartJsTheme,
});
// Add XAxis and YAxis
sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { isVisible: false }));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { isVisible: false }));
// Create a Heatmap Data-series. Pass heatValues as a number[][] to the UniformHeatmapDataSeries
const initialZValues: number[][] = generateExampleData(WIDTH, HEIGHT, 200, 20, MAX_SERIES);
const heatmapDataSeries = new UniformHeatmapDataSeries(wasmContext, {
xStart: 0,
xStep: 1,
yStart: 0,
yStep: 1,
zValues: 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,
useLinearTextureFiltering: false,
colorMap: new HeatmapColorMap({
minimum: 0,
maximum: 200,
gradientStops: [
{ offset: 1, color: appTheme.VividPink },
{ offset: 0.9, color: appTheme.VividOrange },
{ offset: 0.7, color: appTheme.MutedRed },
{ offset: 0.5, color: appTheme.VividGreen },
{ offset: 0.3, color: appTheme.VividSkyBlue },
{ offset: 0.2, color: appTheme.Indigo },
{ offset: 0, color: appTheme.DarkIndigo },
],
}),
});
// Add heatmap to the chart
sciChartSurface.renderableSeries.add(heatmapSeries);
// Add interaction
sciChartSurface.chartModifiers.add(new ZoomPanModifier({ enableZoom: true }));
sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
// Functions for running the example in real-time
let timerId: NodeJS.Timeout;
let updateIndex: number = 0;
const updateChart = () => {
// Cycle through pre-generated data on timer tick
const newZValues = generateExampleData(WIDTH, HEIGHT, 200, updateIndex++, MAX_SERIES);
// Update the heatmap z-values
heatmapDataSeries.setZValues(newZValues);
if (updateIndex >= MAX_SERIES) {
updateIndex = 0;
}
timerId = setTimeout(updateChart, 16);
};
const startUpdate = () => {
if (!timerId) {
updateChart();
}
};
const stopUpdate = () => {
clearTimeout(timerId);
timerId = undefined;
};
const subscribeToRenderStats = (callback: (stats: { xSize: number; ySize: number; fps: number }) => void) => {
// Handle drawing/updating FPS
let lastRendered = Date.now();
sciChartSurface.rendered.subscribe(() => {
const currentTime = Date.now();
const timeDiffSeconds = (currentTime - lastRendered) / 1000;
lastRendered = currentTime;
const fps = 1 / timeDiffSeconds;
callback({
xSize: heatmapDataSeries.arrayWidth,
ySize: heatmapDataSeries.arrayHeight,
fps,
});
});
};
return { sciChartSurface, subscribeToRenderStats, controls: { startUpdate, stopUpdate } };
};
// Draws a Heatmap legend over the <div id={divHeatmapLegend}></div>
export const drawHeatmapLegend = async (rootElement: string | HTMLDivElement) => {
const { heatmapLegend, wasmContext } = await HeatmapLegend.create(rootElement, {
theme: {
...appTheme.SciChartJsTheme,
sciChartBackground: appTheme.DarkIndigo + "BB",
loadingAnimationBackground: appTheme.DarkIndigo + "BB",
},
yAxisOptions: {
isInnerAxis: true,
labelStyle: {
fontSize: 12,
color: appTheme.ForegroundColor,
},
axisBorder: {
borderRight: 1,
color: appTheme.ForegroundColor + "77",
},
majorTickLineStyle: {
color: appTheme.ForegroundColor,
tickSize: 6,
strokeThickness: 1,
},
minorTickLineStyle: {
color: appTheme.ForegroundColor,
tickSize: 3,
strokeThickness: 1,
},
},
colorMap: {
minimum: 0,
maximum: 200,
gradientStops: [
{ offset: 1, color: appTheme.VividPink },
{ offset: 0.9, color: appTheme.VividOrange },
{ offset: 0.7, color: appTheme.MutedRed },
{ offset: 0.5, color: appTheme.VividGreen },
{ offset: 0.3, color: appTheme.VividSkyBlue },
{ offset: 0.2, color: appTheme.Indigo },
{ offset: 0, color: appTheme.DarkIndigo },
],
},
});
return { sciChartSurface: heatmapLegend.innerSciChartSurface.sciChartSurface };
};
// 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 generateExampleData(
width: number,
height: number,
cpMax: number,
index: number,
maxIndex: number
): number[][] {
// Returns a 2-dimensional javascript array [height (y)] [width (x)] size
const zValues = zeroArray2D([height, width]);
// math.round but to X digits
function roundTo(number: number, digits: number) {
return number;
// return parseFloat(number.toFixed(digits));
}
const angle = roundTo(Math.PI * 2 * index, 3) / maxIndex;
// When appending data to a 2D Array for the heatmap, the order of appending (X,Y) does not matter
// but when accessing the zValues[][] array, we set data [y] then [x]
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
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() * 10;
zValues[y][x] = zValue > cpMax ? cpMax : zValue;
}
}
return zValues;
}
This example demonstrates a high-performance Heatmap Chart implemented using JavaScript with SciChart.js. The implementation focuses on real-time data streaming and dynamic visual updates, leveraging WebGL-powered rendering for optimal performance.
The chart is built by creating a SciChartSurface instance via the SciChart.js API, and hidden numeric axes are added to simplify the presentation. The example generates a two-dimensional array of data which is fed to a UniformHeatmapDataSeries. A UniformHeatmapRenderableSeries is then configured with a detailed gradient via HeatmapColorMap to accurately represent the data. Real-time updates are managed using JavaScript’s setTimeout to continuously update the series, as explained in the Adding Realtime Updates documentation.
Key features include real-time chart updates with dynamic data streaming, advanced color mapping techniques, and integrated performance monitoring. The color mapping is finely tuned using gradient stops which you can learn more about in the Uniform Heatmap Chart documentation and Uniform-Heatmap-Colormaps resources. In addition, interactive modifiers such as ZoomPanModifier and MouseWheelZoomModifier enhance the user experience.
Built on JavaScript, this example adheres to best practices by directly interacting with the SciChart.js API without relying on additional frameworks. Developers can monitor performance by subscribing to render events, a technique detailed in the Performance Tips & Tricks guide. Furthermore, interactive features are implemented using modifiers like the MouseWheelZoomModifier to ensure a smooth user experience. This approach provides a clear and maintainable structure for integrating SciChart.js within any JavaScript project.








































