问题
I am trying to get a datatable (DT) to scroll to the proper row/line when hovering over a point on a map. I can do things like have the row be selected, but I cannot figure out how to make the datatable Y-scroll to the proper entry. I'm trying to do this without Paging, as my datatable uses subsets and is not overall that large.
I'm doing this in R/Shiny/DT my javascript experience is 0. This post seems to have been trying to do the same thing, except that the example is one the initial table load instead of reacting to events outside the initially loaded table. I do not understand how I would make the tables scrolling reactive to user events.
R Shiny - Scrolling to a given row of datatable with javascript callback
The product is for internal (academic) use to make data manipulation and error checking faster.
#Attempt at datatable scrollable, workable example
library(shiny)
library(leaflet)
library(DT)
data("mtcars")
samp_data = cbind(mtcars,mtcars,mtcars)
samp_data[2] = 'just some string thats often quite long and will take multiple lines on a table draw,
one problem I have is that if I do add "scroller = T" to the options list in the renderDT call,
is that this line will collapse into a single line and create a very long horizonal entry.'
ui = fillPage(
fillRow( flex = 1, width = '100%', height = '80%',
leafletOutput("map", width = '100%', height = "100%")
),
fillRow( width = '100%', height='20%', flex = 1,
# style = "overflow-y: auto; overflow-x: auto;",
div( DTOutput('db_info', width="100%", height="100%"), style = "font-size:85%")
)
)
server = shinyServer(function(input, output, session) {
output$map = renderLeaflet( leaflet(options = leafletOptions(zoomControl = FALSE)) %>% addTiles() %>% addMiniMap(zoomLevelFixed=2, toggleDisplay=T) )
# output$map = renderLeaflet( leaflet(options = leafletOptions(zoomControl = FALSE)) %>% addTiles() %>% addMiniMap(zoomLevelFixed=2, toggleDisplay=T) )
#For some reason the first draw is wrong
output$db_info <- renderDT( samp_data,
class = 'cell-border stripe',
# extensions = 'Scroller',
rownames = F,
server = F,
options = list(
dom = 't', # dom 't' is a specific option
autoWidth = T,
scrollX = T,
scrollY = '15vh',
scrollCollapse = T,
# scroller = T,
# paging = F,
# initComplete = JS('function() {
# $(this.api().table().row(4)).addClass("selected");
# this.api().table().row(4).scrollTo();}'),
columnDefs = list(list(
width = '500px', targets = c(1) #sets width of citations, need autoWidth=T and scrollX=T to work
))# END columnDefs
)# End options list
)# END RENDER DATA TABLE
#some event on map doesn't really matter for example, hardcode for now
#observeEvent({
#This is where I would like to scroll to the appropriate row in the datatable
# dataTableProxy("db_info", session = session)
# selectRows(c(4,6)) %>%
# selectPage(which(input$db_info_rows_all == c(4,6)) %/% input$db_info_state$length + 1)
# callback = JS('.scroller.toPosition( 4 );')
# dataTableProxy('db_info', session=session) %>% selectRows(c(5,6))
#})
})
shinyApp(ui, server)
I've added an example script where I've been trying to work through some solutions. I have not had a hint of success however. In the end I'd like to autoscroll to the portion of the table when a user clicks or hovers over the corresponding point on a map. I can implement that later easily enough, if I can get the interaction with the table worked out. In this example I'm not actually using an observer, I'm just trying to see if I can get something to happen at all.
Thank you for any aid!
回答1:
Since I was unable to solve this, given that it seems I would need to know the length of the table in advance before being able to scroll around it (and paging) I had to settle for a different approach.
observeEvent( input$map_marker_mouseover, {
marker_id = input$map_marker_mouseover$id
dataTableProxy("db_info", session = session) %>%
updateSearch(keywords = list(global = marker_id , columns = "acc_num"))
})
observeEvent( input$map_marker_mouseout, {
dataTableProxy("db_info", session = session) %>%
clearSearch()
})
Simply put, I make the unique identifier of the table the $id of the marker, when I mouse over a point it runs a search of the unique ID column automatically which causes it to subset the table to only that record. When mousing out it clears the search so that the table re-appears. I make the table with these options:
output$db_info <- renderDT( sp_pts,
class = 'cell-border table-condensed table-hover',
rownames = FALSE,
server = F,
options = list(
dom = 'tf',
autoWidth = T,
scrollX = T,
scrollY = '15vh',
scrollCollapse = T,
searching = T,
paging = F,
columnDefs = list(list(
width = '500px',
targets = c(pt_cite_loc)
))# END columnDefs
)# End options list
)# END RENDER DATA TABLE
来源:https://stackoverflow.com/questions/52492179/scroll-to-row-based-on-user-event-r-dt-shiny-without-using-paging