将Leaflet控件放在Shiny环境中的地图div之外

问题描述 投票:0回答:1

是否可以在 Shiny 环境中将 Leaflet 控件移到地图 div 之外?

示例: enter image description here

来自以下代码:

library(shiny)
library(leaflet)

shinyApp(
  
  ui <- fluidPage(
    sidebarPanel("This is where I want to put the leaflet layers control", width = 3), 
    mainPanel(
      leafletOutput("map", width = "100%"), 
      width = 9)
  ), 
  
  server <- function(session, input, output){
    
    output$map <- renderLeaflet({
      leaflet() %>% 
        addProviderTiles("Esri.WorldTerrain", group = "Layer1") %>% 
        addProviderTiles("Esri.WorldImagery", group = "Layer2") %>% 
        addLayersControl(position = "topleft", 
                         baseGroups = c("Layer1", "Layer2"), 
                         options = layersControlOptions(collapsed = F))
    })  # END RENDERLEAFET
  }  # END SERVER
)  # END SHINYAPP

我看到了这个问题,但它是特定于leaflet.js的,它与Shiny有很大不同。有什么办法可以做到这一点吗?

javascript html r shiny r-leaflet
1个回答
2
投票

用 JS 可以(部分?)实现。

在Shiny中使用JS

在闪亮的

library(shinyjs)
中使用JS是一个很好的捷径。在 ui 端使用
useShinyjs()
,在服务器端使用
runjs()

修改 HTML

当你想要修改 DOM 时,你必须知道,必须等到 DOM 完全构建完成后,才能对其进行修改。使用

session$onFlushed(function() {}
确保仅在 DOM 完全构建后才开始修改。

重新定位 HTML 元素

首先,您必须知道要重新定位的元素以及要插入元素的目标是如何命名的。为此,运行应用程序(在浏览器中)右键单击所需的元素并选择“检查”。 接下来,过程是将“要重新定位的元素”保存在变量中,将其从传单地图中删除并将其添加到地图之外。

JS 代码可能如下所示:

     var targetName = "div.leaflet-control-layers.leaflet-control-layers-expanded.leaflet-control"
     var target = document.querySelector(targetName);
     var dest = document.querySelector("div.col-sm-3");
     document.querySelector(targetName).remove()
     dest.appendChild(target)

挑战 如果将所有这些放在一起,您会发现控件不在灰色框中,而是在其下方。鉴于上面的代码,原因是它被附加到

div.col-sm-3
而不是
form.well
(因为它不适用于
form.well
)。我有想法在 UI
tags$div(id = "insertContainer", "")
中添加一个空容器并将其插入其中,但这也不起作用。我不知道进入灰色盒子对你来说有多重要,可能看起来会更好。也许有人可以帮忙。

代码

library(shiny)
library(leaflet)
library(shinyjs)

  ui <- fluidPage(
    useShinyjs(),
    sidebarPanel(HTML("This is where I want to put the leaflet layers control"), width = 3, height = 5), 
    mainPanel(
      leafletOutput("map", width = "100%"), 
      width = 9)
  )

  server <- function(session, input, output){

    session$onFlushed(function() {
      runjs('
             var targetName = "div.leaflet-control-layers.leaflet-control-layers-expanded.leaflet-control"
             var target = document.querySelector(targetName);
             var dest = document.querySelector("div.col-sm-3");
             document.querySelector(targetName).remove()
             dest.appendChild(target)
      ')
    })

    output$map <- renderLeaflet({
      leaflet() %>% 
        addProviderTiles("Esri.WorldTerrain", group = "Layer1") %>% 
        addProviderTiles("Esri.WorldImagery", group = "Layer2") %>% 
        addLayersControl(position = "topleft", 
                         baseGroups = c("Layer1", "Layer2"), 
                         options = layersControlOptions(collapsed = F))
    })  # END RENDERLEAFET
  }  # END SERVER


runApp(shinyApp(ui, server), launch.browser = TRUE)
© www.soinside.com 2019 - 2024. All rights reserved.