Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freezing header and first column using data.table in Shiny

I have a Shiny app that yields a data table, but I can't freeze the first column and the headers, so the table is hard to read as you go down or across. Is there anyway to freeze the panes? I've tried searching but have found nothing.

like image 755
Kamal Avatar asked Oct 07 '14 04:10

Kamal


2 Answers

Interesting question and now thanks to the recent update of Shiny to data.tables 1.10.2 it is alot easier to use the various plug-ins and extensions. For your question the FixedHeader extension seems ideal. To add this extension we need to include the relevant JavaScript and CSS file (see http://cdn.datatables.net/):

tagList(
  singleton(tags$head(tags$script(src='//cdn.datatables.net/fixedheader/2.1.2/js/dataTables.fixedHeader.min.js',type='text/javascript'))),
  singleton(tags$head(tags$link(href='//cdn.datatables.net/fixedheader/2.1.2/css/dataTables.fixedHeader.css',rel='stylesheet',type='text/css')))
)

data.tables has an option initComplete which allows us to stipulate a callback once table is drawn etc.

function(settings, json) {
     new $.fn.dataTable.FixedHeader(this, {
                                            left:   true,
                                            right:  true
                                          } );
                                        }

We will use a modified version of the iris data set adding an index and some random data at the end to show left to right scrolling:

library(shiny)
myData <- cbind(list(index = row.names(iris)), iris
                , rep(list(row.names(iris)), 10))
names(myData)[7:16] <- paste0("randomData", 1:10)
runApp(
  list(ui = fluidPage(
    tagList(
      singleton(tags$head(tags$script(src='//cdn.datatables.net/fixedheader/2.1.2/js/dataTables.fixedHeader.min.js',type='text/javascript'))),
      singleton(tags$head(tags$link(href='//cdn.datatables.net/fixedheader/2.1.2/css/dataTables.fixedHeader.css',rel='stylesheet',type='text/css')))
    ), 

    dataTableOutput("mytable")
  )
  , server = function(input, output, session){
    output$mytable <- renderDataTable(myData,
                                      options = list(
                                        pageLength = 50,
                                        initComplete = I("function(settings, json){
                                          new $.fn.dataTable.FixedHeader(this, {
                                            left:   true,
                                            right:  true
                                          } );
                                        }")
                                      )
    )
  })
)

so in the image we can see we are scrolled down to record 8 and across some ways but the header and the first column (our added index column) are still visible.

enter image description here

like image 55
jdharrison Avatar answered Nov 01 '22 01:11

jdharrison


FixedHeader is now (2021) compatible with FixedColumns. See table

library(shiny)
library(DT)
runApp(
  list(ui = fluidPage(
    
    dataTableOutput("mytable")
  )
  , server = function(input, output, session){
    Rows <- c(1:30)
    for (y in 1:15){
      x<-y-1
      assign(letters[x+1],runif(5, 0, 1))
    }
    x <- data.frame(Rows, mget(letters[1:15]), row.names=NULL) 
    x<- x[2:15]
    output$mytable <- renderDataTable(
      DT::datatable(x, rownames=FALSE,extensions = c('FixedColumns',"FixedHeader"), 
                    options = list(dom = 't', 
                                   scrollX = TRUE, 
                                   paging=FALSE,
                                   fixedHeader=TRUE,
                                   fixedColumns = list(leftColumns = 1, rightColumns = 0))
      )
    )
  } 
  )
)

Implemented:

2021-09-10: FixedColumns 4.0.0

like image 11
Ferroao Avatar answered Nov 01 '22 01:11

Ferroao