Marker Cluster Calculator for Google Maps v3

If you’ve ever worked with the Google Maps API for a large number of markers I’d say you’ve run into this issue; how do you manage hundreds of markers on the map without killing your browser? Now admittedly over the past few years browsers have improved massively (thanks to the “browser wars 2.0″), but handling a large number of markers is a sure-fire way to make even modern browsers fall over.

So what’s the answer? Thankfully there are helper libraries that allow you to cluster markers together, so the browser only has to draw one icon, rather than fifty. An excellent article on the subject was written in 2010 by Luke Mahe and Chris Broadfoot of Google. In it they go into great detail on what the problem is, and how to solve it with a sprinkle of JavaScript magic.

For a recent project I required marker clustering, as there were 500+ markers to be rendered on the map. I decided to use the MarkerClusterer library to do the job. It applies grid-based clustering, each marker is added to its closest cluster group within the set bounds. Everything worked perfectly until the client requested a change to how many cluster groups there were. Luckily there is a setCalculator() method that allows you to modify how clusters are defined and influence the styling, but looking around the net I saw very little explanation of what exactly this calculator function was doing, so I’ve created a small demo and heavily commented the setCalculator function for future users.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* Set our own custom marker cluster calculator
* It's important to remember that this function runs for EACH
* cluster individually.
* @param  {Array} markers Set of markers for this cluster.
* @param {Number} numStyles Number of styles we have to play with (set in mcOptions).
*/
markerCluster.setCalculator(function(markers, numStyles){
    //create an index for icon styles
    var index = 0,
    //Count the total number of markers in this cluster
        count = markers.length,
    //Set total to loop through (starts at total number)
        total = count;

    /**
     * While we still have markers, divide by a set number and
     * increase the index. Cluster moves up to a new style.
     *
     * The bigger the index, the more markers the cluster contains,
     * so the bigger the cluster.
     */
    while (total !== 0) {
        //Create a new total by dividing by a set number
        total = parseInt(total / 5, 10);
        //Increase the index and move up to the next style
        index++;
    }

    /**
     * Make sure we always return a valid index. E.g. If we only have
     * 5 styles, but the index is 8, this will make sure we return
     * 5. Returning an index of 8 wouldn't have a marker style.
     */
    index = Math.min(index, numStyles);

    //Tell MarkerCluster this clusters details (and how to style it)
    return {
        text: count + " ("+ index + ")",
        index: index
    };
});

Hopefully it’s all self-explanatory as to what the method is doing. Each cluster has its own index, this defines what icon is used. You can modify these icons and add your own, and also change how many cluster levels there will be.

You can view the simple demo here, here’s a direct link to the map JavaScript file.

Loading

Webmentions