首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可编程触发鼠标点击R传单中的闪光事件

可编程触发鼠标点击R传单中的闪光事件
EN

Stack Overflow用户
提问于 2021-12-09 11:18:40
回答 1查看 530关注 0票数 2

我的问题与这个相同:触发标记鼠标点击R传单中的事件,但是我没有足够的代表来添加评论,而且编辑队列是“满的”,所以我不能将我的想法添加到原来的问题中。不确定这是否违反社区规则/最佳实践,如果违反,请删除!对下面冗长的描述表示歉意,但我想我可能已经接近了一个解决方案,而javascript或闪亮的大师可以在短时间内修复它!或者,我完全错了。感谢您的阅读!

当我在我的R闪亮的web应用程序中的DT数据表中选择一行时,我想触发一个传单地图标记单击事件。

下面是一个min示例应用程序,作为添加此功能的基础:

代码语言:javascript
复制
library(shiny)
library(leaflet)
library(magrittr)
library(shinyjs)

# create js function that triggers a click on a button 'buttona'
jsCode <- 'shinyjs.buttonClick = (function() {
           $("#buttona").click();
           });'

df <- tibble::tibble(id = c(1,2,3,4,5),
                     label = c('One','Two','Three','Four','Five'),
                     lat = c(50,55,60,65,70), lng = c(0,5,-5,10,-10)
                     )

ui <- fluidPage(
    # new lines to enable shinyjs and import custom js function
    shinyjs::useShinyjs(),
    shinyjs::extendShinyjs(text = jsCode, functions = c('buttonClick')),

    leaflet::leafletOutput('map'),
    DT::DTOutput('table'),
    shiny::actionButton('buttona',"Button A") # new button
)

server <- function(input, output, session) {
    
    output$map <- leaflet::renderLeaflet({
        leaflet::leaflet(options = leaflet::leafletOptions(minZoom = 3,maxZoom = 10)) %>%
            leaflet::setView(lng = 10,lat = 60,zoom = 3) %>%
            leaflet::addProviderTiles(provider = leaflet::providers$Esri.OceanBasemap) %>%
            leaflet::addMarkers(data = df,
                                layerId = ~id,
                                group = 'group1',
                                label = ~label,
                                lat = ~lat,
                                lng = ~lng,
                                popup = ~paste("<h3>More Information</h3>",
                                               "<b>Title:</b>",label,sep =" "))
    })
    output$table <- DT::renderDT(df,
                                 selection = 'single',
                                 rownames = FALSE,
                                 editable = FALSE
    )

    # observer looking for datatable row selection and triggering js function
    observeEvent(input$table_rows_selected,{
        shinyjs::js$buttonClick()
    })

    # observer looking for button click to trigger modal
    observeEvent(input$buttona,{
        showModal(
            modalDialog(title = "Test",
                        size = 'm',
                        h1("Test")
                        
            )
        )
    })
    
}

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

我尝试过的事情:

shinyjs和javascript

我已经成功地使用shinyjs包创建了一个按钮(参见上面的示例应用程序)来创建类似的功能,但是当我试图对标记做同样的事情时,我只是不知道js知识来找到正确的元素。通过浏览chrome中的js控制台,我可以手动找到它们,但它们在一个iframe中,我不知道如何编程实现目标,而且位置(例如jQuery351022343796258432992 )中有一个随机字符串。通过chrome js控制台使用手动定位(在执行此操作之前,我需要使用“Elements”选项卡在iframe中选择#文档),我可以使用以下行触发我想要的单击事件:

代码语言:javascript
复制
var mymap = document.getElementsByClassName('leaflet');
var els = mymap.map.jQuery351022343796258432992.leafletMap.layerManager._byGroup.group1;
els[0].fire('click'); //note this is the leaflet.js to trigger a marker click event

闪烁小部件

根据本页底部的传单文档,使用shinywidgets::onRender可能会有一些东西,但是我不知道如何在这个场景中实现它。

再次感谢你的阅读!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-09 23:56:12

使用JS的解决方案

访问Map对象之后,需要遍历所有层,以找到具有特定id的标记。

我修改了用shinyjs调用的JS函数,以迭代所有层,并在与id匹配的标记上触发事件click。为了避免每次都查找Map对象,在使用htmlwidgets::onRender函数进行呈现之后,将检索Map对象。作为shinyjs的替代方案,您可以使用runjs来执行函数(不在下面的代码中)。

代码语言:javascript
复制
library(shiny)
library(leaflet)
library(magrittr)
library(shinyjs)

# create js function that triggers a click on a marker selected by a row in a DT
jsCode <- 'shinyjs.markerClick = function(id) {
              map.eachLayer(function (layer) {
                if (layer.options.layerId == id) {
                  layer.fire("click");
                }
              })
           };'

df <- tibble::tibble(id = c(1,2,3,4,5),
                     label = c('One','Two','Three','Four','Five'),
                     lat = c(50,55,60,65,70), lng = c(0,5,-5,10,-10)
)

ui <- fluidPage(
  # new lines to enable shinyjs and import custom js function
  shinyjs::useShinyjs(),
  shinyjs::extendShinyjs(text = jsCode, functions = c('markerClick')),
  
  leaflet::leafletOutput('map'),
  DT::DTOutput('table'),
  shiny::actionButton('buttona',"Button A") # new button
)

server <- function(input, output, session) {
  
  output$map <- leaflet::renderLeaflet({
    m <- leaflet::leaflet(options = leaflet::leafletOptions(minZoom = 3,maxZoom = 10)) %>%
      leaflet::setView(lng = 10,lat = 60,zoom = 3) %>%
      leaflet::addProviderTiles(provider = leaflet::providers$Esri.OceanBasemap) %>%
      leaflet::addMarkers(data = df,
                          layerId = ~id,
                          group = 'group1',
                          label = ~label,
                          lat = ~lat,
                          lng = ~lng,
                          popup = ~paste("<h3>More Information</h3>",
                                         "<b>Title:</b>",label,sep =" "))
    
    # assign the leaflet object to variable 'map'
    m <- m %>% 
      htmlwidgets::onRender("
          function(el, x) {
            map = this;
          }"
      )                                         
    
  })
  output$table <- DT::renderDT(df,
                               selection = 'single',
                               rownames = FALSE,
                               editable = FALSE
  )
  
  # observer looking for datatable row selection and triggering js function
  observeEvent(input$table_rows_selected,{
    rowIndex <- input$table_rows_selected
    df$id[rowIndex]
    shinyjs::js$markerClick(df$id[rowIndex])
  })
  
  # observer looking for button click to trigger modal
  observeEvent(input$buttona,{
    showModal(
      modalDialog(title = "Test",
                  size = 'm',
                  h1("Test")
                  
      )
    ) 
  })
  
}

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

使用传单代理的解决方案

每次用户选择表中的一行时,只需添加一个新的弹出窗口即可。使用相同的layerId自动更新可能已经在地图上的弹出是很重要的。另外,由于弹出将放置在标记latlng上,因此有必要使用offset调整像素上的相对位置。

代码语言:javascript
复制
library(shiny)
library(leaflet)

df <- tibble::tibble(id = c(1,2,3,4,5),
                     label = c('One','Two','Three','Four','Five'),
                     lat = c(50,55,60,65,70), lng = c(0,5,-5,10,-10)
)

ui <- fluidPage( 
  leaflet::leafletOutput('map'),
  DT::DTOutput('table')
)

server <- function(input, output, session) {
  
  output$map <- leaflet::renderLeaflet({
    m <- leaflet::leaflet(options = leaflet::leafletOptions(minZoom = 3,maxZoom = 10)) %>%
      leaflet::setView(lng = 10,lat = 60,zoom = 3) %>%
      leaflet::addProviderTiles(provider = leaflet::providers$Esri.OceanBasemap) %>%
      leaflet::addMarkers(data = df,
                          layerId = ~id,
                          group = 'group1',
                          label = ~label,
                          lat = ~lat,
                          lng = ~lng,
                          popup = ~paste("<h3>More Information</h3>",
                                         "<b>Title:</b>",label,sep =" "))
    
  })
  
  output$table <- DT::renderDT(df,
                               selection = 'single',
                               rownames = FALSE,
                               editable = FALSE
  )
  
  # observer looking for datatable row selection and use leaflet proxy to add a popup
  observeEvent(input$table_rows_selected,{
    rowIndex <- input$table_rows_selected
    df$id[rowIndex]
    proxy <- leafletProxy("map")
    addPopups(
      proxy,
      lng = df$lng[rowIndex],
      lat =df$lat[rowIndex],
      popup = paste("<h3>More Information</h3>",
                    "<b>Title:</b>",df$label[rowIndex],sep =" "),
      layerId = "popup",
      options  = popupOptions(offset = list (x = 0, y = -26))
    )
  })
}

shinyApp(ui = ui, server = server)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70288989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档