You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用中点击地图后实现Datatable自动滚动到选中行

解决方案

要实现点击地图后Datatable自动滚动到选中行,你可以通过Shiny与前端JavaScript的通信机制结合DataTables的API来实现。核心逻辑是:在表格选中行更新后,调用JS代码让目标行滚动到可视区域内。

具体实现步骤

  1. 在change_selection()函数中,除了更新表格的选中状态,通过Shiny的自定义消息机制传递选中行的索引给前端。
  2. 在UI中嵌入一段JavaScript代码,监听这个自定义消息,调用DataTables的API完成滚动操作。

修改后的完整代码

library(shiny)
library(leaflet)
library(sf)
library(DT)

# 加载nc县数据
nc <- st_read(system.file("shape/nc.shp", package="sf")) |> 
  st_transform(crs = 4326)

ui <- fluidPage(
  leafletOutput("map"),
  DTOutput("table"),
  
  # 添加自定义JavaScript代码
  tags$script(HTML("
    // 监听Shiny发送的滚动指令
    Shiny.addCustomMessageHandler('scrollToTargetRow', function(rowNum) {
      // 获取Datatable实例
      var targetTable = $('#table').DataTable();
      // DataTables行索引从0开始,Shiny行索引从1开始,需做转换
      targetTable.row(rowNum - 1).scrollTo();
    });
  "))
)

server <- function(input, output, session) {
  # 渲染Leaflet地图
  output$map <- renderLeaflet({
    leaflet(nc) |> 
      addTiles() |> 
      addPolygons(
        layerId = ~NAME,
        fillColor = "white",
        fillOpacity = 0.5,
        color = "black",
        weight = 1,
        highlightOptions = highlightOptions(
          fillColor = "blue",
          fillOpacity = 0.8,
          bringToFront = TRUE
        )
      )
  })
  
  # 渲染Datatable
  output$table <- renderDT({
    datatable(
      nc |> st_drop_geometry(),
      selection = list(mode = "single", target = "row"),
      rownames = FALSE
    )
  })
  
  # 定义选中变更处理函数
  change_selection <- function(selected_id) {
    # 更新表格选中行
    table_proxy <- dataTableProxy("table")
    target_row <- which(nc$NAME == selected_id)
    selectRows(table_proxy, target_row)
    
    # 发送滚动指令给前端JS
    session$sendCustomMessage("scrollToTargetRow", target_row)
  }
  
  # 监听表格行点击,同步高亮地图对应多边形
  observeEvent(input$table_rows_selected, {
    if (!is.null(input$table_rows_selected)) {
      selected_name <- nc$NAME[input$table_rows_selected]
      leafletProxy("map") |> 
        removeShape("highlight") |> 
        addPolygons(
          data = nc[nc$NAME == selected_name,],
          layerId = "highlight",
          fillColor = "blue",
          fillOpacity = 0.8,
          color = "black",
          weight = 2
        )
    }
  })
  
  # 监听地图多边形点击,同步选中表格行并滚动
  observeEvent(input$map_shape_click, {
    selected_id <- input$map_shape_click$id
    change_selection(selected_id)
  })
}

shinyApp(ui, server)

关键细节说明

  • 自定义消息通信:session$sendCustomMessage()是Shiny与前端交互的标准方式,能安全传递数据到JavaScript环境。
  • 索引转换:DataTables的行索引从0开始,而Shiny中表格的行索引从1开始,因此需要将target_row减1后再传递给JS。
  • 兼容备选方案:如果你的DT版本不支持scrollTo()方法,可以改用原生JS的scrollIntoView()实现平滑滚动:
    var targetRowNode = targetTable.row(rowNum - 1).node();
    targetRowNode.scrollIntoView({behavior: 'smooth', block: 'center'});
    

内容的提问来源于stack exchange,提问作者Wander Demuynck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:50:19