23

My leaflet map looks something like this:

library(sp)
library(leaflet)
circleFun <- function(center = c(0,0),diameter = 1, npoints = 100){
  r = diameter / 2
  tt <- seq(0,2*pi,length.out = npoints)
  xx <- center[1] + r * cos(tt)
  yy <- center[2] + r * sin(tt)
  Sr1 = Polygon(cbind(xx, yy))
  Srs1 = Polygons(list(Sr1), "s1")
  SpP = SpatialPolygons(list(Srs1), 1:1)
  return(SpP)
}
Circle.Town <- circleFun(c(1,-1),2.3,npoints = 100)

df1 <- data.frame(long=c(0.6,1,1.4), lat=c(-2, -.8, -0.2), other=c('a', 'b', 'c'), VAM=c(10,8,6), 
                  type=c('Public', 'Public', 'Private'), id=c(1:3)) %>% 
  mutate(X=paste0('<strong>id: </strong>', 
                  id,
                  '<br><strong>type</strong>: ',
                  type,
                  '<br><strong>VAM</strong>: ',
                  VAM))

# Create a continuous palette function
pal <- colorNumeric(
  palette = "RdYlBu",
  domain = df1$VAM
)

leaflet(height = "400px") %>% 
  addTiles() %>%
  addPolygons(data = Circle.Town, color = 'green',  fillOpacity = .7) %>%
  addCircleMarkers(data = df1, lat = ~lat, lng =~long, 
                   radius = ~VAM, popup = ~as.character(X), 
                   fillColor = ~pal(VAM),
                   stroke = FALSE, fillOpacity = 0.8,
                   clusterOptions = markerClusterOptions()) %>% 
  addLegend(position = "topright",
            pal = pal, values = df1$VAM,
            title = "VAM",
            opacity = 1
  ) %>% 
  setView(lng = 1, lat = -1, zoom = 8)

Right now, I get a popup when I click one of the circles. Is it possible to get the information when I hover the mouse instead of click? Ideally, I would like something like this.

Thanks!

MLavoie
  • 9,671
  • 41
  • 36
  • 56
Ignacio
  • 7,646
  • 16
  • 60
  • 113

2 Answers2

13

This may have been added to the leaflet package since this question was posed a year ago, but this can be done via the label argument. I am using leaflet R package version 1.1.0.

Read the data in as above:

library(sp)
library(leaflet)
library(dplyr)

circleFun <- function(center = c(0,0),diameter = 1, npoints = 100){
  r = diameter / 2
  tt <- seq(0,2*pi,length.out = npoints)
  xx <- center[1] + r * cos(tt)
  yy <- center[2] + r * sin(tt)
  Sr1 = Polygon(cbind(xx, yy))
  Srs1 = Polygons(list(Sr1), "s1")
  SpP = SpatialPolygons(list(Srs1), 1:1)
  return(SpP)
}
Circle.Town <- circleFun(c(1,-1),2.3,npoints = 100)

df1 <- data.frame(long=c(0.6,1,1.4), lat=c(-2, -.8, -0.2), other=c('a', 'b', 'c'), VAM=c(10,8,6), 
  type=c('Public', 'Public', 'Private'), id=c(1:3)) %>% 
  mutate(X=paste0('<strong>id: </strong>', 
    id,
    '<br><strong>type</strong>: ',
    type,
    '<br><strong>VAM</strong>: ',
    VAM))

# Create a continuous palette function
pal <- colorNumeric(
  palette = "RdYlBu",
  domain = df1$VAM
)

But create a list of labels instead of vector:

labs <- as.list(df1$X)

And then lapply the HTML function over that list within the label argument. Note to use label instead of popup.

library(htmltools)
leaflet(height = "400px") %>% 
  addTiles() %>%
  addPolygons(data = Circle.Town, color = 'green',  fillOpacity = .7) %>%
  addCircleMarkers(data = df1, lat = ~lat, lng =~long, 
    radius = ~VAM, label = lapply(labs, HTML), 
    fillColor = ~pal(VAM),
    stroke = FALSE, fillOpacity = 0.8,
    clusterOptions = markerClusterOptions()) %>% 
  addLegend(position = "topright",
    pal = pal, values = df1$VAM,
    title = "VAM",
    opacity = 1
  ) %>% 
  setView(lng = 1, lat = -1, zoom = 8)

This method is described in an an answer to this SO question: R and Leaflet: How to arrange label text across multiple lines

There is more info on HTML in labels in leaflet documentation: https://rstudio.github.io/leaflet/popups.html

Chris Holbrook
  • 2,531
  • 1
  • 17
  • 30
1

Here is an alternative:

library(leaflet)
library(htmltools)
library(htmlwidgets)

yourmap <- leaflet(height = "400px") %>% 
  addTiles() %>%
  addPolygons(data = Circle.Town, color = 'green',  fillOpacity = .7) %>%
  addCircleMarkers(data = df1, lat = ~lat, lng =~long, 
                   radius = ~VAM, popup = ~as.character(X), 
                   fillColor = ~pal(VAM),
                   stroke = FALSE, fillOpacity = 0.8,
                   clusterOptions = markerClusterOptions()) %>% 
  addLegend(position = "topright",
            pal = pal, values = df1$VAM,
            title = "VAM",
            opacity = 1
  ) %>% 
  setView(lng = 1, lat = -1, zoom = 8)

setwd("~/Desktop/")
saveWidget(yourmap, file="yourmap.html")

In your desktop, you will have an html and a folder saved under yourmap. Open the leaflet.js file located in /pathTo/yourmap_files/leaflet-binding-1.0.1.9002. In leaflet.js, scroll down to var popup = df.get(i, 'popup'); and paste just below:

          marker.on('mouseover', function (e) {
    this.openPopup();
});
marker.on('mouseout', function (e) {
    this.closePopup();
});

Save and reopen yourmap.html file. Hover on one of your point!!

MLavoie
  • 9,671
  • 41
  • 36
  • 56
  • I tried this solution with my Leaflet map and don't get a folder of "yourmap" when I use the saveWidget function. All I get is the .html file. When I open this in Brackets (my text editor of choice), `var popup = ...` is not present. Any suggestions? – Lauren Sep 20 '16 at 21:14
  • @Lauren, I am sorry but I don't have access to my R codes; I don't have a computer anymore! But when you click on the html file, do you have your leaflet map? When you run the code, do you have any warnings? – MLavoie Sep 21 '16 at 08:24
  • Yes, my map does come up when I click on the .html file. If I open it with my text editor, there are a few super long (seemingly) gibberish strings, a ton of coordinates, then what appears to be popup info. With my relatively limited experience working with Leaflet within Javascript, I don't really recognize the syntax as JS. No warnings when I open it! – Lauren Sep 21 '16 at 14:47
  • @Lauren. I don't know if you fixed your problem, but I just rerun the code on my new computer and it worked. – MLavoie Oct 05 '16 at 16:39
  • I believe I found the issue! In the `saveWidget` function, I had to set the parameter 'selfcontained' to false in order to access the JS file. Now to try the solution again! – Lauren Oct 18 '16 at 16:14