label on markerClusterOptions

Hi there,

I have a problem for which I can't find an existing solution.

When I create my map leaflet, I gather my markers in "clusters pie markers" using a function in Javascript, however I am not too comfortable with this language...

I would like, in the same way that when I switch to a marker I see its "label", I would like to have a label when I switch to the markerCluster. It is possible to display the area shown under this markerCluster, so is it possible to add a label when I pass over it?

cluster label NO label marker

Thank's for the help,

1 Like

I don't have answer for this, but I would be curious about its feasiblity - the leaflet clusters are created dynamically depending on zoom level and distance between points, so creating a cluster with a specific label might be challenging.

1 Like

Indeed, in the same way I can't manage cluster markers with my own polygons, which would be a big step forward as well.

I know that the dynamic management according to the zoom can be a problem but having these own polygons as a cluster and moreover to put a label, dynamic too, on it would be great.

if you could provide a good reprex then that would encourage forum users to play with it and look for solutions

I'm not used to "reprex", but here is the code needed to display a slight example of what I'm doing right now.

if (!require("leaflet")) {
  install.packages("leaflet")
  library('leaflet')
}
if (!require("mapview")) {
  install.packages("mapview")
  library(mapview)
}
if (!require("htmlwidgets")) {
  install.packages("htmlwidgets")
  library(htmlwidgets)
}
if (!require("shinycssloaders")) {
  install.packages("shinycssloaders")
  library(shinycssloaders)
}
if (!require("dplyr")) {
  install.packages("dplyr")
  library(dplyr)
}
if (!require("rgdal")) {
  install.packages("rgdal")
  library(rgdal)
  library(sp)
}
if (!require("rjson")) {
  install.packages("rjson")
  library(rjson)
}
if (!require("leaflet.extras")) {
  install.packages("leaflet.extras")
  library(leaflet.extras)
}
library(magrittr)
library(leaflet.minicharts)



data = data.frame(
  stringsAsFactors = FALSE,
  CODE_POSTAL = c("77230","39300",
                             "74000","75008","75008","78110","94300","77230",
                             "26000","92300","64200","69600","77580",
                             "31470","61000","78160","60240","33850","83510",
                             "94320","82000","75001","94700","44100","56300",
                             "94400","91240","14790","14100","06000",
                             "91360","42300","45300","78250","51100","66000",
                             "34000","49100","35000","93330","08000","45000",
                             "42000","13004","13600","77400","92110",
                             "17000","78440","35200","69670","74000","21121",
                             "69170","74150","69100","93100","69630","95600",
                             "74000","78200","17137","94100","34730",
                             "34000","61100","26250","94260","86000","75006",
                             "07200","64100","35000","14000","64100","47300",
                             "84100","81150","75015","94270","75006",
                             "77100","75007","81200","92200","75012","84000",
                             "92300","75012","93230","67100","09700","14000",
                             "91210","38000","31170","13100","74160",
                             "78600","75009"),
  VILLE = c("Longperrier",
                       "Champagnole","Annecy","Paris","Paris","Le Vesinet",
                       "Vincennes","Longperrier","Valence",
                       "Levallois-Perret","Biarritz","Oullins",
                       "Crecy-la-Chapelle","Fontenilles","Alencon","Marly-le-Roi",
                       "Chambors","Leognan","Lorgues","Thiais","Montauban",
                       "Paris","Maisons-Alfort","Nantes","Pontivy",
                       "Vitry-sur-Seine","Saint-Michel-sur-Orge","Mouen",
                       "Lisieux","Nice","Villemoisson-sur-Orge","Roanne",
                       "Pithiviers","Oinville-sur-Montcient","Reims",
                       "Perpignan","Montpellier","Angers","Rennes",
                       "Neuilly-sur-Marne","Charleville-Mezieres","Orleans",
                       "Saint-etienne","Marseille","La Ciotat",
                       "Lagny-sur-Marne","Clichy","La Rochelle","Gargenville",
                       "Rennes","Vaugneray","Annecy","Ahuy","Tarare",
                       "Rumilly","Villeurbanne","Montreuil",
                       "Chaponost","Eaubonne","Annecy","Mantes-la-Jolie",
                       "Nieul-sur-Mer","Saint-Maur-des-Fosses","Prades-le-Lez",
                       "Montpellier","Flers","Livron-sur-Drome",
                       "Fresnes","Poitiers","Paris","Aubenas","Bayonne",
                       "Rennes","Caen","Bayonne","Villeneuve-sur-Lot",
                       "Orange","Marssac-sur-Tarn","Paris",
                       "Le Kremlin-Bicetre","Paris","Meaux","Paris","Mazamet",
                       "Neuilly-sur-Seine","Paris","Avignon",
                       "Levallois-Perret","Paris","Romainville","Strasbourg",
                       "Saverdun","Caen","Draveil","Grenoble","Tournefeuille",
                       "Aix-en-Provence","Saint-Julien-en-Genevois",
                       "Le Mesnil-le-Roi","Paris"),
  LATITUDE = c(49.0522448,
                          46.7419812,45.9054701,48.8675989,48.8755583,48.8927192,
                          48.8484083,49.0522448,44.9382697,48.8935695,
                          43.461605,45.7195969,48.8579393,43.555608,
                          48.4299352,48.8792785,49.2600267,44.7350324,
                          43.4909725,48.7639583,43.968911,48.8592023,48.8027976,
                          47.2143905,48.0578063,48.7864262,48.6383631,
                          49.15544,49.1510989,43.7123322,48.6658245,
                          46.0362348,48.1678236,49.0292366,49.2516412,42.7012181,
                          43.6080974,47.4684495,48.1061923,48.8591079,
                          49.7459409,47.9085658,45.438269,43.3022002,
                          43.2718758,48.8790051,48.9104278,46.1600723,48.9883223,
                          48.0949327,45.7362585,45.9000264,47.3693899,
                          45.8955555,45.862103,45.7689076,48.8558404,
                          45.71051,48.9821211,45.9116932,48.9956541,46.2057515,
                          48.8027129,43.6957682,43.6080974,48.7461972,
                          44.7737893,48.7577047,46.5727859,48.8463686,
                          44.6151489,43.4843876,48.097474,49.1799581,
                          43.492541,44.4066697,44.1362932,43.915303,48.8429089,
                          48.810136,48.8517022,48.9613215,48.8550362,
                          43.4935543,48.8823077,48.8458331,43.9499561,
                          48.8911236,48.8289399,48.8805575,48.5637589,43.2368825,
                          49.1771453,48.6853042,45.1909071,43.5865127,
                          43.5299177,46.141418,48.9380481,48.8749936),
  LONGITUDE = c(2.6639454,
                           5.9205601,6.1280876,2.3418852,2.3154132,2.1348924,
                           2.4333743,2.6639454,4.8994988,2.2863555,-1.539059,
                           4.8015186,2.9136219,1.193089,0.082261,2.0904479,
                           1.8168806,-0.5979998,6.3598357,2.3900864,
                           1.4118247,2.3472261,2.4284366,-1.5860529,-2.9601083,
                           2.3929347,2.3162689,-0.4518532,0.2274898,
                           7.2617484,2.3379109,4.0731401,2.2531562,1.853266,
                           4.0426445,2.8950323,3.889393,-0.5581599,
                           -1.677962,2.5269598,4.723618,1.9119427,4.391821,
                           5.3944497,5.3914207,2.7084773,2.3086692,-1.1558429,
                           1.8125452,-1.6526906,4.671988,6.1224505,
                           5.0208288,4.4307141,5.9474293,4.8777018,2.4397387,
                           4.742831,2.2851008,6.1318765,1.7357577,-1.1642772,
                           2.4914111,3.8626888,3.889393,-0.5746574,
                           4.8411644,2.3198117,0.327439,2.3179856,4.3934242,
                           -1.5489234,-1.685923,-0.356745,-1.4716018,0.7089464,
                           4.8014218,2.027285,2.2938111,2.3606769,
                           2.3337244,2.8957304,2.3040394,2.3754899,2.2709241,
                           2.3781456,4.8051698,2.2878682,2.3073866,2.4366732,
                           7.7580486,1.5752686,-0.3577968,2.3961792,
                           5.7303273,1.3411846,5.4441972,6.07927,2.1261346,
                           2.3268606),
  statut = as.factor(c("type_1_oui",
                       "type_1_oui",
                       "type_1_oui","type_1_oui",
                       "type_1_oui",
                       "type_1_oui","type_1_oui",
                       "type_1_oui",
                       "type_1_oui","type_1_oui",
                       "type_1_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui","type_2_oui",
                       "type_2_oui",
                       "type_1_oui","type_1_oui",
                       "type_1_oui",
                       "type_1_oui","type_1_oui",
                       "type_1_non",
                       "type_1_non","type_1_non",
                       "type_1_non",
                       "type_1_non","type_1_non",
                       "type_1_non",
                       "type_2_non","type_2_non",
                       "type_2_non",
                       "type_2_non","type_1_non",
                       "type_2_non","type_2_non",
                       "type_2_non",
                       "type_2_non","type_2_non",
                       "type_2_non",
                       "type_2_non","type_2_non",
                       "type_2_non","type_2_non",
                       "type_2_non",
                       "type_2_non","type_2_non"))
)

x_y = data[,c(3,4)]

spdf <- SpatialPointsDataFrame(coords = x_y, data = data,
                               proj4string = CRS("+proj=longlat +ellps=GRS80"))

joliepalette<-c("red","green","blue","orange")[1:nlevels(spdf$statut)]
getColor <- function(spdf) {joliepalette[spdf$statut]}

icons <- awesomeIcons(
  icon = 'user-md',
  library = 'fa',
  markerColor = getColor(spdf),
  iconColor = getColor(spdf)
)


tag.map.title <- tags$style(HTML('.leaflet-control.map-title {transform: translate(-50%,20%);position: fixed !important;
                                         left: 50%;text-align: center;padding-left: 10px;padding-right: 10px;
                                         background-color: rgb(186,221,190);font-weight: bold;font-size: 13px;}'))


title <- tags$div(tag.map.title, HTML('Example') )

html_legend <- "<div class='marker-cluster'> Ville / Code postal</div><span>"

icons <- awesomeIcons(
  library = "fa",
  markerColor = getColor(spdf),
  iconColor = "black",
  text = getNumber(spdf)
)

#Generate the javascript
#####
jsscript3<-
  paste0(
    "function(cluster) {
const groups= [",paste("'",levels(spdf$statut),"'",sep="",collapse=","),"];
const colors= {
groups: [",paste("'",joliepalette,"'",sep="",collapse=","),"],
center:'#ddd',
text:'black'
};
const markers= cluster.getAllChildMarkers();

const proportions= groups.map(group => markers.filter(marker => marker.options.group === group).length / markers.length);
function sum(arr, first= 0, last) {
return arr.slice(first, last).reduce((total, curr) => total+curr, 0);
}const cumulativeProportions= proportions.map((val, i, arr) => sum(arr, 0, i+1));
cumulativeProportions.unshift(0);

const width = 2*Math.sqrt(markers.length);
const radius= 15+width/2;

const arcs= cumulativeProportions.map((prop, i) => { return {
x   :  radius*Math.sin(2*Math.PI*prop),
y   : -radius*Math.cos(2*Math.PI*prop),
long: proportions[i-1] >.5 ? 1 : 0
}});
const paths= proportions.map((prop, i) => {
if (prop === 0) return '';
else if (prop === 1) return `<circle cx='0' cy='0' r='${radius}' fill='none' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`;
else return `<path d='M ${arcs[i].x} ${arcs[i].y} A ${radius} ${radius} 0 ${arcs[i+1].long} 1 ${arcs[i+1].x} ${arcs[i+1].y}' fill='none' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`
});

return new L.DivIcon({
html: `

<svg width='60' height='60' viewBox='-30 -30 60 60' style='width: 60px; height: 60px; position: relative; top: -24px; left: -24px;' >
<circle cx='0' cy='0' r='15' stroke='none' fill='${colors.center}' />
<text x='0' y='0' dominant-baseline='central' text-anchor='middle' fill='${colors.text}' font-size='15'>${markers.length}</text>
${paths.join('')}
</svg>
`,
className: 'marker-cluster'
});
}")
#####

map <- leaflet(spdf) %>%
  setMaxBounds(lng2 = 9.51,lat2 = 41.43,lng1 = -5.210,lat1 =51.13) %>%
  addTiles(options = tileOptions(minZoom = 6)) %>%
  setView(lat = 46.855269,lng = 2.621832,zoom = 6) %>%
  addAwesomeMarkers(data=spdf,lng = spdf$LONGITUDE,lat = spdf$LATITUDE,
                    group=~statut,
                    icon = icons,
                    label = paste(spdf$CODE_POSTAL,' ',spdf$VILLE),
                    clusterOptions = markerClusterOptions(
                      iconCreateFunction =
                        JS(jsscript3))) %>%
  
  addLegend("bottomright",colors =  joliepalette,labels =c('type_2_oui','type_1_oui',
                                                           'type_2_non','type_1_non'),opacity = 1) %>%
  addControl(html_legend,"bottomleft") %>%
  addControl(
    title,
    position = "topright",
    className = "map-title"
  ) %>% 
  
  addEasyButton(easyButton(
    icon="fa-crosshairs", title="Locate Me",
    onClick=JS("function(btn, map){ map.locate({setView: true}); }"))) %>%
  addScaleBar(position = "bottomleft",options = scaleBarOptions(imperial = FALSE)) %>%
  # addControl(searchLayer)
  addSearchOSM(options = searchOptions(zoom = 10)) %>%
  onRender("function(el, x) {
        $('input.search-input')[0].placeholder = 'Code postal - Ville'
        }")

map

Regarding the method to use my own polygons, I have some predefined polygons, but I don't know how to make examples to illustrate what I'm talking about.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.