Building choropleth map (heatmap) of India in Javascript using react-simple-maps

Varun Kumar
4 min readMar 29, 2020

--

A choropleth map is a great way to visualize data for a given geographical region. In this map areas are coloured, shaded or patterned in relation to a data variable.
Recently I was working in a project in which I had to plot data of Covid-19 confirmed cases against each state of India. I implemented this in react using react-simple-maps and in this article, I’ll walk you through all the steps of implementation.

Choropleth Map of India

Getting TopoJSON data of India

The first step of creating Choropleth Map is to get TopoJson (extension of GeoJSON) data for given country. For India, you can download this file but for other countries you can refer steps mentioned in Readme of datamaps.

Creating the Map Component

For creating our Map Component, we’ll use ComposableMap from react-simple-maps.

import { 
ComposableMap, Geographies, Geography
} from 'react-simple-maps';

const INDIA_TOPO_JSON = require('./india.topo.json');

const PROJECTION_CONFIG = {
scale: 350,
center: [78.9629, 22.5937]
};

function App() {
return (
<ComposableMap
projectionConfig={PROJECTION_CONFIG}
projection="geoMercator"
width={600}
height={220}
data-tip=""
>
<Geographies geography={INDIA_TOPO_JSON}>
{({ geographies }) =>
geographies.map(geo => {
const current = data.find(s => s.id === geo.id);
return (
<Geography
key={geo.rsmKey}
geography={geo}
fill={current ? colorScale(current.value) : DEFAULT_COLOR}
style={geographyStyle}
onMouseEnter={onMouseEnter(geo, current)}
onMouseLeave={onMouseLeave}
/>
);
})
}
</Geographies>
</ComposableMap>
)
}

Sample Map Data

In above code snippet, we are referencing data variable for our map data. A sample data would look like this-

const getHeatMapData = () => {
return [
{ id: 'AP', state: 'Andhra Pradesh', value: getRandomInt() },
{ id: 'AR', state: 'Arunachal Pradesh', value: getRandomInt() },
{ id: 'AS', state: 'Assam', value: getRandomInt() },
{ id: 'BR', state: 'Bihar', value: getRandomInt() },
{ id: 'CT', state: 'Chhattisgarh', value: getRandomInt() },
{ id: 'GA', state: 'Goa', value: 21 },
{ id: 'GJ', state: 'Gujarat', value: 22 },
{ id: 'HR', state: 'Haryana', value: getRandomInt() },
{ id: 'HP', state: 'Himachal Pradesh', value: 24 },
{ id: 'JH', state: 'Jharkhand', value: 26 },
{ id: 'KA', state: 'Karnataka', value: 27 },
{ id: 'KL', state: 'Kerala', value: getRandomInt() },
{ id: 'MP', state: 'Madhya Pradesh', value: getRandomInt() },
{ id: 'MH', state: 'Maharashtra', value: getRandomInt() },
{ id: 'MN', state: 'Manipur', value: getRandomInt() },
{ id: 'ML', state: 'Meghalaya', value: 59 },
{ id: 'MZ', state: 'Mizoram', value: getRandomInt() },
{ id: 'NL', state: 'Nagaland', value: 59 },
{ id: 'OR', state: 'Odisha', value: 59 },
{ id: 'PB', state: 'Punjab', value: getRandomInt() },
{ id: 'RJ', state: 'Rajasthan', value: getRandomInt() },
{ id: 'SK', state: 'Sikkim', value: getRandomInt() },
{ id: 'TN', state: 'Tamil Nadu', value: getRandomInt() },
{ id: 'TG', state: 'Telangana', value: getRandomInt() },
{ id: 'TR', state: 'Tripura', value: 14 },
{ id: 'UT', state: 'Uttarakhand', value: getRandomInt() },
{ id: 'UP', state: 'Uttar Pradesh', value: 15 },
{ id: 'WB', state: 'West Bengal', value: 17 },
{ id: 'WB', state: 'West Bengal', value: 17 },
{ id: 'AN', state: 'Andaman and Nicobar Islands', value: getRandomInt() },
{ id: 'CH', state: 'Chandigarh', value: getRandomInt() },
{ id: 'DN', state: 'Dadra and Nagar Haveli', value: 19 },
{ id: 'DD', state: 'Daman and Diu', value: 20 },
{ id: 'DL', state: 'Delhi', value: 59 },
{ id: 'JK', state: 'Jammu and Kashmir', value: 25 },
{ id: 'LA', state: 'Ladakh', value: getRandomInt() },
{ id: 'LD', state: 'Lakshadweep', value: getRandomInt() },
{ id: 'PY', state: 'Puducherry', value: getRandomInt() }
];
};

Adding Tooltip

To show data on hover of each state, we can add onMouseEnter and onMouseLeave event listeners along with react-tooltip.

import React, { useState } from 'react';
import ReactTooltip from 'react-tooltip';

function App() {
const [tooltipContent, setTooltipContent] = useState('');

const onMouseEnter = (geo, current = { value: 'NA' }) => {
return () => {
setTooltipContent(`${geo.properties.name}: ${current.value}`);
};
};

const onMouseLeave = () => {
setTooltipContent('');
};

return () {
<>
<ReactTooltip>{tooltipContent}</ReactTooltip>
<ComposableMap
data-tip=""
// other props
/>
</>
}
}

Showing Gradient

Gradient to show data range

To give users an idea about intensity of data, we can show a linear gradient with min = minimum of all values and max = maximum of all values.

const LinearGradient = props => {
const { data } = props;
const boxStyle = {
width: 180,
margin: 'auto'
};
const gradientStyle = {
backgroundImage:
`linear-gradient(to right, ${data.fromColor} , ${data.toColor})`,
height: 20
};
return (
<div>
<div style={boxStyle} className="display-flex">
<span>{data.min}</span>
<span className="fill"></span>
<span>{data.max}</span>
</div>
<div
style={{ ...boxStyle, ...gradientStyle }}
className="mt8">
</div>
</div>
);
};

Source Code

A complete source code for above implementation is available at https://github.com/varunon9/india-choropleth-javascript

References

  1. datamaps: https://github.com/markmarkoh/datamaps
  2. react-simple-maps: https://github.com/zcreativelabs/react-simple-maps

--

--