是否可以在Shiny环境中将Leaflet控件移到map div之外?
从以下代码:
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
我看到this question,但它特定于leaflet.js,与Shiny明显不同。有没有办法做到这一点?
答案 0 :(得分: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)