1

With the markerClusterGroup leaflet plugin, calling the spiderfy function twice automatically closes the opened popup.

This seems to be due to this piece of code in the unspiderfy function, that is called automatically by the second spiderfy call.

var tiles = L.tileLayer(...);
var map = L.map(...);
var coords = Array(...);
var mcg = L.markerClusterGroup();
var markers = Array();

for (var i = 0; i < 100; i++) {
  var c = coords[i];
  var marker = L.marker(new L.LatLng(a[0], a[1]));
  markers.push(marker)
  marker.bindPopup("Point " + i);
  mcg.addLayer(marker);
}

function openPoint(i) {
    var marker = markers[i];
     var cluster = mcg.getVisibleParent(marker);
    if(cluster && cluster.spiderfy) {
        cluster.spiderfy();
    }
}

map.addLayer(mcg);

var x = ...;
var y = ...;
openPoint(x)            // Spiderfies the point x
markers[x].openPopup(); // Opens the popup for the point x
openPoint(y)            // Spiderfies the point y, and sadly closes the previous popup

Here is a fiddle that illustrates the behavior I describe. Just click on buttons to spiderfy groups of items. Open a popup. And then click on another button to spiderfy another group of items. And see that the popup is closing.

How can I prevent this behavior?

0
2

There are two ways to achieve the behavior you want. One is to edit Leaflet.markercluster plugin code.

The other way is to reopen popup after it's undesirably closed. Drawback of this method is that popup blinks and the whole method is a bit hackish, but it can be done relatively simply.

That's how it goes:

  1. With the help of clustermouseover and clustermouseout event processing it's checked on popupclose event if popup was closed because of spiderfy event. If yes, popup is reopened.
  2. With the help of unspiderfied event, popup is opened which was closed during this action.

Relevant code could then look something like this (tested, but not very thoroughly, so there might still be some logic missing):

var reopenPopup = false;
var closedPopup = null;

var mcg = L.markerClusterGroup();
var markers = Array();

function onClick(evt) {
    var marker = markers[evt.target.dataset.markerid];
    var cluster = mcg.getVisibleParent(marker);
    if(cluster && cluster.spiderfy) {
      reopenPopup = true;
      cluster.spiderfy();
      reopenPopup = false;
    }
}

for (var i = 0; i < 100; i++) {
  var a = addressPoints[i];
  var title = a[2];
  var marker = L.marker(new L.LatLng(a[0], a[1]), { title: title });
  markers.push(marker)
  marker.bindPopup(title);
  marker.on('popupclose', function(evt) {
    closedPopup = evt.target;
    if (reopenPopup) {
      setTimeout(function() {
        closedPopup.openPopup();
        closedPopup = null;
      }, 0);
      }
    else {
      setTimeout(function() {
        closedPopup = null;
      }, 500);
    }
  });
  mcg.addLayer(marker);
  
  var button = document.createElement("button");
  var content = document.createTextNode(i);
  button.appendChild(content);
  document.getElementById("buttons").appendChild(button);
  button.addEventListener("click", onClick);
  button.dataset.markerid = i;
}

map.addLayer(mcg);

mcg.on('clustermouseover', function(evt) {
  reopenPopup = true;
});
mcg.on('clustermouseout', function(evt) {
  reopenPopup = false;
});
mcg.on('unspiderfied', function(evt) {
  if (closedPopup) {
    closedPopup.openPopup();
    closedPopup = null;
  }
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.