leaflet icon indicating copy to clipboard operation
leaflet copied to clipboard

maxClusterRadius: Using a function instead of a single value doesn't work

Open daattali opened this issue 2 years ago • 2 comments

I'm not a poweruser of {leaflet} so perhaps I'm doing something wrong rather than this being a bug.

There is a function markerClusterOptions() that accepts "extra options passed to underlying JavaScript object". I could not find in the function's documentation a clear answer to what those options are (again, maybe it is documented somewhere, I don't know how to navigate the {leaflet} world!), but I believe that it's referring to https://github.com/Leaflet/Leaflet.markercluster

That page claims there's a parameter called maxClusterRadius that controls how far markers need to be from each other to cluster together. According to the documentation on GitHub, this parameter accepts either a single number or a function:

maxClusterRadius: The maximum radius that a cluster will cover from the central marker (in pixels). Default 80. Decreasing will make more, smaller clusters. You can also use a function that accepts the current map zoom and returns the maximum cluster radius in pixels.

When I use this parameter with a single value, it works as expected. However, I cannot get it to work with a function. Example:

library(leaflet)

df <- data.frame(lat=c(43.6529539, 43.6533352),lng=c(-79.3794453, -79.3796324))

leaflet(df) %>% addTiles() %>% addMarkers(clusterOptions = markerClusterOptions(
  maxClusterRadius = JS(
    "function(zoom) {
      if (zoom >= 17) {
        return 500;
      } else {
        return 0;
      }
    }"
  )
))

This should only cluster when you're very zoomed in, but when you zoom out it should not cluster. If you use maxClusterRadius=0 or maxClusterRadius=JS("function(zoom) { return 0; }") then the markers will never cluster. This is evidence that the above code does not work when zooming out.

I tried doing a GitHub-wide search for uses of maxClusterRadius in R, but 100% of the results used a single value and none used a function, so I can't see if other people got it to work.

daattali avatar Jul 25 '23 21:07 daattali

I can see in the source code https://github.com/rstudio/leaflet/blob/0f8e8315c63b8348c6cc054e1964af48309b576e/inst/htmlwidgets/plugins/Leaflet.markercluster/leaflet.markercluster-src.js#L938-L940 that there is an explicit attempt to make the option work with both a value and a function, which leads me to believe that it is supposed to work, but unfortunately I can't find any examples anywhere so I can't be sure.

daattali avatar Jul 25 '23 21:07 daattali

I think I got it to work. I think the problem was with the variable zoom in the function, which should be called mapZoom. Here a code that sould work:

library(leaflet)

df <- data.frame(lat=c(43.6529539, 43.6533352),lng=c(-79.3794453, -79.3796324))

leaflet(df) %>% addTiles() %>% addMarkers(
  clusterOptions = markerClusterOptions(maxClusterRadius = 
    htmlwidgets::JS("function (mapZoom) {
      if (mapZoom > 13) {
        return 0;
      } else {
        return 70;
      }
    }"
  )))

This post pointed me into the right direction: https://stackoverflow.com/questions/64476106/change-clusterradius-depending-on-current-zoom-leaflet

I am new to commenting, I hope the format is correct.

simknu avatar Jan 31 '24 08:01 simknu