Spacing out Markers in Map Component

Currently I’m using MapboxGL as my map component. I have a group of markers clustered in the same spot, which makes it hard to see the markers. I want an algorithm that checks if there are any markers in the area of each other and automatically shifts itself to a random location but meanwhile still keeping a smaller marker in it’s original location.

Reference Image:

enter image description here

CodeSandbox: https://codesandbox.io/s/full-popup-mapbox-stackoverflow-forked-v9xgb

Currently this is my code, where I’m getting the longitude and latitude from my API and mapping it out:

const [viewport, setViewport] = useState({
    latitude: 50.826758,
    longitude: 4.380197,
    width: "100vw",
    height: "100vh",
    zoom: 1,
    scrollZoom: "false"
  });

  const [selectedProperty, setSelectedProperty] = useState(null);
  const [isPopupShown, setIsPopupShown] = useState(false);

  return (
    <div className="root">
      <div className="map">
        <ReactMapGL
          {...viewport}
          mapboxApiAccessToken={YOURMAPBOXTOKEN}
          mapStyle="mapbox://styles/mapbox/dark-v9"
          onViewportChange={(viewport) => {
            setViewport(viewport);
          }}
        >
          <HTMLOverlay
            redraw={(props) => {
              return (
                <div
                  style={{
                    backgroundColor: "rgba(255, 0, 0, 0.5)",
                    width: isPopupShown ? props.width : 0,
                    height: isPopupShown ? props.height : 0,
                    transition: "all .2s ease-in-out",
                    transform: "scale(1.1)",
                    overflow: "hidden",
                    alignItems: "center",
                    justifyContent: "center"
                  }}
                >
                  {/* todo: text/content position */}
                  <h1>Text</h1>
                </div>
              );
            }}
          />

          {posts &&
            posts.map((item) => (
              <Marker
                key={item.id}
                latitude={item.latitude}
                longitude={item.longitude}
              >
                <button className="marker-btn">
                  <Icon
                    style={{
                      width: 48,
                      height: 48
                    }}
                    onMouseEnter={() => {
                      setSelectedProperty(item);
                      setIsPopupShown(true);
                    }}
                    onMouseOut={() => {
                      setSelectedProperty(null);
                      setIsPopupShown(false);
                    }}
                    alt="Marker"
                  />
                </button>
              </Marker>
            ))}
        </ReactMapGL>

Answer

What you are trying to do is not really adapted on a dynamic map because the elements would have to be repositioned permanently on the map during a move (ouch!)

The most relevant would be to use the principle of clusters which is perfect for the concern of grouping points. https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/

With all the style options in mapbox you can easily make something graphically acceptable in the spirit of what you want to do. Here are some ideas: https://medium.com/@droushi/mapbox-cluster-icons-based-on-cluster-content-d462a5a3ad5c