【问题标题】:Shiny leaflet map, on marker click decrease map width and insert tableoutput闪亮的传单地图,在标记上单击减小地图宽度并插入表格输出
【发布时间】:2017-09-20 00:09:56
【问题描述】:

我正在开发一个闪亮的应用程序,它会在传单地图上显示一些标记。单击其中一个标记时,data.frame 的相应行应显示在地图右侧的 rhandsontable 中。具体来说,应该减小地图宽度(例如从 100% 到 50%),并且应该在空闲空间中插入 rhandsontable。

我的代码存在一些问题,目前我无法解决:

  1. 标记在 LeafletProxy 内时不会绘制在地图上(这在更复杂的应用程序中是必需的)。

  2. 仅观察到第一次标记点击,然后表格不再变化(可能是 observeEvent 有问题)

  3. rhandsontable 被添加到地图下方,而不是在右边的空间中,当地图宽度减小时,它会被释放。

数据应存储在响应式值中(以使更改成为可能)。

这是一个最小的可重现示例:

library(shiny)
library(leaflet)
library(rhandsontable)

ui <- fluidPage(
  fluidRow(
    uiOutput("map2"), 
    uiOutput("table2")
  )
)


server <- function(input, output, session){
  values <- reactiveValues(
    data = data.frame(X = c(1, 2), lat = c(48, 49), lng = c(11, 11.5)),
    which_marker = NULL,
    leaflet_map_width = "100%"
  )

  output$map2 <- renderUI({
    leafletOutput("map", width = values$leaflet_map_width, height = "500px")
  })

  output$map <- renderLeaflet({
    leaflet() %>% addTiles() %>% setView(11, 48.5, 8) # %>% addMarkers(data = values$data, layerId = values$data$X)
  })

  observe({
    leafletProxy("map") %>% addMarkers(data = values$data, layerId = values$data$X)
  })

  observeEvent(input$map_marker_click, {
    print("observed map_marker_click")
    values$which_marker <- input$map_marker_click$id
    values$leaflet_map_width = "50%"
    output$table2 <- renderUI({
      rHandsontableOutput("table")
    })
  })

  output$table <- renderRHandsontable({
    data <- values$data[values$which_marker, ]
    rhandsontable(t(data), rowHeaderWidth = 120)
  })
}

shinyApp(ui, server)

【问题讨论】:

  • 关于 3) 你应该使用类似 fluidRow( column(width = 10, offset = 0, style='padding:0px;', leafletOutput("map", width = "100%", height = "500px")), column(width = 2, offset = 0, style='padding:0px;', rHandsontableOutput("table") ) ) 的东西,并根据你的需要设置列的宽度。
  • 列的问题是,它预先分配了空间。因此,如果我使用您建议的代码,地图右侧最初会有空白(总宽度的 2/12)。但是我希望最初使用全宽地图,并且只有在单击标记时才应该将地图的某些宽度用于 rhandsontable。希望,这说明了一切。

标签: r shiny leaflet


【解决方案1】:

注意:这仅回答了 1/3 的问题。 但正如人们在 cmets 中看到的那样,在那里给出提示是没有意义的: 要回答您的第三个问题,请参阅下面的解决方案。 (根据需要设置列的宽度)

library(shiny)
library(leaflet)
library(rhandsontable)

ui <- fluidPage(
  uiOutput("map2")
)


server <- function(input, output, session){
  values <- reactiveValues(
    data = data.frame(X = c(1, 2), lat = c(48, 49), lng = c(11, 11.5)),
    which_marker = NULL,
    leaflet_map_width = "100%"
  )

  observe({
    values$which_marker <- input$map_marker_click$id
  })

  output$map2 <- renderUI({
    if(!is.null(input$map_marker_click)){
      fluidRow(
        column(width = 10, offset = 0, style='padding:0px;',
          leafletOutput("map", width = "100%", height = "500px")),
        column(width = 2, offset = 0, style='padding:0px;',
          rHandsontableOutput("table")
        )
      )
    }else{
      leafletOutput("map", width = values$leaflet_map_width, height = "500px")
    }

  })

  output$map <- renderLeaflet({
    leaflet() %>% addTiles() %>% addMarkers(data = values$data, layerId = values$data$X)
  })

  output$table <- renderRHandsontable({
    data <- values$data[values$which_marker, ]
    rhandsontable(t(data), rowHeaderWidth = 120)
  })
}

shinyApp(ui, server)

【讨论】:

  • 啊,对不起,我误会了你,没想到在renderUI中使用列。干得好!
  • 不,我的错。难以用 cmets 概括。我只是不想写作为答案,因为其他人倾向于认为问题现在已经完全回答了;)
猜你喜欢
  • 2018-03-13
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
  • 2019-09-03
  • 2023-01-11
  • 2018-10-30
  • 1970-01-01
相关资源
最近更新 更多