I'm using rhandsontable with dqshiny to display a large table in an app.
I put some code below. In this code, there are maybe 4 scroll-bars. 2 in the table and 2 on the outer page.
I only want 2 scroll-bars, can someone help? I have been messing with the CSS for hours to try and get the filters to show but also have scrollbars.
library(shiny)
library(rhandsontable)
library(shinythemes)
library(shinyjs)
library(dqshiny)
df = data.frame(hello1 = seq(100), stringsAsFactors = FALSE)
df2 = df
for(i in 1:30){
df = cbind(df, df2)
}
names(df) = paste0(names(df), seq(20))
shinyApp(
ui = fluidPage(
theme = shinytheme("cerulean"),
navbarPage("sample Rhandsontable Page", selected = "tab01",
id = "navbar",
position = "fixed-top",
tags$style(type="text/css", "body {padding-top: 70px;}"),
tags$head(
tags$style(
#"body {overflow-y: scroll;}"
"body {overflow: visible;}"
)
),
tags$head(
tags$style(type = "text/css", ".container-fluid {padding-left:0px;
padding-right:0px; margin-right:0px; margin-left:0px;}")
),
useShinyjs(),
tabPanel("tab01",
tags$head(tags$style("#randomTable-filters {overflow:visible !important;}")),
tags$style('#randomTableTags * { white-space: nowrap}'),
tags$style('.shiny-html-output * {width = 100% }'),
div(id='randomTableTags', style="overflow: visible;",
dq_handsontable_output("randomTable")
)
)
)
),
server = function(input, output, session) {
dq_render_handsontable(
"randomTable",
df,
filters = "T",
page_size = c(500L, 1000L),
width_align = TRUE,
horizontal_scroll = FALSE,
table_param = list(highlightRow = TRUE, autoColumnSize = TRUE),
)
}
)
here is an image of the output:
If you have trouble with dqshiny, you can run:
library(devtools)
devtools::install_github('daqana/dqshiny', upgrade = 'always')
Solution 1: You can add this in your css file. It should be applicable to all handsontable in your app.
.handsontable {
overflow: hidden;
}
Solution 2: You can use stretcH in your code to avoid extra scroll bars.
rhandsontable(data,stretchH = "all",stretchV = "all")
Related
I am trying to stylize my UI in a shiny app that I am making. I had previously built a fairly comprehensive map that I now have to modularize to improve readability by setting the map background as a transparent layer. Unfortunately, I cannot seem to understand how to go about applying CSS styles while using modules.
mapUI <- function(id) {
ns <- NS(id)
leafletOutput(ns("map"),width =250 , height = 250))
}
basin <- rgdal::readOGR("data/basin.kml", "basin")
ui <- pagePiling(
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "style.css")),
sections.color = c('#f2f2f2', '#2C3E50', '#39C'),
opts = options,
menu = c("Start" = "start",
"Station 1" = "station1",
"Station 2" = "station2"
),
pageSectionImage(
center = TRUE,
img = "image1.jpg",
menu = "start",
mapUI("map1")
),
pageSectionImage(
center = TRUE,
img ="image2.jpg",
menu = "station1",
mapUI("map2")
),
pageSectionImage(
center = TRUE,
img ="image3.jpg",
menu = "station2",
mapUI("map3")
)
)
server <- function(input, output){
mapServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
output$map<-renderLeaflet({
leaflet(options = leafletOptions(zoomControl = FALSE, minZoom = 5, maxZoom = 5))%>%
addPolygons(data = basin,color = "white",weight = 2,opacity = 1,fillOpacity = 0.9 )
})
})
}
mapServer("map1")
mapServer("map2")
}
here is the style.css that doesn't work for me!
#bottommap-map{
background: rgba(0,0,0,0.05);
}
In my shiny app I display a table (reactable) with an expandable row. I would like to change the background color for certain words, therefor I use html spans. It works fine for the text in the regular row, in the expandable row however only the plain html code is displayed.
I set html = TRUE for both columns yet is not displayed correctly. How do I make it work?
app.R
library(shiny)
library(htmltools)
library(reactable)
ui <- fluidPage(
reactableOutput("table")
)
server <- function(input, output) {
output$table <- renderReactable({
df = data.frame("title" = c("This is the <span style='background-color:yellow;'>Title</span>", "This is a longer Title"),
"abstract" = c("This is the <span style='background-color:yellow;'>abstract</span>", "This is an even longer abstract"))
reactable(
df,
columns = list(
abstract = colDef(show = F, html = TRUE),
title = colDef( html = TRUE)
),
details = function(index) {
htmltools::div(style= "background-color:white",
htmltools::tags$div(style= "background-color:#eee; padding: .9em; border-color: #ffe;", df[index, "abstract"])
)
}
)
})
}
Using the html function from here we can do -
library(shiny)
library(htmltools)
library(reactable)
html <- function(x, inline = FALSE) {
container <- if (inline) htmltools::span else htmltools::div
container(dangerouslySetInnerHTML = list("__html" = x))
}
ui <- fluidPage(
reactableOutput("table")
)
server <- function(input, output) {
output$table <- renderReactable({
df = data.frame("title" = c("This is the <span style='background-color:yellow;'>Title</span>", "This is a longer Title"),
"abstract" = c("This is the <span style='background-color:yellow;'>abstract</span>", "This is an even longer abstract"))
reactable(
df,
columns = list(
abstract = colDef(show = F, html = TRUE),
title = colDef( html = TRUE)
),
details = function(index) {
htmltools::div(style= "background-color:white",
htmltools::tags$div(style= "background-color:#eee; padding: .9em; border-color: #ffe;",
html(df[index, "abstract"]))
)
}
)
})
}
shinyApp(ui,server)
I have placed 3 button icons in wellpanel.
The problem is all the 3 icons do not appear in one single row ("screenshot" icon appears in the first line where the next 2 icons appear in the second row).
I tried aligning with "fixedRow" and "style" but could not achieve.
Can anyone please help me to do this?
Thanks...
Script:
TableA = data.frame(Product = c('iPhone', 'Macbook', 'Airpod', 'Macbook', 'Airpod', 'Macbook', 'iPhone'), East = c(1:7), West = c(5:11), North = c(15:21), South = c(24:30))
library(shiny)
library(shinythemes)
library(DT)
library(rhandsontable)
library(tidyverse)
library(tidyquant)
library(knitr)
library(gt)
library(shinycssloaders)
library(shinydashboard)
library(shinyWidgets)
header = dashboardHeader(title = 'Shiny Dashboard', titleWidth = 400)
sidebar = dashboardSidebar(
wellPanel(
"Export Options", id = "DownloadPanel", style = "background: #222d32; max-height: 145px; max-width: 220px; align-items: center",
fixedRow(tags$div(style="display: inline-block; vertical-align:center; horizontal-align:center", class = "row-fluid",
screenshotButton(selector="#TableC", label = NULL, filename = paste("Summary")),
downloadButton(outputId = "SummaryExcelDownload", label = NULL, icon = icon("file-excel"), class = "butt1",
tags$head(tags$style(".butt{background-color:white;} .butt1{color: #217346 !important;}"))),
downloadButton(outputId = "SummaryPdfDownload", label = NULL, icon = icon("file-pdf"), class = "butt2",
tags$head(tags$style(".butt{background-color:white;} .butt2{color: #b30c00 !important;}")))
))
)
)
body <- dashboardBody(uiOutput("mainpanel"))
ui = dashboardPage(header, sidebar, body)
############
server = function(input, output, session)
{
output$mainpanel = renderUI({
fluidRow(tabBox(width = 250, height = 100,
tabPanel("Apple Sales", value = 'tab1', gt_output(outputId = "TableC")%>% withSpinner(color="#3483CA", type = 1, size = 2))
))
})
TableB = as.data.frame(TableA) %>%
gt() %>%
grand_summary_rows(columns = 2:5, fns = list(TotalSales = "sum")) %>%
tab_options(grand_summary_row.background.color = "#DDEBF7") %>%
cols_width(columns = 1 ~ px(1), columns = 2 ~ px(300), everything() ~ px(100)) %>%
tab_spanner(label = "Sales", columns = 3:6)
output$TableC = render_gt(expr = TableB)
output$SummaryExcelDownload = downloadHandler(
filename = "Summary.pdf",
content = function(file) {write.xlsx(TableC, file)})
output$SummaryPdfDownload = downloadHandler(
filename = "Summary.pdf",
content = function(file) {write.xlsx(TableC, file)})
}
############
shinyApp(ui = ui, server = server)
Output:
Note:
Please ignore the "server" arguments for excel and pdf downloads (output$SummaryExcelDownload and output$SummaryPdfDownload) as I'm still exploring to correct the same.
Try this
library(shinyscreenshot)
header = dashboardHeader(title = 'Shiny Dashboard', titleWidth = 400)
sidebar = dashboardSidebar( width=300,
h5(strong("If you want to see buttons in a row, just use div()")),
fluidRow(div(
div(style="display: inline-block; width: 135px ;", screenshotButton("btn21", "Buttons")),
div(style="display: inline-block; width: 75px ;", downloadButton("btn22", "in a")),
div(style="display: inline-block; width: 75px ;", downloadButton("btn23", "row"))
)),
div(style="display: inline-block; vertical-align:center; horizontal-align:center", class = "row-fluid",
actionButton("btn11", "Buttons"),
actionButton("btn12", "in a"),
actionButton("btn13", "col")
),
div(
div(style="display: inline-block; width: 95px ;", actionButton("btn31", "Buttons")),
div(style="display: inline-block; width: 75px ;", actionButton("btn32", "in a")),
div(style="display: inline-block; width: 65px ;", actionButton("btn33", "row"))
)
)
body <- dashboardBody()
ui = dashboardPage(header, sidebar, body)
server <- function(input, output) {}
shinyApp(ui, server)
Is it possible to display different image as title of the shiny dashboard based on the tabPanel() that you use. I want different image for the tab 'Front' and different for the tab 'Data'.
# app.R ##
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(DT)
library(shinyWidgets)
library(shinyjs)
dbHeader <- dashboardHeaderPlus(
enable_rightsidebar = TRUE,
rightSidebarIcon = "gears",
fixed = T,
title = tags$a(href='http://mycompanyishere.com',
tags$img(src='logo.png'))
)
ui <- dashboardPagePlus(
dbHeader,
dashboardSidebar(),
dashboardBody(
useShinyjs(),
tags$hr(),
tabsetPanel(
id ="tabA",
type = "tabs",
tabPanel("Front",icon = icon("accusoft")),
tabPanel("Data", icon = icon("table")
)
)
),
rightsidebar = rightSidebar()
)
server <- function(input, output) {
observe({
if (input$tabA == "Front") {
hide(selector = "body > div.wrapper > header > nav > div:nth-child(4) > ul")
addClass(selector = "body", class = "sidebar-collapse")
removeClass(selector = "body", class = "control-sidebar-open")
} else {
show(selector = "body > div.wrapper > header > nav > div:nth-child(4) > ul")
removeClass(selector = "body", class = "sidebar-collapse")
addClass(selector = "body", class = "control-sidebar-open")
}
})
}
shinyApp(ui = ui, server = server)
So one way to achieve this is by using shinyjs and modify CSS in Shiny reactive output.
In order to do so, I've first "borrowed" this function
# This part is from the link below and will be used to modify CSS in reactive part
# https://stackoverflow.com/questions/31425841/css-for-each-page-in-r-shiny
modifyStyle <- function(selector, ...) {
values <- as.list(substitute(list(...)))[-1L]
parameters <- names(values)
args <- Map(function(p, v) paste0("'", p,"': '", v,"'"), parameters, values)
jsc <- paste0("$('",selector,"').css({", paste(args, collapse = ", "),"});")
shinyjs::runjs(code = jsc)
}
And then using two functions below (inside observe() function in server side part) I've modified CSS in the reactive output using CSS code:
# Show one picture.
# NOTE:if using your own picture modify the path inside url().. See the code below.
modifyStyle(".logo img ", "content" = "url(https://dotunroy.files.wordpress.com/2015/05/happy-people.jpg)")
# Show another picture
modifyStyle(".logo img ", "content" = "url(test.png)")
Note that, in order for me to show that the code works, first I needed to have some pictures. So I've saved one picture inside my www directory (the picture is called test.png (see the above code)). And another is available from this link https://dotunroy.files.wordpress.com/2015/05/happy-people.jpg.
So the whole code looks like this (again, in order for you to display images, replace the path of my images inside url() with your own)
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(DT)
library(shinyWidgets)
library(shinyjs)
# Modify the CSS style of a given selector
# This part is from
# https://stackoverflow.com/questions/31425841/css-for-each-page-in-r-shiny
modifyStyle <- function(selector, ...) {
values <- as.list(substitute(list(...)))[-1L]
parameters <- names(values)
args <- Map(function(p, v) paste0("'", p,"': '", v,"'"), parameters, values)
jsc <- paste0("$('",selector,"').css({", paste(args, collapse = ", "),"});")
shinyjs::runjs(code = jsc)
}
dbHeader <- dashboardHeaderPlus(
enable_rightsidebar = TRUE,
rightSidebarIcon = "gears",
fixed = T,
title = tags$a(href='http://mycompanyishere.com',
# Modify the width and the height of the image as you like
tags$img(src='test.png', width ="50%", height = "70%"))
)
ui <- dashboardPagePlus(
dbHeader,
dashboardSidebar(),
dashboardBody(
useShinyjs(),
tags$hr(),
tabsetPanel(
id ="tabA",
type = "tabs",
tabPanel("Front",icon = icon("accusoft")),
tabPanel("Data", icon = icon("table")
)
)
),
rightsidebar = rightSidebar()
)
server <- function(input, output) {
observe({
if (input$tabA == "Front") {
hide(selector = "body > div.wrapper > header > nav > div:nth-child(4) > ul")
addClass(selector = "body", class = "sidebar-collapse")
removeClass(selector = "body", class = "control-sidebar-open")
modifyStyle(".logo img ", "content" = "url(https://dotunroy.files.wordpress.com/2015/05/happy-people.jpg)")
# shinyjs::toggleClass(selector = "head", class = "logo",
# condition = (input$tabA == "Front"))
} else {
show(selector = "body > div.wrapper > header > nav > div:nth-child(4) > ul")
removeClass(selector = "body", class = "sidebar-collapse")
addClass(selector = "body", class = "control-sidebar-open")
modifyStyle(".logo img ", "content" = "url(test.png)")
}
})
}
shinyApp(ui = ui, server = server)
And the output is:
UPDATE
Note that if you want to modify the width and the height of the image, just add these two parameters in CSS, i.e.
# Add a custom number of the percentage to width and height parameters
modifyStyle(".logo img ", "content" =
"url(https://dotunroy.files.wordpress.com/2015/05/happy-people.jpg)",
"width" = "100%", "height" = "100%")
I'm using the splitLayout() function within a dashboardSidebar() from the shinydashboard package. When I do, there is a significant gap between inputs within my splitLayout().
When I used vanilla shiny, I could control this gap with parameter cellArgs = list(style="padding: 0px") but this seems to have a different effect within a dashboardSidebar().
Question:
How can I control the gap between inputs inside a splitLayout() within a dashboardSidebar()?
Here is a MRE which shows my unsuccessful attempts at using padding
library(shinydashboard)
library(shiny)
sidebar <- dashboardSidebar(width=400,
sidebarMenu(
menuItem("Default", tabName = "dashboard", icon = icon("dashboard"),startExpanded = T,
splitLayout(cellWidths = c(100,100,100,100),
textInput("a1",label=NULL,value = 1),
textInput("a2",label=NULL,value = 2),
textInput("a3",label=NULL,value = 3),
textInput("a4",label=NULL,value = 4)
),
splitLayout(cellWidths = c(100,100,100,100),cellArgs = list(style="padding: 0px"),
textInput("b1",label=NULL,value = 1),
textInput("b2",label=NULL,value = 2),
textInput("b3",label=NULL,value = 3),
textInput("b4",label=NULL,value = 4)
),
#see the effect of padding
splitLayout(cellWidths = c(100,100,100,100),cellArgs = list(style="padding: 20px"),
textInput("c1",label=NULL,value = 1),
textInput("c2",label=NULL,value = 2),
textInput("c3",label=NULL,value = 3),
textInput("c4",label=NULL,value = 4)
)
)
)
)
body <- dashboardBody(
)
# Put them together into a dashboardPage
ui <- dashboardPage(
dashboardHeader(title = "Padding demo",titleWidth=400),
sidebar,
body
)
server <- function(input, output) {
}
shinyApp(ui,server)
your problem is not the padding of the the splitCells - that is working fine. It has more to do with that the inputs also have padding around them. To remove this you can add the following code
body <- dashboardBody(
tags$head(
tags$style(
".shiny-input-container{padding:0px !important;}"
)
)
)
hope this helps