visgl / visgl/react-google-maps

Marker icons are showing along with marker cluster

Open
#408 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
1.9k
Forks
193
Avg merge
3d 16h
Merged PRs (30d)
13

Description

Description

When loading my custom google map component, marker cluster is getting created but with that actual markers are also getting drown. Providing screenshot below:

image

Expected result: It should show only marker clusters

Also I didn't see any documentation on how can we close one marker info window programmatically, when I am opening another marker info window.

Steps to Reproduce

Below is my code:

import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { Map, Marker, InfoWindow, useMap, useMarkerRef } from '@vis.gl/react-google-maps';
import { MarkerClusterer } from '@googlemaps/markerclusterer';

export default function GoogleMaps({ markerData, defaultZoom = 4, defaultCenter = { lat: 17.3850, lng: 78.4867 }, mapHeight }) {

    const map = useMap();
    const assetClusterer = useRef(null);

    useEffect(() => {
        if (!map) return;
        if (markerData?.length) {
            const bounds = new window.google.maps.LatLngBounds();
            markerData.forEach(({ latitude, longitude }) => {
                bounds.extend({ lat: latitude, lng: longitude });
            });
            map.fitBounds(bounds);
            map.panToBounds(bounds);
        }
        if (!assetClusterer.current) {
            assetClusterer.current = new MarkerClusterer({ map });
        }
    }, [map]);

    const AssetMarkers = () => {
        const [assetMarkers, setAssetMarkers] = useState({});

        useEffect(() => {
            assetClusterer.current?.clearMarkers();
            assetClusterer.current?.addMarkers(Object.values(assetMarkers));
        }, [assetMarkers]);

        const setMarkerRef = (marker, key) => {
            if (marker && assetMarkers[key]) return;
            if (!marker && !assetMarkers[key]) return;

            setAssetMarkers(prev => {
                if (marker) {
                    return { ...prev, [key]: marker };
                } else {
                    const newMarkers = { ...prev };
                    delete newMarkers[key];
                    return newMarkers;
                }
            });
        };

        const AssetMarker = ({ point, setMarkerRef }) => {
            const [infoWindowShown, setInfoWindowShown] = useState(false);
            let [markerRef, marker] = useMarkerRef();

            const refCallback = useCallback((marker1) => {
                if (!marker1) return;
                markerRef(marker1);
                setMarkerRef(marker1, point.deviceSN);
            }, [setMarkerRef, point.deviceSN]);

            const handleAssetMarkerClick = useCallback(() => {
                setInfoWindowShown(true);
            }, []);

            const handleInfoWindowClose = useCallback(() => setInfoWindowShown(false), []);
            return (
                <>
                    <Marker
                        position={{ lat: point.latitude, lng: point.longitude }}
                        ref={refCallback}
                        onClick={handleAssetMarkerClick} />
                    {
                        infoWindowShown && <InfoWindow anchor={marker} onClose={handleInfoWindowClose}>
                            <h2>InfoWindow content!</h2>
                            <p>Some arbitrary html to be rendered into the InfoWindow.</p>
                        </InfoWindow>
                    }
                </>
            )
        }

        return (
            <>
                {
                    markerData.map((objMarker) => (
                        <AssetMarker key={objMarker.deviceSN} point={objMarker} setMarkerRef={setMarkerRef} />
                    ))
                }
            </>
        )
    }

    return (
        <Map style={{ width: '100%', height: mapHeight }} defaultZoom={defaultZoom} defaultCenter={defaultCenter} streetViewControl={false} gestureHandling="greedy">
            <AssetMarkers />
        </Map>
    )
}
Environment
  • Library version: 1.0.2
  • Google maps version: weekly
  • Browser and Version: Chrome
  • OS: Window 10
Logs

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied GoogleMaps component, especially the Marker, useMarkerRef, InfoWindow, and MarkerClusterer setup. Reproduce the example with the stated library and Google Maps versions, then verify that clustering does not leave individual markers visible and that opening another info window closes the previous one.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.