闪亮 - 在数据表中选择记录时如何突出显示传单地图上的对象?

Posted

技术标签:

【中文标题】闪亮 - 在数据表中选择记录时如何突出显示传单地图上的对象?【英文标题】:Shiny - how to highlight an object on a leaflet map when selecting a record in a datatable? 【发布时间】:2018-07-24 16:24:06 【问题描述】:

在选择(单击)数据表中的相应记录时,是否可以突出显示传单地图上的标记或折线?

我查看了这些问题/线程:

selecting a marker on leaflet, from a DT row click and vice versa - 没有答案

https://github.com/r-spatial/mapedit/issues/56 - 检查及时投资组合在 2017 年 7 月 23 日的评论。如 gif 所示,我希望能够在数据表中选择一行,以便相应的地图对象(标记/折线)突出显示为好吧(不编辑地图)。

这是一个工作示例,其中突出显示的地图对象在下面的数据表中被选中,但反之亦然 - 这是我想要实现的目标。

##############################################################################
# Libraries
##############################################################################
library(shiny)
library(shinythemes)
library(ggplot2)
library(plotly)
library(leaflet)
library(DT)
##############################################################################
# Data
##############################################################################
qDat <- quakes
qDat$id <- seq.int(nrow(qDat))
str(qDat)
##############################################################################
# UI Side
##############################################################################
ui <- fluidPage(
  titlePanel("Visualization of Fiji Earthquake"),

  # side panel
  sidebarPanel(
    h3('Fiji Earthquake Data'),

    sliderInput(
      inputId = "sld01_Mag",
      label="Show earthquakes of magnitude:", 
      min=min(qDat$mag), max=max(qDat$mag),
      value=c(min(qDat$mag),max(qDat$mag)), step=0.1
      ),

    plotlyOutput('hist01')
    ),

  # main panel
  mainPanel(
    leafletOutput('map01'),
    dataTableOutput('table01')
    )

)
##############################################################################
# Server Side
##############################################################################
server <- function(input,output)
  qSub <-  reactive(

      subset <- subset(qDat, qDat$mag>=input$sld01_Mag[1] &
                         qDat$mag<=input$sld01_Mag[2])
  )

  # histogram
  output$hist01 <- renderPlotly(
    ggplot(data=qSub(), aes(x=stations)) + 
      geom_histogram(binwidth=5) +
      xlab('Number of Reporting Stations') +
      ylab('Count') +
      xlim(min(qDat$stations), max(qDat$stations))+
      ggtitle('Fiji Earthquake')
  )

  # table
  output$table01 <- renderDataTable(

    DT::datatable(qSub(), selection = "single",options=list(stateSave = TRUE))
  )

  # map
  output$map01 <- renderLeaflet(
    pal <- colorNumeric("YlOrRd", domain=c(min(quakes$mag), max(quakes$mag)))
    qMap <- leaflet(data = qSub()) %>% 
      addTiles() %>%
      addMarkers(popup=~as.character(mag), layerId = qSub()$id) %>%
      addLegend("bottomright", pal = pal, values = ~mag,
                title = "Earthquake Magnitude",
                opacity = 1)
    qMap
  )

  observeEvent(input$map01_marker_click, 
    clickId <- input$map01_marker_click$id
    dataTableProxy("table01") %>%
      selectRows(which(qSub()$id == clickId)) %>%
      selectPage(which(input$table01_rows_all == clickId) %/% input$table01_state$length + 1)
  )


##############################################################################
shinyApp(ui = ui, server = server)
##############################################################################

有什么建议吗?

【问题讨论】:

【参考方案1】:

是的,这是可能的。您可以从datatableinput$x_rows_selected 中获取选定的行,其中xdatatable 名称。然后我们可以使用leafletProxy 删除旧标记并添加一个新标记。我还创建了一个reactiveVal 来跟踪先前标记的行,并在单击新元素时重置该元素的标记。如果您还想保持之前选择的标记为红色,只需删除 reactiveVal prev_row() 并删除 observeEvent. 的第二部分下面是一个工作示例。

请注意,我在 qSub() 反应式中添加了 head(25) 以限制行数以进行说明。

希望这会有所帮助!



    ##############################################################################
# Libraries
##############################################################################
library(shiny)
library(shinythemes)
library(ggplot2)
library(plotly)
library(leaflet)
library(DT)
##############################################################################
# Data
##############################################################################
qDat <- quakes
qDat$id <- seq.int(nrow(qDat))
str(qDat)
##############################################################################
# UI Side
##############################################################################
ui <- fluidPage(
  titlePanel("Visualization of Fiji Earthquake"),

  # side panel
  sidebarPanel(
    h3('Fiji Earthquake Data'),

    sliderInput(
      inputId = "sld01_Mag",
      label="Show earthquakes of magnitude:", 
      min=min(qDat$mag), max=max(qDat$mag),
      value=c(min(qDat$mag),max(qDat$mag)), step=0.1
    ),

    plotlyOutput('hist01')
  ),

  # main panel
  mainPanel(
    leafletOutput('map01'),
    dataTableOutput('table01')
  )

)
##############################################################################
# Server Side
##############################################################################
server <- function(input,output)
  qSub <-  reactive(

    subset <- subset(qDat, qDat$mag>=input$sld01_Mag[1] &
                       qDat$mag<=input$sld01_Mag[2]) %>% head(25)
  )

  # histogram
  output$hist01 <- renderPlotly(
    ggplot(data=qSub(), aes(x=stations)) + 
      geom_histogram(binwidth=5) +
      xlab('Number of Reporting Stations') +
      ylab('Count') +
      xlim(min(qDat$stations), max(qDat$stations))+
      ggtitle('Fiji Earthquake')
  )

  # table
  output$table01 <- renderDataTable(

    DT::datatable(qSub(), selection = "single",options=list(stateSave = TRUE))
  )

  # to keep track of previously selected row
  prev_row <- reactiveVal()

  # new icon style
  my_icon = makeAwesomeIcon(icon = 'flag', markerColor = 'red', iconColor = 'white')

  observeEvent(input$table01_rows_selected, 
    row_selected = qSub()[input$table01_rows_selected,]
    proxy <- leafletProxy('map01')
    print(row_selected)
    proxy %>%
      addAwesomeMarkers(popup=as.character(row_selected$mag),
                        layerId = as.character(row_selected$id),
                        lng=row_selected$long, 
                        lat=row_selected$lat,
                        icon = my_icon)

    # Reset previously selected marker
    if(!is.null(prev_row()))
    
      proxy %>%
        addMarkers(popup=as.character(prev_row()$mag), 
                   layerId = as.character(prev_row()$id),
                   lng=prev_row()$long, 
                   lat=prev_row()$lat)
    
    # set new value to reactiveVal 
    prev_row(row_selected)
  )

  # map
  output$map01 <- renderLeaflet(
    pal <- colorNumeric("YlOrRd", domain=c(min(quakes$mag), max(quakes$mag)))
    qMap <- leaflet(data = qSub()) %>% 
      addTiles() %>%
      addMarkers(popup=~as.character(mag), layerId = as.character(qSub()$id)) %>%
      addLegend("bottomright", pal = pal, values = ~mag,
                title = "Earthquake Magnitude",
                opacity = 1)
    qMap
  )

  observeEvent(input$map01_marker_click, 
    clickId <- input$map01_marker_click$id
    dataTableProxy("table01") %>%
      selectRows(which(qSub()$id == clickId)) %>%
      selectPage(which(input$table01_rows_all == clickId) %/% input$table01_state$length + 1)
  )


##############################################################################
shinyApp(ui = ui, server = server)
##############################################################################

【讨论】:

这很有帮助!谢谢你。有没有办法突出标记而不是在顶部绘制另一个标记?我假设当我突出显示一个标记时,在 DT 中突出显示一行而不是添加一个新行。 另一个问题,是否可以对折线做同样的事情?在我的实际应用程序中,我有由折线连接的标记。理想情况下,我想选择一个 DT 行,并且两个端点和连接的折线都会在地图上突出显示。 @M_M 据我所知,没有(简单的)方法可以更改已放置标记的颜色。当您在 DT 中选择一行时,您不会向 DT 添加新行,您只是向地图添加一个标记。对于折线,也许我的回答 here 可以帮助您朝着正确的方向前进。 我删除了removeMarker() 语句。这些都是多余的,因为添加具有相同 layerId 的新标记将删除旧图层。 再次感谢 - 我会查看您为折线发送的链接。是否可以启用双击以取消选择标记/行?并且只能通过表格而不是通过单击地图上的标记进行选择吗?

以上是关于闪亮 - 在数据表中选择记录时如何突出显示传单地图上的对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何突出显示在我的传单地图(nuxt/vue)中单击了哪个标记

如何在闪亮中循环观察事件?单击多边形时更改传单中的样式

如何使用传单和 jQuery Birdseye 在点击时突出显示标记

使用动态菜单时,闪亮的传单无法正常工作

闪亮的传单不适用于动态菜单

闪亮的传单地图功能没有响应