I am trying to get finer control of leaflet popups in R, using the leaflet package. The code for a MWE is below:
library(dplyr)
library(magrittr)
library(leaflet)
download.file(
url = "http://biogeo.ucdavis.edu/data/gadm2.8/rds/GBR_adm1.rds",
destfile = "GBR_adm1.rds",
method = "curl"
)
shp_gbr <- readRDS("GBR_adm1.rds")
# get centroids for placing popups in second map
shp_gbr_centers <-
rgeos::gCentroid(shp_gbr, byid = TRUE) %>%
sp::SpatialPointsDataFrame(shp_gbr#data, match.ID = FALSE)
shp_gbr#data %<>%
left_join(shp_gbr_centers[1], by = 'OBJECTID', copy = TRUE) %>%
rename(lat = y, lng = x) %>%
select(NAME_1, lat, lng) %>%
mutate(text = ProgGUIinR::LoremIpsum)
popup <- paste("<b><h3>", shp_gbr$NAME_1, "</h3></b>", shp_gbr$text)
shp_gbr %>%
leaflet() %>%
addPolygons(popup = ~popup)
This gives a nice map with popups that appear on clicking within the areas of the 4 countries, but in this case, the text is too much for the popup to handle nicely:
What I would like is to access some of the popupOptions available via the addPopups function, in this case to make the popup wider and have a scroll bar. An example of this is below:
shp_gbr %>%
leaflet() %>%
addPolygons() %>%
addPopups(
data = shp_gbr#data,
popup = ~popup,
options =
popupOptions(
maxWidth = 600,
maxHeight = 100
)
)
However, the popups are now set to be open on launch, rather than appearing on clicking within the boundaries, and do not reopen on click once closed:
My question is how to combine these elements so that you could have, say, a scroll bar for too much text within a map such as the first example, where the popups are closed by default but open on click.
You could use this function to create your popup:
popup <- paste("<div class='leaflet-popup-scrolled' style='max-width:600px;max-height:100px'><b><h3>", shp_gbr$NAME_1, "</h3></b>", shp_gbr$text,"</div>")
It wraps the popup in a div with the leaflet-popup-scrolled class to add the scroll bar and inline CSS to set the max-width and max-height.
Related
I'm making a leaflet map with popups. The popups give information of the ID of the polygon being selected. The problem I have is that the name of the field use for ID can change, so the way I was originally doing doesn't work anymore.
Here is a reproducible example:
## preparing the RE:
library(maps); library(sf); library(leaflet); library(htmltools)
w = st_as_sf(map('world', plot = FALSE, fill = TRUE))
What I use to do is prepare a html string to display:
text <- paste0("<b>ID %s</b>")
Then call the leaflet and populating the popups with sprintf and htmlEscape
leaflet(data=w) %>% addTiles() %>%
addPolygons(
popup = ~sprintf(
text,
htmlEscape(ID)
)
)
This works great :
However, the field isn't always called ID, but the name is known and in a r object (here called vari):
colnames(w) <- c("geometry", "country")
vari <- "country"
text <- paste0("<b>", vari, " %s</b>")
leaflet(data=w) %>% addTiles() %>%
addPolygons(
popup = ~sprintf(
text,
htmlEscape(vari)
)
)
This doesn't work:
I've tried using as.name so it would be considered as a symbol but it doesn't work:
vari <- as.name("country")
text <- paste0("<b>", vari, " %s</b>")
leaflet(data=w) %>% addTiles() %>%
addPolygons(
popup = ~sprintf(
text,
htmlEscape(vari)
)
)
Error in sprintf(text, htmlEscape(vari)) :
invalid type of argument[1]: 'symbol'
Any idea how to fix that? BTW, my HTML is more complex than in my example (uses more variables, however, all other variable names are fixed, only the ID field change).
I'm not sure if this is what you're after, but it sounds like you want to be able to simply populate any popup with the data from a column that doesn't necessarily have the name ID, but is simply an identifier agnostic of title? So in this case country? I fear this is an ugly cheat, but given your data structure contains a data.frame where the coords are actually a list structure, i simply test the dataframe columns for class, whichever is a character, use that as the index and directly call
leaflet(data=w) %>% addTiles() %>%
addPolygons(
popup = ~sprintf('<b>ID %s</b>', w[[names(which(mapply(is.character, w)))]])
)
I have a leaflet map which I created in R and I would like to add a dropdown filter based on fields in a column. The code looks straightforward in JS, see example here Leaflet dropdown filter, however I can't figure out how to adjust the code for R.
library(leaflet.extras)
n = c(2, 3, 5)
long = c(102.1,102.13,102.2)
lat = c(55,55.1,55.15)
select_cols= c("a","b","c")
df = data.frame(n, long, lat,select_cols)
pal <- colorFactor(c("navy", "red","green"), domain = c("a","b","c"))
leaflet(df)%>% addTiles()%>%
addCircleMarkers(lng = long,lat=lat,radius= ~n*2,
color=~pal(select_cols),stroke=F,fillOpacity = 1)
Here is the JS code that adds a dropdown filter.
var legend = L.control({position: 'topright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend');
div.innerHTML = '<select><option>1</option><option>2</option>
<option>3</option></select>';
div.firstChild.onmousedown = div.firstChild.ondblclick =
L.DomEvent.stopPropagation;
return div;
};
legend.addTo(map);
I know how to add the "show hide layers" feature, however I have over 20 different fields and I think it would be easier if the user could select the associated field using a drop down box.
In case anyone is looking for something similar, I found a solution using crosstalk. See the code below for an example.
library(crosstalk)
library(tidyverse)
library(leaflet.extras)
quakes <- quakes %>%
dplyr::mutate(mag.level = cut(mag,c(3,4,5,6),
labels = c('3.01-4.00', '4.01-5.00', '5.01-6.00')))
quakes_sd<- SharedData$new(quakes)
map<- leaflet(quakes_sd)%>%addProviderTiles(providers$Esri.WorldTopoMap)%>% addCircles()
#add filter
bscols(
filter_select("Magnitude Level", "Magnitude Level", quakes_sd, ~mag.level)
)
bscols(map)
Using leaflet in shiny to make an interactive map. Pulling data for popups from a CSV:
Row on CSV:
Name lat lng
Tufts 42.349598 -71.063541
Code on R for markers:
m %>% addMarkers(~lng, ~lat, icon = custommarker1 popup = ~htmlEscape(Name))
This returns marker in correct spot with popup displaying 'tufts'
Wondering if there is a way to encode a hyperlink into the popup directly in the CSV?Oor to put plain text as a new CSV column and have R/Shiny then turn it into a hyperlink.
Very new to shiny/leaflet and would appreciate any help!
Just include the link in the popup as html:
output$mymap <- renderLeaflet({
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup= ' R ')
m # Print the map
})
You can set the popup equal to a column in your dataframe as well. If your dataframe was called df and it contained longitude = long, latitude= lat, and urls = link :
output$mymap <- renderLeaflet({
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=df$long, lat=df$lat, popup= df$link)
m # Print the map
})
If you want the link to be a hyperlink, I have used this
popup = ~paste("", "click here", "")
provided your data has a column called link where the urls are.
Any solution/help about writing r shiny leaflet |popup|.
Thinks
I am trying to put some informations into my R shiny leaflet tool, and I got a problem to write something like that:
popup = paste(data$url,data$nom)
The problem is that in the code the data$url is a website, and I want to render it like a link?
and when I try making with the ~symbol I got error messages ...
leaflet() %>%
addTiles(
urlTemplate = "//{s}.tiles.mapbox.com/v3/jcheng.map-5ebohr46/{z}/{x}/{y}.png",
attribution = 'Maps by Mapbox'
) %>%
setView(lng = LONG, lat = LAT , zoom = ZOOM)%>%
addMarkers(data,lng=data$Longitude,lat=data$Latitude,
popup = paste(data$url,data$nom)
) %>%
You can use html tags for that. Just change your popup to the following:
popup = paste("",data$url,"",data$nom)
I would like to control the width of a leaflet-feature popup via R, how can I do that?
output$HomeMap <- renderLeaflet(leaflet() %>%
addTiles() %>%
setView(1.93, 41.48, zoom = 3) %>%
addPolygons(data = subset(world, name %in% datasourceInput()),
color = datasourceColor(),
weight = 1,
popup = datasourcePopups()
))
I do not understand how to control the options associated to the popup..
Many thanks in advance for your help on this issue and best regards!
I had a similar issue in creating the series of maps that I am working on right now. Any formatting that I would want to be done on the html/css/javascripted page, is made inside quotations, I used double quotes example: "<br>" to create a line break and start the next piece of information on the next line.
To give order to it, I used a set of tables...I had 16 rows with text and wanted to use the last row for a png image. It worked, but the image made the text scale off the side of the popup above...the background did not scale with it.
So I did some playing around with the code, scoured the net, and then inserted this line of code at the very top of my popup variable:
myPopUp<- paste("<style> div.leaflet-popup-content {width:auto !important;}</style>",
myvariable, "some copy to print", another variable)
Making sure the entire popup is inside of the paste function and now the popup automatically adjusts to the size of the content. This does mean that you need to pay attention to your copy length and appropriately size any images in your popups.
I have mine set up to pull 16 values and a graph from one of 292 census tracts and drop in the right data and cached images, then re-scale and it is working flawlessly. You might want to give it a try.
this is the magic code: "<style> div.leaflet-popup-content {width:auto !important;}</style>"
This is how it looks
Now if only I could make the popup anchor somewhere that I approved of consistently!
#bethanyP's answer will work in all cases. I thought some additional detail might be helpful. I commented inline to explain each step.
library(leaflet)
# example from https://rstudio.github.io/leaflet/popups.html
content <- paste(sep = "<br/>",
"<b><a href='http://www.samurainoodle.com'>Samurai Noodle</a></b>",
"606 5th Ave. S",
"Seattle, WA 98138"
)
leaflet() %>% addTiles() %>%
addPopups(-122.327298, 47.597131, content,
options = popupOptions(closeButton = FALSE)
)
# according to ?popupOptions can specify min/maxWidth
# set min and max width the to force a width
leaflet() %>% addTiles() %>%
addPopups(
-122.327298, 47.597131,
content,
options = popupOptions(
closeButton = FALSE,
minWidth = 300,
maxWidth = 300
)
)
# on the other hand, it appears that we only have maxHeight
# so height cannot be controlled in the same way
leaflet() %>% addTiles() %>%
addPopups(
-122.327298, 47.597131,
content,
options = popupOptions(
closeButton = FALSE,
maxHeight = 20
)
)
# let's extend the example to show how we can use
# htmltools to add CSS to control our popups
# could also use the approach suggested in
# the other answer, but I think this is more
# fitting with typical HTML/JS convention
lf <- leaflet() %>% addTiles() %>%
addPopups(
-122.327298, 47.597131,
content,
options = popupOptions(
closeButton = FALSE,
# not necessary but adding a className
# can help in terms of specificity
# especially if you have multiple popups
# with different styling
className = "myspecial-popup"
)
)
library(htmltools)
browsable(
tagList(
tags$head(
# more specific is better
tags$style(
'div.myspecial-popup div.leaflet-popup-content-wrapper {
height: 400px;
opacity: .5;
}'
)
),
lf
)
)