Google Maps JavaScript MarkerClusterer

repository·main·Indexed 43 days ago

https://github.com/googlemaps/js-markerclusterer

A library for creating and managing per-zoom-level clusters for large amounts of markers on Google Maps. Version 2.6.2 supports both legacy google.maps.Marker and AdvancedMarkerElement, providing multiple clustering algorithms including SuperCluster, GridAlgorithm, and SuperClusterViewportAlgorithm to improve map performance and readability.

Tokens
6.2K
Snippets
26
Records
36
Agent score
54%

What's inside MarkerClusterer

  1. Install @googlemaps/markerclusterer

    main

    You can install the library via npm or include it directly in your HTML using a UMD link.

    npm installation

    npm i @googlemaps/markerclusterer

    UMD installation

    Add the following script tag to your HTML document:

    <script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>

    When using the UMD version, the MarkerClusterer class is available under the markerClusterer.MarkerClusterer namespace.

  2. Migrating from @googlemaps/markerclustererplus

    main

    If you are migrating from the older @googlemaps/markerclustererplus library, note the following breaking changes:

    1. Options Object: MarkerClusterer now accepts a single options object instead of positional parameters.
    2. Algorithm & Renderer: The constructor now explicitly accepts algorithm and renderer parameters for increased flexibility.
    3. Default Algorithm: The default algorithm is now supercluster (which uses k-d trees for performance), whereas GridAlgorithm is still supported but no longer the default.
    4. Styling: Cluster styling has been simplified and moved into the Renderer interface.
    5. Implementation: MarkerClusterer is still an instance of google.maps.OverlayView, but it now uses google.maps.Markers instead of google.maps.Overlay to render clusters, improving compatibility with map panes and click handlers.
  3. Use the MarkerClusterer library

    main

    The @googlemaps/markerclusterer package provides tools for clustering markers on a Google Map. The library is organized into several functional modules that you can import directly from the main entrypoint:

    • MarkerClusterer: The core class used to manage markers and create clusters.
    • algorithms: Provides different clustering algorithms (e.g., SuperCluster).
    • cluster: Contains classes and logic related to individual clusters.
    • renderer: Allows for customizing how clusters and markers are visually rendered on the map.
    • marker-utils: Utility functions for working with markers.

    To use the library, import the necessary components from @googlemaps/markerclusterer.

    import { MarkerClusterer, SuperClusterAlgorithm } from '@googlemaps/markerclusterer';
    
    // Example initialization pattern
    const markerClusterer = new MarkerClusterer({ map, markers, algorithm: new SuperClusterAlgorithm() });
  4. Implement a custom clustering algorithm

    main

    To provide a custom clustering logic to the MarkerClusterer, you must implement the Algorithm interface. An algorithm takes marker data and map context as input and returns an array of clusters.

    AlgorithmInput

    An object containing:

    • map: The google.maps.Map instance.
    • markers: An array of Marker objects to be clustered.
    • mapCanvasProjection: A google.maps.MapCanvasProjection used for converting coordinates to pixels.

    AlgorithmOutput

    An object containing:

    • clusters: An array of Cluster objects generated by the algorithm.
    • changed (optional): A boolean flag indicating if the clusters have changed since the last calculation.
    import { Algorithm, AlgorithmInput, AlgorithmOutput } from '@googlemaps/markerclusterer';
    
    export class MyCustomAlgorithm implements Algorithm {
      calculate({ markers, map }: AlgorithmInput): AlgorithmOutput {
        // Your clustering logic here
        const clusters: Cluster[] = []; 
        
        return {
          clusters,
          changed: true
        };
      }
    }
  5. Handle cluster click events

    main

    You can handle cluster clicks in two ways:

    1. Via the onClusterClick option: Pass a callback to the MarkerClusterer constructor. This is the recommended way for high-level logic.
    2. Via Event Listeners: The MarkerClusterer instance triggers MarkerClustererEvents.CLUSTER_CLICK on the map.

    Note: The clusterer automatically detects if it is using legacy google.maps.Marker or the newer AdvancedMarkerElement and listens for the appropriate click event (click vs gmp-click) to ensure compatibility.

    // Option 1: Constructor callback
    const clusterer = new MarkerClusterer({
      map: map,
      markers: markers,
      onClusterClick: (event, cluster, map) => {
        console.log('Cluster clicked:', cluster);
      }
    });
    
    // Option 2: Event listener
    google.maps.event.addListener(clusterer, 'click', (event, cluster, map) => {
      // Handle click
    });
  6. Basic usage of MarkerClusterer

    main

    To create a clusterer, import MarkerClusterer and instantiate it with an options object containing your map and markers. By default, it uses the supercluster algorithm and the default renderer.

    import { MarkerClusterer } from "@googlemaps/markerclusterer";
    
    // use default algorithm and renderer
    const markerCluster = new MarkerClusterer({ map, markers });
  7. Configure MarkerClustererOptions

    main

    The MarkerClustererOptions interface defines the configuration for the MarkerClusterer instance:

    • markers?: An array of Marker objects to be clustered. Defaults to an empty array.
    • algorithm?: An Algorithm implementation used to calculate clusters. Defaults to SuperClusterAlgorithm.
    • algorithmOptions?: Options passed to the clustering algorithm.
    • map?: The google.maps.Map instance to which the clusterer is attached. Can be null to initialize without a map.
    • renderer?: A Renderer object that converts a Cluster into a google.maps.Marker. Defaults to DefaultRenderer.
    • onClusterClick?: A callback function of type onClusterClickHandler triggered when a cluster is clicked.
  8. Configure SuperClusterViewportAlgorithm options

    main

    The SuperClusterViewportOptions interface allows you to configure both the viewport behavior and the underlying supercluster engine.

    Key configuration properties include:

    • maxZoom: The maximum zoom level for which clusters are generated.
    • radius: The radius of the cluster (in pixels).
    • viewportPadding: The amount of padding (in pixels) added to the viewport bounds to prevent clusters from popping in/out at the edges.
    • ...options: Any additional options supported by the supercluster, such as minZoom or extent.
  9. MarkerClusterer configuration options

    main

    The MarkerClusterer constructor accepts a single options object. This is a change from previous versions that used positional parameters.

    Available keys in the options object:

    • algorithm: An instance of Algorithm to define how markers are grouped.
    • map: The google.maps.Map instance to which clusters will be attached.
    • markers: An array of google.maps.Marker[] to be clustered.
    • renderer: An instance of Renderer to define how clusters are visually represented.
    • onClusterClick: A callback function of type onClusterClickHandler triggered when a cluster is clicked.
    {
        algorithm?: Algorithm;
        map?: google.maps.Map;
        markers?: google.maps.Marker[];
        renderer?: Renderer;
        onClusterClick?: onClusterClickHandler;
    }
  10. DefaultRenderer implementation details

    main

    The DefaultRenderer is the standard implementation used by MarkerClusterer. It features:

    • Dynamic Coloring: It changes the cluster color (red vs blue) based on whether the cluster's count exceeds the mean cluster size (or a minimum threshold of 10).
    • SVG Icons: It generates an SVG string containing concentric circles and the cluster count.
    • Advanced Marker Support: It automatically detects if google.maps.marker.AdvancedMarkerElement is available on the map. If so, it uses the SVG as the content property; otherwise, it falls back to using the SVG as a base64-encoded icon for a standard google.maps.Marker.
    // The DefaultRenderer logic uses stats.clusters.markers.mean to determine color:
    const color = count > Math.max(10, stats.clusters.markers.mean) ? "#ff0000" : "#0000ff";