我已将TextPath插件添加到一个 Shiny 的应用程序中,类似于this example。这很好用:

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)

})

根据docs,我现在想使用leafletProxy(),以便每当 react 性数据源发生更改时,整个 map 都不会被重绘。 ,,使用以下代码片段
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)

不能按预期工作。我认为这是因为onRender仅在发生新的渲染时才被调用,并且leafletProxy的全部要点是不重新渲染吗?如果这是正确的,是否可以使用其他方法来做到这一点?

最佳答案

尽管可能会有更清洁的方法,但可能类似于以下内容。

我所做的是使用leafletProxy从points_reactive()函数添加折线图层,同时将group设置为reactive。我曾经听过map的layeradd事件,如果添加了一个带有reactive组的图层,我就添加了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')

  }
)
}

10-06 07:14