Using choropleth maps is one of the popular ways to create infographics. Interactive maps allow to extend the possibilities of infographics, for example by dynamically generating a map based on an updatable data set.
In this tutorial we will show how to create a heatmap representing data from a dataset. To do this, we will create a map of the U.S. population as an example.
Population data used in this example will be as listed below:
State id | Population |
First, we should select colors that will represent minimum and maximum population. The color for each state will be calculated based on its population percentage between minimum and maximum values. The calculation scenario is provided below:
var max_color = "#d50000",
min_color = "#ffd5d5",
color_ratio = {},
max_pop = Math.max.apply (
Math,
population_data.map (
function ( obj ) {
return parseInt ( obj.pop );
}
)
),
min_pop = Math.min.apply (
Math,
population_data.map (
function ( obj ) {
return parseInt ( obj.pop );
}
)
),
diff = max_pop - min_pop;
$.each ( population_data.population, function ( id, pop ){
pop = parseInt ( pop );
color_ratio[ id ] = {
ratio: ( pop - min_pop ) / ( diff ),
pop: pop.toString ()
};
});
We assume that all necessary data are already received from the server and are available in some variable (in our case this variable is named population_data). It should contain data in the form of array of objects like in the example below.
var population_data = [
{id: "st1", pop: "4858979"},
{id: "st2", pop: "738432"},
{id: "st3", pop: "6828065"},
...
];
First, we initialize the boundary values for colors as min_color and max_color. Then, in the loop we calculate the percentage of population values between the boundary values for each state via ( pop - min_pop ) / ( diff ) and store them along with the values themselves in a new object (color_ratio). It will be used later. The fragment max_pop = Math.max.apply ( ... ) allows us to loop through population_data array and find there the maximum value of population (the same is true for the minimum value).
There are two ways to calculate proportional values for colors: write our own function or use a plugin. We provide examples for both cases.
var color = colorByRatio ( min_color, max_color, ratio );
function colorByRatio ( color1, color2, ratio ){
var max_color, min_color;
if ( parseInt ( color1.replace ( '#', '') ) > parseInt ( color1.replace ( '#', '') ) ) {
max_color = color1;
min_color = color2;
} else {
max_color = color2;
min_color = color1;
}
var rgb_max = Raphael.getRGB ( max_color ),
rgb_min = Raphael.getRGB ( min_color );
var rgb = "rgb(" +
[
Math.round ( rgb_min.r + ( rgb_max.r - rgb_min.r ) * ratio ),
Math.round ( rgb_min.g + ( rgb_max.g - rgb_min.g ) * ratio ),
Math.round ( rgb_min.b + ( rgb_max.b - rgb_min.b ) * ratio )
].join ( ',' ) +
")";
return Raphael.color ( rgb ).hex;
}
This function is based on the following principle. The resulting color's intensity values of red, green and blue should be in the same percentage within the boundary colors' intensity values as the percentage of population value within boundary population values.
The function takes three parameters: the first two are color values (HEX string only) for our boundary colors (in any order) and the third is the percentage between them. After calculation it returns a new color value in the form of a HEX string.
var color = $.xcolor.opacity ( color_min, color_max, ratio );
In this example we use the jQuery color plugin xcolor.
This plugin provides many useful functions for working with colors. The function we use is $.xcolor.opacity.
Like in the first example it takes three parameters, but in this case the order does matter. The first parameter is the minimum color followed by the maximum color.
Now, when we know how to convert population to color, all is left is to set them to our map. This can be done as follows:
$.each ( color_ratio, function ( id, obj ) {
map.mapConfig.map_data[ id ][ 'color' ] = colorByRatio ( min_color, max_color, obj.ratio );
map.mapConfig.map_data[ id ][ 'colorOver' ] = colorByRatio ( min_color, max_color, obj.ratio );
map.mapConfig.map_data[ id ][ 'comment' ] = "State population: " + obj.pop + " ppl.";
});
In this code snippet we are looping through the previously defined color_ratio object that holds the percentage and population values for each state. Inside the loop we change settings of the map by accessing the map.mapConfig object and assigning our values to the properties of each "state" object.
Here we specified the color for each state and the hover color (the color and colorOver properties respectively) and also the pop-up content (the comment property) so we can see the state population on hover as well.
In this example, we use the demo version of the HTML5 US map. Additionally, choropleth colorization is frequently used for the square tile grid map of the USA.