Google maps with spiderfier, custom tooltips

by Emma Bishop

HTML

<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier/1.0.3/oms.min.js"></script>
<div id="map-container">
  <div id="map">
  </div>
  <h3>
    To test:
  </h3>
  <ol>
    <li>Hover over the marker "C":
      <ul>
        <li>Tooltip with "C" shows up at upper left corner of marker</li>
      </ul>
    </li>
    <li>Hover over group of markers "B" and "A" (hidden by B):
      <ul>
        <li>Nothing happens! This is expected/desired behavior</li>
      </ul>
    </li>
    <li>Click group of markers "B" and "A":
      <ul>
        <li>Markers jump apart from each other, with lines to their original locations</li>
      </ul>
    </li>
    <li>Hover over either "A" or "B", in their "spiderfied" state:
      <ul>
        <li>Current behavior: Tooltip with correct info shows up, but at the original location of the marker</li>
        <li>Desired behavior: Tooltip shows up at the current location of the marker</li>
      </ul>
    </li>
  </ol>
</div>

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  font-family: sans-serif;
  font-size: 14px;
}

#map-container{
  position: relative;
}

#map {
  height: 300px;
  width: 70%;
  display: inline-block;
}

#info{
  position: absolute;
  background-color: white;
  padding: 4px;
  border: 1px solid black;
  border-radius: 3px;
}
li{
  padding-top: 5px;
}

JavaScript

google.maps.event.addDomListener(window, 'load', initMap);

var destinations = [
  {id: 'A', location: {lat: 40.788, lng: -77}},
  {id: 'B', location: {lat: 40.787, lng: -77}},
  {id: 'C', location: {lat: 40.777, lng: -77}}
];

function initMap(){

	// create google map centered on origin
  var map = new google.maps.Map(document.getElementById('map'), {
    center: 	{lat: 40.781, lng: -77},
    zoom: 13
  });
  
  // add oms
  var oms = new OverlappingMarkerSpiderfier(map, {
    keepSpiderfied: true,
    nearbyDistance: 28,
    circleFootSeparation: 48,
    spiralFootSeparation: 50,
  } );
  
  
  for (let i = 0, l = destinations.length; i < l; i ++) {
  	// add markers
  	const destination = destinations[i];
    const marker = new google.maps.Marker({
      position: destination.location,
      label: destination.id,
      data: {
      	// add separate attribute for
        // easy access to location data later
      	location: destination.location,
      },
    });
    
    // add marker to map using OMS
    oms.addMarker(marker);
    
    
    google.maps.event.addListener(marker, 'mouseover', function mouseover() {
    	// on mousover, if the marker is NOT in a group that OMS will spiderfy
      // or has already been spiderfied, trigger info element
    	const markerNearOthers = oms.markersNearMarker(marker, true).length;
      if (marker.hasOwnProperty('_omsData') || !markerNearOthers) {
      	const markerPosition = getMarkerRelativePosition(marker, map);
        showInfo(markerPosition, destination.id)
      }
    });
    
    google.maps.event.addListener(marker, 'mouseout', function mouseout() {
    	// on mouse out, remove info element
    	hideInfo()
    })
  }
}


function project(latLng) {
  var TILE_SIZE = 256;
  var siny = Math.sin(latLng.lat * Math.PI / 180);

  // Truncating to 0.9999 effectively limits latitude to 89.189. This is
  // about a third of a tile past the edge of the world tile.
  // siny = Math.min(Math.max(siny, -1), 1);
  siny =...