Skip to main content Skip to footer

Creating a Heat Map Visualization with FlexMap and ColorScale in JavaScript

Wijmo FlexMap Heat Map

Background:

Wijmo does not currently provide a dedicated built-in HeatMap chart type. However, you can simulate a heat map by using the FlexMap control with ColorScale.

This approach works by rendering each heat map cell as a GeoJSON polygon and using ColorScale to assign colors based on each cell’s value.

Steps to Complete:

  1. Install and import the required Wijmo packages.
  2. Add a host element for the heat map.
  3. Create heat map data.
  4. Convert the data into GeoJSON polygons.
  5. Configure FlexMap, GeoMapLayer, and ColorScale.

Getting Started:

Install and import the required Wijmo packages

npm install @mescius/wijmo.purejs.all

Then import the required modules:

import '@mescius/wijmo.styles/wijmo.css';
import { FlexMap, GeoMapLayer, ColorScale } from '@mescius/wijmo.chart.map';
import { Position } from '@mescius/wijmo.chart';
  • FlexMap displays the visualization, GeoMapLayer renders the generated shapes, and ColorScale applies colors based on the data value.

 

Add a host element for the heat map

Add a container where the heat map will render.

<div id="heatMap"></div>

Add a height so the map has visible space on the page:

#heatMap {
  height: 420px;
  width: 100%;
}

 

Create heat map data

Define the row, column, and value for each heat map cell.

const heatData = [
  { region: 'North', quarter: 'Q1', value: 24 },
  { region: 'North', quarter: 'Q2', value: 38 },
  { region: 'North', quarter: 'Q3', value: 65 },
  { region: 'North', quarter: 'Q4', value: 42 },
  { region: 'South', quarter: 'Q1', value: 18 },
  { region: 'South', quarter: 'Q2', value: 55 },
  { region: 'South', quarter: 'Q3', value: 72 },
  { region: 'South', quarter: 'Q4', value: 49 }
];

const rows = [...new Set(heatData.map(item => item.region))];
const columns = [...new Set(heatData.map(item => item.quarter))];
  • Each object represents one heat map cell. The value field is what determines the cell color.

 

Convert the data into GeoJSON polygons

GeoMapLayer uses GeoJSON, so each heat map cell can be represented as a rectangular polygon.

function createHeatMapGeoJson(data, rows, columns) {
  return {
    type: 'FeatureCollection',
    features: data.map(item => {
      const x = columns.indexOf(item.quarter);
      const y = rows.indexOf(item.region);

      return {
        type: 'Feature',
        properties: item,
        geometry: {
          type: 'Polygon',
          coordinates: [[
            [x, y],
            [x + 1, y],
            [x + 1, y + 1],
            [x, y + 1],
            [x, y]
          ]]
        }
      };
    })
  };
}
  • This creates one polygon for each data point. The polygon’s properties object keeps the original value available for color binding and tooltips.

 

Configure FlexMap, GeoMapLayer, and ColorScale

Create the map, add a GeoMapLayer, and use ColorScale.binding to read each cell’s value.

const heatMapGeoJson = createHeatMapGeoJson(heatData, rows, columns);

let heatMap = new FlexMap('#heatMap', {
  header: 'Sales Heat Map',
  legend: {
    position: Position.Right
  },
  tooltip: {
    content: feature => {
      const item = feature.properties;
      return `${item.region}<br>${item.quarter}: ${item.value}`;
    }
  },
  layers: [
    new GeoMapLayer({
      itemsSource: heatMapGeoJson,
      style: {
        stroke: '#ffffff',
        strokeWidth: 1
      },
      colorScale: new ColorScale({
        binding: feature => feature.properties.value,
        colors: ['#2166ac', '#67a9cf', '#f7f7f7', '#fdae61', '#b2182b'],
        colorUnknown: '#eeeeee',
        format: 'n0'
      }),
      itemsSourceChanged: layer => {
        heatMap.zoomTo(layer.getGeoBBox());
      }
    })
  ]
});
  • ColorScale transforms each numeric value into a color. Lower values are displayed with cooler colors, and higher values are displayed with warmer colors.

 

With this setup, FlexMap displays a heat map-style visualization, and ColorScale automatically colors each cell based on the bound value.

Happy coding!

Andrew Peterson

Technical Engagement Engineer