Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Not an issue] Info for React integration #55

Open
jabidof opened this issue Jan 11, 2023 · 3 comments
Open

[Not an issue] Info for React integration #55

jabidof opened this issue Jan 11, 2023 · 3 comments

Comments

@jabidof
Copy link

jabidof commented Jan 11, 2023

For any interested react-leaflet users, you can integrate this lib following way:

declare global {
  interface Window {
    OverlappingMarkerSpiderfier: any;
  }
}

interface ISpiderify {
  onClick?: (marker: L.Marker<any>) => void;
  onSpiderfy?: (markers: Marker<any>[]) => void;
  onUnspiderfy?: (markers: L.Marker<any>[]) => void;
  children?: React.ReactNode;
}
export const Spiderify = (props: ISpiderify) => {
  const map = useMap();

  const oms: any = useMemo(() => {
    const _oms =new window.OverlappingMarkerSpiderfier(map, {
      keepSpiderfied: false,
      nearbyDistance: 20, // This is the pixel radius within which a marker is considered to be overlapping a clicked marker. D=20
      circleSpiralSwitchover: Infinity, // This is the lowest number of markers that will be fanned out into a spiral instead of a circle. Set this to 0 to always get spirals, or Infinity for all circles.
      legWeight: 1.5, // This determines the thickness of the lines joining spiderfied markers to their original locations.
    });
    _oms.addListener("spiderfy", (markers: Marker[]) => {
      markers.forEach((m) => m.closePopup()); //force to close popup
      if (props.onSpiderfy) props.onSpiderfy(markers);
    });
    _oms.addListener("unspiderfy", (markers: Marker[]) => {
      if (props.onUnspiderfy) props.onUnspiderfy(markers);
    });
    _oms.addListener("click", (marker: Marker) => {
      if (props.onClick) props.onClick(marker);
    });
    return _oms;
  }, [map, props]);

  const childrenWithProps = React.Children.map(props.children, (child) => {
    // Checking isValidElement is the safe way and avoids a
    // typescript error too.
    if (React.isValidElement(child)) {
      // @ts-ignore
      return React.cloneElement(child, { oms });
    }
    return child;
  });
  return <LayerGroup>{childrenWithProps}</LayerGroup>;
};

Then in your MapContainer:

<Spiderify
  onClick={(m) => {
    console.log("click", m);
  }}
>
      {... all your <Marker /> ...}
</Spiderify>

Probably it can be improved...

@Samettkaya
Copy link

Hello, I tried this example and it didn't work for me. how can I do it

@Thomas-Martin-1998
Copy link

Anyone got something that works? I just spent all day trying to get this to work with React-Leaflet, the documentation/examples are all out of date. This is the best I've seen yet, but it doesn't work, and I have no errors to help me debug why.

@RISHIKESHk07
Copy link

@Thomas-Martin-1998 any luck on solving this problem ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants