How to Design Software — Dynamic Heatmaps
By: Joseph Gefroh
Tags: JavaScript, Software Development, Front End Development, Programming, Software Engineering

What is a heatmap?

A heatmap essentially shows a map and colors in various aspects of it based on some sort of scale.

The “map” doesn’t necessarily have to be a map — it can be a periodic table or a bunch of circles. What really matters is that there are distinct areas that will be colored differently depending on what bucket that distinct area falls in to.

The components

There’s three aspects of a heatmap as far as web applications are concerned.

the map

the code

the data

The map

First off, you need an SVG of a map that you can color. I took this one from the Wikimedia Commons:

This particular US map was a SVG available for from Wikimedia.

Breaking down an SVG

If you ever interacted with an SVG file, you may have noticed it behaves differently than other image files. Some sites don’t let you upload them, they maintain their quality when their size changes, and your browser seems to be the default file opener in a lot of cases.

Well, that’s because they are different. SVGs actually consist of markup. If you inspect an SVG file, you’ll see all of the markup that makes up the SVG image.

The markup for the map above, with some CSS added to the <path> element for Hawaii, coloring it red.

All of that incomprehensible garbage is actually the data that then makes up the individual lines and shapes. This means that you can do a lot of things like interact with it using Javascript and CSS. It behaves like HTML, so you can add styles, ids, attributes, etc.

That’s where the true power is.

Prepare your SVG

So, let’s assume you found or created your SVG. If you create one, I don’t recommend coding it — use a drawing tool that will output an SVG.

You need to prepare your SVG by adding identifiers to all of the various parts you want to independently color.

The map above was particularly convenient — it was already categorized into states. For others, you may need to do it yourself.

Each of the individual <path> elements that make up a state had an ID attached to it with the ISO 3166 Alpha-2 code.

Hawaii, for example, has an id of HI . If your map is missing it, simply add the id="HI" to the <path> that makes up Hawaii.

These IDs will be used as handles to manipulate it in the future using Javascript.

The Code

Now, let’s write the coloring function. It’ll be a function that takes an identifier and sets a color. We’ll flesh this out later once we structure the data appropriately — for now let’s stub it out and return a randomly selected color.

We don’t care about the color specifically or how it is chosen. What we are caring about is tying it together.

// map.js

function setColorFor(state) {

let color = Math.random() > 0.5 ? 'red' : 'blue'; let element = document.getElementById(state)

if (element) {

element.style.fill = color;

}

} setColorFor('HI');

Put them both in an HTML file

Let’s go and put them together.



<html>

<body>

<svg xmlns="

<!-- Put the rest of the SVG here... -->

</svg> http://www.w3.org/2000/svg " viewBox="0 0 930 585"> <script type="text/javascript" src="map.js"></script>

</body>

</html>

You should see something like below:

Open map.html using your browser and you should see Hawaii with a color.

The Data

Now, we get to the final piece of the puzzle: the data.

Structure of data

We need to structure the data in a way we can push it to the map while maintaining domain independence. All this means is that we shouldn’t have to change the code to make it work with another use case.

Suppose we are using this map to visualize the extent of coronavirus cases in the United States. Let’s make up some numbers and see what a subset of this data would look like:

let positiveTests = {

HI: 500,

WA: 1000,

MD: 10,

FL: 9001

}

Great! We clearly have a key-value pair of state code to value. Now, how do we bucket these into groups along a scale? I’m not a data algorithm expert, so we’ll do a bit of a janky approach.

First calculate how we want to distribute it

The first decision to make — how many buckets do we want?

Let’s suppose we want to have the following breakdown:

High (≥ 5000) [Red]

Moderate (≥ 1000 and < 5000) [Orange]

Low (≥ 500 and < 1000) [Yellow]

Minimal (< 500) [Green]

Unknown [Grey]

We effectively have 5 buckets that we will divide the values into. This is what I will call the distribution scale (not the actual name since I’m not a data guy).

This distribution scale can be hard-coded as below:

function getColorFor(value) {

if (!value) {

return 'grey';

}

else if (value >= 5000) {

return 'red';

}

else if (value >= 1000) {

return 'orange';

}

else if (value >= 500) {

return 'yellow'

}

else {

return 'green';

}

}

Now, let’s incorporate this getColorFor(value) function into the setColorFor(state) function we created above in our map.js script:

// map.js

let data = {

HI: 500,

WA: 1000,

MD: 10,

FL: 9001

} function setColorFor(state) {

let color = getColorFor(data[state]);

let element = document.getElementById(state)

if (element) {

element.style.fill = color;

}

} function getColorFor(value) {

// ...

} setColorFor('HI');

At this point, Hawaii should turn yellow — this makes sense because our data says that Hawaii has ≥ 500 cases. However, all the other states in the dataset are still grey.

Coloring the other states

The other states are still grey because the coloring of states is hard-coded.

The setColorFor('HI') line is the line of code that is triggering the color change. We could go and write out every single state, but that is boring and just poor engineering.

Let’s go and make it so that we don’t have to list every state individually. Let’s remove setColorFor('HI') and replace it with the below code.

//map.js

// ...all other code function applyData(data) {

Object.keys(data).forEach(function(key) {

setColorFor(key);

});

} applyData(data);

Now we should see all the states we included in our dataset light up like a rainbow:

applyData(data) will go and iterate through the object’s keys, which happen to be state abbreviations like ‘HI’ or ‘WA’.

You can now see how you would start adding new colors, etc. It’s all very straightforward to do.