листовка плагин и leafletProxy с PolylineDecorator в качестве примера - PullRequest
0 голосов
/ 17 октября 2018

Пожалуйста, обратитесь также к вопросу плагин листовки и leafletProxy .

Я хочу использовать плагин polylineDecorator в листовке для R.

Следующий инструкция о том, как использовать плагин листовки от R , я могу использовать его, если использую подход вместе с leaflet().Смотрите первый пример, который работает, как я хотел.Но если я пытаюсь использовать тот же подход с leafletProxy(), он просто ничего не делает, я получаю только строку без декоратора.См. Второй пример.

Мой вопрос заключается в том, как я могу использовать плагин листовки с R's leafletProxy().

Пример 1 : Версия, которая работает, без использования lefletProxy.

library(shiny)
library(leaflet)
library(htmltools)

download.file(
          'https://raw.githubusercontent.com/bbecquet/Leaflet.PolylineDecorator/master/dist/leaflet.polylineDecorator.js', 
          'leaflet.polylineDecorator.js')

polylineDecoratorPlugin <- htmlDependency('Leaflet.PolylineDecorator',
                                          '1.6.0',
                      src = normalizePath('.'), 
                      script = 'leaflet.polylineDecorator.js')

registerPlugin <- function(map, plugin) {
  map$dependencies <- c(map$dependencies, list(plugin))
  map
}


ui <- bootstrapPage( 
            tags$style(type = "text/css", "html, body {width:100%;height:100%}"), 
            leafletOutput("map", width = "100%", height = "100%")
            )

server <- function(input, output) {
  dat <- data.frame(lat0=c(29,29.1),lat1=c(30,30.1), lng0=c(-96,-96.1),lng1=c(-95,-95.1))
  output$map <- renderLeaflet({
      m <- leaflet() %>%
#        addProviderTiles(providers$OpenStreetMap.BlackAndWhite) %>%
        setView(lat=29.762778, lng=-95.383056, zoom=8)  %>% # Houston
        registerPlugin(polylineDecoratorPlugin) %>%
        addPolylines(lat=c(dat$lat0[1], dat$lat1[1]), lng=c(dat$lng0[1],dat$lng1[1])) %>%
        addPolylines(lat=c(dat$lat0[2], dat$lat1[2]), lng=c(dat$lng0[2],dat$lng1[2])) %>%
        htmlwidgets::onRender("function(el,x,data) {
                            for(var i=0; i < data.lat0.length; i++) {
                              var dec = L.polylineDecorator([[data.lat0[i],data.lng0[i]],[data.lat1[i],data.lng1[i]]], {
                              patterns: [
                              {offset: 0, repeat: 20, symbol: L.Symbol.arrowHead({pixelSize:15, pathOptions:{stroke:true}})}
                              ]
                              }).addTo(this);
                            }
                            }",
                            data=dat)

  })
}

# Run the application 
shinyApp(ui = ui, server = server)

Вот то, что я получаю из кода выше, и это то, что я ожидал.

from the top code

Пример2 : версия, которая не показывает декоратор, просто строка, используя lefletProxy ():

library(shiny)
library(leaflet)
library(htmltools)

download.file(
          'https://raw.githubusercontent.com/bbecquet/Leaflet.PolylineDecorator/master/dist/leaflet.polylineDecorator.js', 
          'leaflet.polylineDecorator.js')

polylineDecoratorPlugin <- htmlDependency('Leaflet.PolylineDecorator',
                                          '1.6.0',
                      src = normalizePath('.'), 
                      script = 'leaflet.polylineDecorator.js')

registerPlugin <- function(map, plugin) {
  map$dependencies <- c(map$dependencies, list(plugin))
  map
}


ui <- bootstrapPage( 
            tags$style(type = "text/css", "html, body {width:100%;height:100%}"), 
            leafletOutput("map", width = "100%", height = "100%")
            )

server <- function(input, output) {
  dat <- data.frame(lat0=c(29,29.1),lat1=c(30,30.1), lng0=c(-96,-96.1),lng1=c(-95,-95.1))
  output$map <- renderLeaflet({
      m <- leaflet() %>%
#        addProviderTiles(providers$OpenStreetMap.BlackAndWhite) %>%
        setView(lat=29.762778, lng=-95.383056, zoom=8)  # Houston
    })
  observe({
    # THIS DOESNT WORK with PROXY!!!
    leafletProxy('map') %>%
    registerPlugin(polylineDecoratorPlugin) %>%
    addPolylines(lat=c(dat$lat0[1], dat$lat1[1]), lng=c(dat$lng0[1],dat$lng1[1])) %>%
    addPolylines(lat=c(dat$lat0[2], dat$lat1[2]), lng=c(dat$lng0[2],dat$lng1[2])) %>%
    htmlwidgets::onRender("function(el,x,data) {
                          for(var i=0; i < data.lat0.length; i++) {
                            var dec = L.polylineDecorator([[data.lat0[i],data.lng0[i]],[data.lat1[i],data.lng1[i]]], {
                            patterns: [
                            {offset: 0, repeat: 20, symbol: L.Symbol.arrowHead({pixelSize:15, pathOptions:{stroke:true}})}
                            ]
                            }).addTo(this);
                          }
                          }",
                          data=dat)
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

А вот результаты из примера 2. Как вы видите, декоратор отсутствует, только строкихотя я пытался использовать htmlwidgets::onRender почти таким же образом.

from the bottom code

1 Ответ

0 голосов
/ 24 февраля 2019

Хорошо, возможно, я прибил его.

Что мне нужно было сделать:

  1. Позвонить htmlwidgets::onRender с leaflet, а не с leafletProxy.Я должен предвидеть, что произойдет, когда я сделаю карту.

  2. Когда я добавляю полилинии, используя lealetProxy, я хочу добавить дополнительную опцию need_decorator = TRUE.

  3. Функция обратного вызова для htmlwidgets::onRender следует добавить прослушиватель событий на карту.в приведенном ниже коде именно эта часть: myMap.on('layeradd', function(e) {...} );.Таким образом, при добавлении слоя будет добавлен декоратор.

  4. Мы хотим добавить декоратор к полилинии.Поэтому мне нужно if ('need_decorator' in lyr.options) это тестирование, если слой, вызвавший событие, был полилинией, которую я хочу иметь в качестве декоратора.Без этого теста полилинейный декоратор будет запускать событие и будет бесконечный цикл вызова.

Пример кода ниже генерирует то, что я хотел.Это может быть очевидно для людей, имеющих опыт работы с javascript, но многие пользователи R, такие как я, не имеют большого опыта в подобных мероприятиях ...

Я хочу иметь дело со случаями, когда полилиния получилаизменено / удалено, но я думаю, что идея будет такой же.

Пожалуйста, дайте мне знать, если есть более простой способ сделать это.

library(shiny)
library(leaflet)
library(htmltools)

download.file(
  'https://raw.githubusercontent.com/bbecquet/Leaflet.PolylineDecorator/master/dist/leaflet.polylineDecorator.js', 
  'leaflet.polylineDecorator.js')

polylineDecoratorPlugin <- htmlDependency('Leaflet.PolylineDecorator',
                                          '1.6.0',
                                          src = normalizePath('.'), 
                                          script = 'leaflet.polylineDecorator.js')

registerPlugin <- function(map, plugin) {
  map$dependencies <- c(map$dependencies, list(plugin))
  map
}


ui <- bootstrapPage( 
  tags$style(type = "text/css", "html, body {width:100%;height:100%}"), 
  leafletOutput("map", width = "100%", height = "100%")
)

server <- function(input, output) {
  dat <- data.frame(lat0=c(29,29.1),lat1=c(30,30.1), lng0=c(-96,-96.1),lng1=c(-95,-95.1))
  output$map <- renderLeaflet({
    m <- leaflet() %>%
      registerPlugin(polylineDecoratorPlugin) %>%
      addProviderTiles(providers$OpenStreetMap.BlackAndWhite) %>%
      setView(lat=29.762778, lng=-95.383056, zoom=8) %>%  # Houston
      htmlwidgets::onRender(
        "function(el,x,data) {
          var myMap = this;

          // I have to wrap the decoration addition code with map.on() function
          // wait for polyline layer to be added before i add decorator    
          myMap.on('layeradd',
            function(e) {
              var lyr = e.layer;
              // among whatever layers added to the map, i look for
              // 'need_decorator' property which i tell myself to add as an options
              // when adding polyline
              if ('need_decorator' in lyr.options) {

                var dec = L.polylineDecorator(lyr, {
                  patterns: [
                    {offset: 0, repeat: 20, symbol: L.Symbol.arrowHead({pixelSize:15, pathOptions:{stroke:true}})}
                  ]
                }).addTo(myMap);
              }
            }
          );
        }",
      data=dat)
  })
  observe({
    leafletProxy('map') %>%
      # I am adding need_decorator = TRUE as an option.  This shows up as, when 
      # event got triggered, event.layer.options.need_decorator in Javascript
      addPolylines(lat=c(dat$lat0[1], dat$lat1[1]), lng=c(dat$lng0[1],dat$lng1[1]), options = list(need_decorator = T)) %>%
      addPolylines(lat=c(dat$lat0[2], dat$lat1[2]), lng=c(dat$lng0[2],dat$lng1[2]), options = list(need_decorator = T)) 

    })
  }

# Run the application 
shinyApp(ui = ui, server = server)
...