I want to mimic the example at http://leafletjs.com/examples/choropleth.html using the leaflet package in R.
Without too much effort I have been able to achieve the info panel on hover by setting layerID, e.g. by ISO code, and then using input$map_shape_mouseover$id to subset according to which country's info should be displayed.
However, I am having a really tough time figuring out how to do the "highlight" effect on hover. Do you think this is possible?
My initial thought was to just add a new polygon on top with no fill and a stroke for whichever country is hovered over. But then when I remove that polygon on mouseout, the whole polygon for that country is completely gone. I realized this is because layerID's must be unique within a category, and I was trying to use the same column for layerID as the original underlying polygon layer.
Any ideas?
BTW I read through https://github.com/rstudio/leaflet/issues/55 but the discussion kind of diverged towards topojson and Joe never really mentioned what, if any, legacy interactivity was added.
+1 - I fully support this. It would make an even greater impact on the users / viewers (levelling the playing field with the vanilla js version)
+1 I would like to use this too. I wonder if the (apparently deprecated) label code could be leveraged to so something like this.
@efh0888 The "legacy interactivity" was referring to what became leafletProxy. It's only "legacy" in the sense that the legacy version of the package had it, and the newer (htmlwidgets-based) version was missing it for a while during development.
I think it'd make sense to have polygon highlighting directly supported in the API, as an additional set of arguments to perhaps pathOptions. The set of hover properties would need to include stroke, color, weight, opacity, fill, fillColor, fillOpacity, and possibly radius for circles, and possibly icon for markers.
@jcheng5 thanks for clarifying. To be honest I was just quickly scanning the post for a solution rather than reading intently.
Is that direct API solution something you foresee getting implemented in the near-ish future? If not, with the current package can you think of a way to do it that looks seamless to the user?
Unfortunately, I'm booked pretty solid until February. In the meantime probably the only work I can do on Leaflet is reviewing PR's and fixing serious bugs. If you or someone else wants to do the work, I can provide guidance as to how I think it could/should be done--shouldn't be difficult if you know JavaScript.
I don't know JS, although, maybe this will be the catalyst I need to finally dive in and learn it...
This is how we are doing it right now (hard coded): https://github.com/GeoCFLLC/leaflet/commit/3f533567237de18a1ceddae4d72c23f7a4198d51.
This PR allows for server-side hover styling: https://github.com/rstudio/leaflet/pull/163#discussion_r37238097. I need to speed up the onEachFeature loop for setting styles and make a function for multiple geojson features - something like styleFeaturesGeoJSON in addition to styleFeatureGeoJSON.
However, I think we also need a way to have an option to set a hover style (including bringToFront, fill, color, weight, and opacity) that can be handled in the client. I suspect this should be in addGeoJSON itself (and other types). It should be able to retain the previous style so you can change it back.
Chris
+1 for this feature.
And it would be nice if this also would apply for points and lines.
Also +1 for this feature. Would be awesome if it also worked for highlighting cells of rasters...
There is a way to do this using onRender, but it's not for the the faint of heart. I'll investigate if this can be done more easily.
FWIW check out the final example http://rpubs.com/bhaskarvk/proj4leaflet for how I did it with onRender.
bhaskarvk that is awesome!
any chance it can be made to work with layersControl? Right now it just works for the first map.
@dads2busy Do you have an example that I can try to make work ?
Yes, here is your example with another addPolygons and layersControl added.
You will notice that when the second layer is selected ("2013") the highlighting no longer functions.
Thanks!
library(sp)
library(albersusa)
spdf <- usa_composite()
pal <- colorNumeric(
palette = "Blues",
domain = spdf@data$pop_2014
)
pal2 <- colorNumeric(
palette = "Blues",
domain = spdf@data$pop_2013
)
bounds <- c(-125, 24 ,-75, 45)
leaflet(
options=
leafletOptions(
worldCopyJump = FALSE,
crs=leafletCRS(
crsClass="L.Proj.CRS",
code='EPSG:2163',
proj4def='+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs',
resolutions = c(65536, 32768, 16384, 8192, 4096, 2048,1024, 512, 256, 128)
))) %>%
fitBounds(bounds[1], bounds[2], bounds[3], bounds[4]) %>%
setMaxBounds(bounds[1], bounds[2], bounds[3], bounds[4]) %>%
addPolygons(data=spdf, weight = 1, color = "#000000",
fillColor=~pal(pop_2014),
fillOpacity=0.7,
label=~stringr::str_c(name,' ', pop_2014),
labelOptions= labelOptions(direction = 'auto'),
group="2014") %>%
addPolygons(data=spdf, weight = 1, color = "#000000",
fillColor=~pal2(pop_2013),
fillOpacity=0.7,
label=~stringr::str_c(name,' ', pop_2014),
labelOptions= labelOptions(direction = 'auto'),
group="2013") %>%
addLayersControl(
baseGroups=c("2014",
"2013"),
position = "topleft",
options = layersControlOptions(collapsed = FALSE)
) %>%
htmlwidgets::onRender("
function(el, t) {
var defaultStyle = {
color: '#000000',
opacity:0.5,
weight: 1,
fillOpacity: 0.7,
};
var highlightStyle = {
color: '#ff0000',
opacity:1,
weight: 3,
fillOpacity: 1,
};
var myMap = this;
var layers = myMap._layers;
for(var i in layers) {
var layer = layers[i];
// need some way to identify our polygons
// as each polygon was assigned a Label we use that
// as our selection criteria
if(layer.label) {
layer.on('mouseover',
function(e) {
this.setStyle(highlightStyle);
this.bringToFront();
});
layer.on('mouseout',
function(e) {
this.setStyle(defaultStyle);
this.bringToBack();
});
}
}
}")
@dads2busy It's just a matter of correctly selecting your polygons to apply the mouseover and mouseout effects. In a single layer case I was simply using the currently displayed polygons.
I modified the selection for your case to correctly select all the state polygons, and hey presto it works.
http://rpubs.com/bhaskarvk/polygon-highlight
Also there's a small bug in your second addPolygons call, you're adding 2013 data but label refers to 2014 :)
Given the rather detailed example I've provided, I am comfortable closing this issue. If anyone disagrees please reopen.
@bhaskarvk Terrific, works great! Thanks!
@dads2busy Now there's an even easier way to highlight polygons.
http://rpubs.com/bhaskarvk/polygon-highlight (You need to build leaflet from GH using devtools).
@bhaskarvk great work!
Is there a CRAN-version available? I would like to install this package on my R-server, but it doesn't allow me to install it from github because of proxy...
CRAN release will be handled by @jcheng5
That would be great, let us know! @bhaskarvk @jcheng5
CRAN ver 1.1 is live.
Is it possible to keep the highlighting also when hover out?
Hi All -
A better way to do this is using highlightOptions in addPolygons (?addPolygons)
highlightOptions(stroke = NULL, color = NULL, weight = NULL,
opacity = NULL, fill = NULL, fillColor = NULL, fillOpacity = NULL,
dashArray = NULL, bringToFront = NULL, sendToBack = NULL)
Example
addPolygons(stroke = T, fillOpacity = 0.5,popup = ~X, highlightOptions = highlightOptions(color = "white", weight = 2,bringToFront = TRUE))
Set bringToFront = TRUE
This works !
Most helpful comment
Hi All -
A better way to do this is using highlightOptions in addPolygons (?addPolygons)
highlightOptions(stroke = NULL, color = NULL, weight = NULL,
opacity = NULL, fill = NULL, fillColor = NULL, fillOpacity = NULL,
dashArray = NULL, bringToFront = NULL, sendToBack = NULL)
Example
addPolygons(stroke = T, fillOpacity = 0.5,popup = ~X, highlightOptions = highlightOptions(color = "white", weight = 2,bringToFront = TRUE))
Set bringToFront = TRUE
This works !