Skip to main content Skip to footer

Creating a Heat Map Visualization with FlexMap and ColorScale in React

FlexMap heat map

Background:

Wijmo does not currently provide a dedicated built-in HeatMap chart type. However, in React applications, you can create a heat map-style visualization by using Wijmo’s FlexMap, GeoMapLayer, and ColorScale components.

This approach renders each heat map cell as a GeoJSON polygon. The ColorScale component then applies colors to each cell based on its numeric value.

Steps to Complete:

  1. Install the required packages.
  2. Import Wijmo React components.
  3. Create the heat map data.
  4. Convert the data into GeoJSON polygons.
  5. Render the map with React components.

Getting Started:

Install the required packages

npm install @mescius/wijmo.react.chart.map @mescius/wijmo.react.chart @mescius/wijmo.styles
  • The chart.map package provides React components for FlexMap, GeoMapLayer, and ColorScale. The chart package provides the legend component.

 

Import Wijmo React components

import { useCallback, useMemo } from 'react';
import '@mescius/wijmo.styles/wijmo.css';

import { FlexChartLegend } from '@mescius/wijmo.react.chart';
import { FlexMap, GeoMapLayer, ColorScale } from '@mescius/wijmo.react.chart.map';
import { Position } from '@mescius/wijmo.chart';
  • These imports allow the map, map layer, legend, and color scale to be declared directly in JSX.

 

Create the heat map data

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 }
];
  • Each object represents one heat map cell. The value field determines the color assigned by ColorScale.

 

Convert the data into GeoJSON polygons

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]
          ]]
        }
      };
    })
  };
}
  • GeoMapLayer expects GeoJSON data, so each heat map cell is represented as a rectangular polygon.

 

Render the map with React components

const heatColors = ['#2166ac', '#67a9cf', '#f7f7f7', '#fdae61', '#b2182b'];
const cellStyle = { stroke: '#ffffff', strokeWidth: 1 };
const mapHostStyle = { width: '100%', height: '420px' };

export default function App() {
  const rows = useMemo(() => [...new Set(heatData.map(item => item.region))], []);
  const columns = useMemo(() => [...new Set(heatData.map(item => item.quarter))], []);

  const heatMapGeoJson = useMemo(() => {
    return createHeatMapGeoJson(heatData, rows, columns);
  }, [rows, columns]);

  const getHeatValue = useCallback(feature => {
    return feature.properties.value;
  }, []);

  const initMap = useCallback(map => {
    map.tooltip.content = feature => {
      const item = feature.properties;
      return `${item.region}<br>${item.quarter}: ${item.value}`;
    };
  }, []);

  const fitHeatMap = useCallback(layer => {
    if (layer.map) {
      layer.map.zoomTo(layer.getGeoBBox());
    }
  }, []);

  return (
    <FlexMap
      header="Sales Heat Map"
      initialized={initMap}
      style={mapHostStyle}
    >
      <FlexChartLegend position={Position.Right} />

      <GeoMapLayer
        itemsSource={heatMapGeoJson}
        style={cellStyle}
        itemsSourceChanged={fitHeatMap}
      >
        <ColorScale
          binding={getHeatValue}
          colors={heatColors}
          colorUnknown="#eeeeee"
          format="n0"
        />
      </GeoMapLayer>
    </FlexMap>
  );
}
  • The FlexMap component renders the visualization, GeoMapLayer displays the generated GeoJSON cells, and ColorScale colors each cell according to its bound value.

  • The initialized callback configures the tooltip, while itemsSourceChanged zooms the map to the generated heat map area after the layer is bound.

Happy coding!

Andrew Peterson

Technical Engagement Engineer