How to make the horizontal scrollbar visible in DT::datatable - r

Using R shiny & DT package, I am creating certain tables. The number of columns vary as per user input & is not fixed. I have included the following code snippet to include a horizontal scrollbar so that when the number of columns is large, the user can scroll through the columns that are not directly visible.
server.R:
output$results <- DT::renderDataTable({
DT::datatable(data = datasetInput(),
options = list(scrollX = TRUE,...)
)
})
<code reduced for brevity>
Using the above code, the Horizontal scrollbar is not visible at first but appears when I click on a row and hit right arrow on my keyboard. Is there any way the scroll bar becomes visible as soon as the table is fired up, no matter how many columns I have, and I can drag the scrollbar using the mouse pointer?
Update:
I tried the code in the answer below and this is what I see - no horizontal scrollbar.

I don't think you can (or should) force a scrollbar easily if you don't need one, but the above code works fine for me, it shows a scrollbar when the page initializes. Maybe the problem is with the data or something else.
Here's a minimal example that has a horizontal scrollbar on page load
runApp(shinyApp(
ui = fluidPage(
DT::dataTableOutput("results", width = 300)
),
server = function(input, output, session) {
output$results <- DT::renderDataTable(
mtcars,
options = list(scrollX = TRUE)
)
}
))

Try this:
DT::datatable(sta, options = list(
pageLength=50, scrollX='400px'), filter = 'top')

I would have done this way also:
datasetInput1 <- reactive({
infile <- input$file1
if(is.null(infile))
return(NULL)
else
m <- read.csv(infile$datapath, header = input$header)
return ( DT::datatable(m, extensions = 'Scroller', options = list(deferRender = F, dom = 't',
columnDefs = list(list(className = 'dt-center',
targets = 5)),
scrollY = 300, scroller = TRUE, scrollX = T,
pageLength = 5))
)
})

Related

How to add a horizontal scrollbar to a fixedHeader in renderDataTable in R Shiny?

I am building a datatable in R Shiny to display data with many columns and rows. I had two problems at first:
When the user was scrolling down the table, the header of the table disappeared. This has been fixed thanks to this SO post.
When a user wishes to go left or right of the table, he has to scroll to the bottom of the page (or top depending on where you display the scrollbar). This is an inconvenience to repeat this task especially when displaying many rows. So, my aim is to add a horizontal scrollbar to the fixed header. Would this be possible?
I searched the internet and I found this post that may contain the answer but not sure how to implement it in my case.
The following reproducible code will spawn a table with 50 rows and 30 columns:
library(shiny)
library(shinyWidgets)
library(shinydashboard)
library(dplyr)
library(data.table)
library(tidyverse)
library(DT)
myFun <- function(n = 5000) {
a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
dt <- setDT(data.frame(replicate(30,sample(myFun(50),50,rep=TRUE))))
ui <- fluidPage(theme = "slate",
navbarPage(title = "Test",
header = tagList(
useShinydashboard(),
),
tabPanel(
"Table",
fluidRow(
box(dataTableOutput("mytable"),
width = 12,
collapsible = FALSE,
title = "",
solidHeader = T
)
)
)
)
)
# server
server <- function(input, output) {
output$mytable <-
renderDataTable(
dt,
filter = list(position = "top", clear = FALSE, plain = TRUE),
extensions = c("FixedHeader"),
options = list(
scrollX = T,
fixedHeader=T,
pageLength = 50,
autoWidth = F,
search = list(regex = TRUE),
# the following is used to cut the string if its too long
columnDefs = list(
list(
targets = "_all",
render = JS(
"function(data, type, row, meta) {",
"return type === 'display' && data != null && data.length > 5 ?",
"'<span title=\"' + data + '\">' + data.substr(0, 5) + '...</span>' : data;",
"}"
)
)
)
),
rownames = FALSE
)
}
# app
shinyApp(ui, server)
Will generate a Shiny app:
Any help is kindly appreciated. Thanks in advance.
The vertical scrollbar that appears is actually for the whole page, not the datatable. You need to restrict the height of your datatable, so it doesn't overflow the page, and add the vertical bar. You can do that by adding
scrollY = 300
to your table options, where "300" is the height of your datatable. Depending on your userbase, what devices they are using etc. you will need to adjust this number or find an appropriate way of setting it automatically.
The above would also fix the problem with disappearing header, since you are actually scrolling table body instead of the whole page.

Issues with controlling width of columns in a rendered datatable Shiny

To render a datatable in a shiny app I use the following code
ui <- fluidPage(
box(width = 10, # this is to control table width
DT::DTOutput(('table'))
)
)
server <- function(input, output) {
options(shiny.maxRequestSize=10000*1024^2)
output$table <- DT::renderDataTable(
datatable(
dataset ,
options = list(dom = 'fltipr',
pageLength = 1000,
#lengthMenu = list(c(250, 500), c('250', '500')),
searchHighlight = TRUE,
autoWidth = TRUE,
columnDefs = list(list(width = '300px', targets = c(7,10)), # this is to control width of two columns
list(visible = FALSE, targets = c(2,4,6, 8,11,13,15,16,17:23)))
), filter = 'top',
selection = 'none',
editable = 'cell')
)
}
With that that setup I am trying to control the width of two of the visible columns. When I run the app, it renders fine, just as I wanted it to be rendered.
But when I try to sort the rendered datatable by one of the columns, the controls for column width (and even the whole table width) stop working. The initially controlled column that contains long sections of text now becomes so wide it does not fit on the page, and I have to scroll sideways.
In essence I would like all table to fit on page, with width of two textual columns controlled strictly not matter how I sort the rendered datatable.
Sincerely,
Maria

R large datatable display in Shiny

I am trying to display a relatively large DataTable in a shiny app. The table's dimensions are 7000x30. The performance in Chrome was very very sluggish so I added the 'Scroller' extension to limit the rendering but that did not help. It seems that it is the large number of columns that is causing the issue, not the large number of rows. I also tried to used the colvis extension but the button gives a non scrollable list and with 30 columns, that wouldn't work. Also I tried to have some columns hidden using the visible option, but that didn't work.
Here is the example:
data = as_tibble(matrix(runif(200000), ncol=30))
data %>%
DT::datatable(filter = 'top', extensions = c('Buttons', 'Scroller'),
options = list(scrollY = 650,
scrollX = 500,
deferRender = TRUE,
scroller = TRUE,
# paging = TRUE,
# pageLength = 25,
buttons = list('excel',
list(extend = 'colvis', targets = 0, visible = FALSE)),
dom = 'lBfrtip',
fixedColumns = TRUE),
rownames = FALSE)
Weirdly, the Rstudio viewer shows the datatable and is fine. It's only when I Run the document as a shiny document and open it in Chrome that it becomes very sluggish. My questions are:
Why is this happening
How do I only show a limited number of columns by default and have the option to show the others
is there a better button for colvis? if the list of columns exceeds the page length, I can't access those hidden columns to toggle them on or off.
What do you mean by sluggish?
I ran it and everything looks okay to me in terms of speed.
library(shiny)
library(shinydashboard)
library(DT)
####/UI/####
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
DT::dataTableOutput("test")
)
ui <- dashboardPage(header, sidebar, body)
####/SERVER/####
server <- function(input, output, session) {
data <- as_tibble(matrix(runif(200000), ncol=30))
output$test <- DT::renderDataTable({
DT::datatable(
data,
filter = 'top', extensions = c('Buttons', 'Scroller'),
options = list(scrollY = 650,
scrollX = 500,
deferRender = TRUE,
scroller = TRUE,
# paging = TRUE,
# pageLength = 25,
buttons = list('excel',
list(extend = 'colvis', targets = 0, visible = FALSE)),
dom = 'lBfrtip',
fixedColumns = TRUE),
rownames = FALSE)
})
}
shinyApp(ui, server)
You may want to remove 'scroller' from Options = () as with that many rows, you may want to break it up into pages. Also, you can try to make the table server processing by putting Server = TRUE in there, that will make it process every page versus the whole dataset at once.

Issue filtering DT datatable with horizontal scroll in Rshiny

In my Rshiny dashboard I want to display a wide table (>15 columns) in a DT DataTable having filters on top and horizontal scrolling on. When I now want to apply the filter all columns are suddenly visible in the area outside the width of the table.
Here's an example that shows the problem:
library(shiny)
library(DT)
runApp(shinyApp(
ui = fluidPage(
DT::dataTableOutput("results", width = 300)
),
server = function(input, output){
output$results <- DT::renderDataTable(
mtcars,
filter = "top",
options = list(scrollX = TRUE,
dom = 'Brtip')
)
}
))
Is this an unfixed problem in DT or is there a way how I could fix this in the given code example?

Add Cell Borders in an R Datatable

Fairly new to R - doing OK with big picture stuff, and struggling on cleaning up the edges when I want to present something to other people.
Banging my head against the wall with something that's probably pretty simple - I simply want to add cell borders - to all cells - in a datatable in a shiny app. Here's a relevant chunk of code:
library(ggplot2)
library(shiny)
library(data.table)
library(DT)
library(plotly)
setwd("C:/Users/Will/Desktop/FinalPages")
lister <- read.table("PlayerList.csv", header=TRUE, quote ="", sep=",",fill = TRUE)
totals <- read.table("TotShooting.csv", header=TRUE, quote ="", sep=",",fill = TRUE)
items <- as.character(lister[[1]])
ui <- fluidPage(
sidebarLayout(
sidebarPanel(selectizeInput("players", "Player:", choices = items, multiple = FALSE),
width=2
),
mainPanel(h5("Total Shooting", align = "center"),
div(dataTableOutput("tot"), style = "font-size:80%", class = 'table-condensed cell-border row-border'),
position="center",
width = 10)
)
)
server <- function(input, output) {
output$tot <- DT::renderDataTable({
validate(
need(input$players, ' ')
)
filterone <- subset(totals, Name == input$players)
filterone <- filterone[,-1:-2]
DT::datatable(filterone,
rownames = FALSE,
options=list(iDisplayLength=7,
bPaginate=FALSE,
bLengthChange=FALSE,
bFilter=FALSE,
bInfo=FALSE,
rowid = FALSE,
autoWidth = FALSE,
ordering = FALSE,
scrollX = TRUE,
borders = TRUE,
columnDefs = list(list(className = 'dt-center', targets ="_all"))
))
}
)
I've been trying to track it down via google, but haven't been able to hit on a solution I can get to work. It's probably something very simple with tags, or a correct class name (I hope so, at least), but I'm lost here. Appreciate any help I can get.
The function that you are looking for is : formatStyle("your DT table", "vector of column index", border = '1px solid #ddd').
You can find a reproducible example here :
library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
DT::dataTableOutput("test")
),
server = function(input, output, session) {
output$test <- DT::renderDataTable({
datatable(mtcars) %>%
formatStyle(c(1:dim(mtcars)[2]), border = '1px solid #ddd')
})
})
There must be more elegant ways but it works !

Resources