I've added the leaflet TextPath plugin to a shiny app in analogy to this example. This works pretty well:
output$fullscreen_map <- renderLeaflet({
points <- points_reactive()
points %>%
leaflet() %>%
addTiles() %>%
fitBounds(~min(lon), ~min(lat), ~max(lon), ~max(lat)) %>%
registerPlugin(textPathPlugin) %>%
onRender("function(el, x, data) {
data = HTMLWidgets.dataframeToD3(data);
data = data.map(function(val) { return [val.lat, val.lon]; });
var layer = L.polyline(data);
layer.on('mouseover', function () {
this.setText(' ► ', {repeat: true, attributes: {fill: 'blue'}});
});
layer.on('mouseout', function () {
this.setText(null);
});
layer.addTo(this);
}", data = points)
})
In accordance with the docs I would now like to use leafletProxy()
so that the entire map doesn't get redrawn whenever the reactive data source changes. Alas, using the following snippet of code
leafletProxy("fullscreen_map", data = points) %>%
onRender("function(el, x, data) {
data = HTMLWidgets.dataframeToD3(data);
data = data.map(function(val) { return [val.lat, val.lon]; });
var layer = L.polyline(data);
layer.on('mouseover', function () {
this.setText(' ► ', {repeat: true, attributes: {fill: 'blue'}});
});
layer.on('mouseout', function () {
this.setText(null);
});
layer.addTo(this);
}", data = points)
does not work as intended. I assume this is because onRender
is only called when a new render occurs and the whole point of leafletProxy
is to not re-render? If this is correct, is there a way to do this using other methods?
It could be something like below, although there would be more cleaner methods.
What I did was to use leafletProxy to add polylines layer from points_reactive()
function, while setting group to be reactive
. I used listened to layeradd
event of map, and if a layer with reactive
group got added, i added the textPath.
output$fullscreen_map <- renderLeaflet({
points <- points_reactive()
points %>%
leaflet() %>%
addTiles() %>%
fitBounds(~min(lon), ~min(lat), ~max(lon), ~max(lat)) %>%
registerPlugin(textPathPlugin) %>%
onRender("function(el, x, data) {
var mymap = this;
mymap.on('layeradd',
function(e) {
console.log(e);
var layer = e.layer;
if (layer.groupname == 'reactive') {
layer.on('mouseover', function () {
this.setText(' ► ', {repeat: true, attributes: {fill: 'blue'}});
});
layer.on('mouseout', function () {
this.setText(null);
});
}
}
);
}", data = points)
})
observeEvent(input$clickme,{
points <- points_reactive()
leafletProxy('fullscreen_map') %>%
addPolylines(lng=points$lon, lat=points$lat, group='reactive')
}
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With