[Edit]
I tried to simplify my code as much as possible:
server.R :
server <- function(input, output, session) {
output$body_UI<-renderUI({
tabPanel("Comparison",
{
fluidPage(
fluidRow(
box(
width=12,
solidHeader=T,
title="Parameters",
status="primary",
uiOutput('date_range_UI')
)
)
)
}
)})
output$date_range_UI <-renderUI({
dateRangeInput(
"date_1",
"Period 1",
start=NULL,
end=NULL
)
})
}
ui.R:
uiHeader <- dashboardHeader(title = NULL)
uiSidebar <- dashboardSidebar(sidebarMenuOutput('sidebar_UI'))
uiBody <- dashboardBody(
tags$head(
tags$style(type="text/css"
),
tags$link(rel = "stylesheet", type = "text/css", href = "style_v2.css")
),
uiOutput('body_UI')
)
dashboardPage(uiHeader,
uiSidebar,
uiBody,
skin = "black")
I think that my problem comes from the file style_v2.css :
.progress-bar, .irs-bar,.irs-bar-edge, .irs-from, .irs-to, .irs-single{
background-color:#000033;
}
.box.box-solid.box-primary>.box-header
{
background-color:#000033;
}
.box.box-solid.box-primary{
border: 1px solid #000033;
}
.box.box-primary, .nav-tabs-custom>.nav-tabs>li.active
{
border-top-color:#000033;
}
body {
background-color: #fff;
}
.content-wrapper, .right-side{
background-color:#FFFFFF;
}
.dropdown-menu{
background-color:#333;
}
This file is located in the folder 'www' which is in the same directory than server.R and ui.R.
If I delete this file, then I have no problem. But I need it and I don't know which part is causing this.
I'm trying to insert a period field using dateRangeInput (Shiny).
But I'm having problems in the display.
NB: I encounter the same problem using dateInput.
Here is an extract of server.R:
dateRangeInput(
"date_1",
"Period 1",
start=min(data$Date_processed),
end=""
)
This is completely illegible...
The issue is with this piece of code in your style_v2.css file:
.dropdown-menu {
background-color: #333;
}
#333 is the dark background you are seeing. You can either remove this or edit the hex colour to be lighter.
If that code is necessary for other dropdowns in your code you can be more specific regarding your css - let me know.
Related
I have a basic R shiny app that I would like to build a light/ dark mode switch for. I think if I can just get it working for the table tab it should be fine to do for the rest. I am aware that shinyjs is the best way to go about it but I can't seem to find the code anywhere.
library(dplyr)
library(shiny)
library(shinythemes)
ui <- fluidPage(theme = shinytheme("slate"),
tags$head(tags$style(HTML(
"
.dataTables_length label,
.dataTables_filter label,
.dataTables_info {
color: white!important;
}
.paginate_button {
background: white!important;
}
thead {
color: white;
}
"))),
mainPanel(tabsetPanel(
type = "tabs",
tabPanel(
title = "Table",
icon = icon("table"),
tags$br(),
DT::DTOutput("table")
)
)))
server <- function(input, output) {
output$table <- DT::renderDT({
iris
})
}
shinyApp(ui = ui, server = server)
EDITED: see notes at the end
If you want to use bootstrap themes, it's possible to do this using a checkbox input and a javascript event that adds/removes <link> elements (i.e., the html element that loads the bootstrap css theme). I switched the shinytheme to darkly as there's a corresponding light theme (flatly). I removed the css that you defined in tags$head as that will be added/removed based on the theme toggle. (see full example below)
Even though this works, there are likely performance issues. Be aware that each time the theme is changed, the file is fetched and reloaded into the browser. There are also style differences between themes, this may cause content to be reorganized or moved slightly when new theme is applied (this may be disruptive for the user). If you were to choose this approach, I would recommend finding a well-designed light and dark theme combo.
Alternatively, you can select a basic bootstrap theme and define your own css themes. You can use a toggle (like this example) or the media query prefers-color-scheme. Then the shinyjs class functions, you can toggle themes from the R server. This approach is often recommended, but does take a bit longer to develop and validate.
Using the bootstrap approach, here's how you could switch themes.
app.R
In the ui, I created a checkbox input and placed it as the last element (for example purposes).
checkboxInput(
inputId = "themeToggle",
label = icon("sun")
)
JS
To switch the bootstrap themes, I defined the html dependency paths defined by the shinythemes package. You can find these in your R package library (library/shinythemes/).
const themes = {
dark: 'shinythemes/css/darkly.min.css',
light: 'shinythemes/css/flatly.min.css'
}
To load a new theme, the paths need to be rendered as an html element. We will also need a function that removes an existing css theme. The easiest way to do that is to select the element that has a matching href as defined in the themes variable.
// create new <link>
function newLink(theme) {
let el = document.createElement('link');
el.setAttribute('rel', 'stylesheet');
el.setAttribute('text', 'text/css');
el.setAttribute('href', theme);
return el;
}
// remove <link> by matching the href attribute
function removeLink(theme) {
let el = document.querySelector(`link[href='${theme}']`)
return el.parentNode.removeChild(el);
}
I also removed the styles defined in the tags$head and created a new <style> element in js.
// css themes (originally defined in tags$head)
const extraDarkThemeCSS = ".dataTables_length label, .dataTables_filter label, .dataTables_info { color: white!important;} .paginate_button { background: white!important;} thead { color: white;}"
// create new <style> and append css
const extraDarkThemeElement = document.createElement("style");
extraDarkThemeElement.appendChild(document.createTextNode(extraDarkThemeCSS));
// add element to <head>
head.appendChild(extraDarkThemeElement);
Lastly, I created an event and attached it to the checkbox input. In this example, checked = 'light' and unchecked = 'dark'.
toggle.addEventListener('input', function(event) {
// if checked, switch to light theme
if (toggle.checked) {
removeLink(themes.dark);
head.removeChild(extraDarkThemeElement);
head.appendChild(lightTheme);
} else {
// else add darktheme
removeLink(themes.light);
head.appendChild(extraDarkThemeElement)
head.appendChild(darkTheme);
}
})
Here's the full app.R file.
library(dplyr)
library(shiny)
library(shinythemes)
ui <- fluidPage(
theme = shinytheme("darkly"),
mainPanel(
tabsetPanel(
type = "tabs",
tabPanel(
title = "Table",
icon = icon("table"),
tags$br(),
DT::DTOutput("table")
)
),
checkboxInput(
inputId = "themeToggle",
label = icon("sun")
)
),
tags$script(
"
// define css theme filepaths
const themes = {
dark: 'shinythemes/css/darkly.min.css',
light: 'shinythemes/css/flatly.min.css'
}
// function that creates a new link element
function newLink(theme) {
let el = document.createElement('link');
el.setAttribute('rel', 'stylesheet');
el.setAttribute('text', 'text/css');
el.setAttribute('href', theme);
return el;
}
// function that remove <link> of current theme by href
function removeLink(theme) {
let el = document.querySelector(`link[href='${theme}']`)
return el.parentNode.removeChild(el);
}
// define vars
const darkTheme = newLink(themes.dark);
const lightTheme = newLink(themes.light);
const head = document.getElementsByTagName('head')[0];
const toggle = document.getElementById('themeToggle');
// define extra css and add as default
const extraDarkThemeCSS = '.dataTables_length label, .dataTables_filter label, .dataTables_info { color: white!important;} .paginate_button { background: white!important;} thead { color: white;}'
const extraDarkThemeElement = document.createElement('style');
extraDarkThemeElement.appendChild(document.createTextNode(extraDarkThemeCSS));
head.appendChild(extraDarkThemeElement);
// define event - checked === 'light'
toggle.addEventListener('input', function(event) {
// if checked, switch to light theme
if (toggle.checked) {
removeLink(themes.dark);
head.removeChild(extraDarkThemeElement);
head.appendChild(lightTheme);
} else {
// else add darktheme
removeLink(themes.light);
head.appendChild(extraDarkThemeElement)
head.appendChild(darkTheme);
}
})
"
)
)
server <- function(input, output) {
output$table <- DT::renderDT({
iris
})
}
shinyApp(ui, server)
EDITS
In this example, I used a checkBoxInput. You can "hide" the input using the following css class. I would recommend adding a visually hidden text element to make this element accessible. The UI would be changed to the following.
checkboxInput(
inputId = "themeToggle",
label = tagList(
tags$span(class = "visually-hidden", "toggle theme"),
tags$span(class = "fa fa-sun", `aria-hidden` = "true")
)
)
Then add the css following css. You can also select and style the icon using #themeToggle + span .fa-sun
/* styles for toggle and visually hidden */
#themeToggle, .visually-hidden {
position: absolute;
width: 1px;
height: 1px;
clip: rect(0 0 0 0);
clip: rect(0, 0, 0, 0);
overflow: hidden;
}
/* styles for icon */
#themeToggle + span .fa-sun {
font-size: 16pt;
}
Here's the updated ui. (I removed the js to make the example shorter)
ui <- fluidPage(
theme = shinytheme("darkly"),
tags$head(
tags$style(
"#themeToggle,
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
clip: rect(0 0 0 0);
clip: rect(0, 0, 0, 0);
overflow: hidden;
}",
"#themeToggle + span .fa-sun {
font-size: 16pt;
}"
)
),
mainPanel(
tabsetPanel(
type = "tabs",
tabPanel(
title = "Table",
icon = icon("table"),
tags$br(),
DT::DTOutput("table")
)
),
checkboxInput(
inputId = "themeToggle",
label = tagList(
tags$span(class = "visually-hidden", "toggle theme"),
tags$span(class = "fa fa-sun", `aria-hidden` = "true")
)
)
),
tags$script("...")
)
You can dynamically switch between bootstrap themes by downloading their CSS files from here, putting them into a folder in your project and using includeCSS in a dynamically generated UI chunk:
library(dplyr)
library(shiny)
library(shinythemes)
ui <- fluidPage(
theme = shinytheme("flatly"),
uiOutput("style"),
tags$head(
tags$style(
HTML(
"
.dataTables_length label,
.dataTables_filter label,
.dataTables_info {
color: white!important;
}
.paginate_button {
background: white!important;
}
thead {
color: white;
}
"
)
)
),
mainPanel(
tabsetPanel(
type = "tabs",
tabPanel(
title = "Table",
icon = icon("table"),
tags$br(),
DT::DTOutput("table")
)
),
checkboxInput("style", "Dark theme")
)
)
server <- function(input, output) {
output$table <- DT::renderDT({
iris
})
output$style <- renderUI({
if (!is.null(input$style)) {
if (input$style) {
includeCSS("www/darkly.css")
} else {
includeCSS("www/flatly.css")
}
}
})
}
shinyApp(ui = ui, server = server)
From what I understand, this will solve the problem.
The advantage of this approach is that if you remove the checkbox and then generate it again, it will still work. Personally, I was going to use dcruvolos helpful solution in my app until I realised that I can't use it with shiny.router because as soon as you temporarily remove the checkbox from the UI, the JS code stops working (if I understand correctly).
Here is a checkbox in the form of a uiOutput that you can add or remove and it will continue working:
library(dplyr)
library(shiny)
library(shinythemes)
ui <- fluidPage(
theme = shinytheme("flatly"),
uiOutput("style"),
tags$head(
tags$style(
HTML(
"
.dataTables_length label,
.dataTables_filter label,
.dataTables_info {
color: white!important;
}
.paginate_button {
background: white!important;
}
thead {
color: white;
}
"
)
)
),
mainPanel(
tabsetPanel(
type = "tabs",
tabPanel(
title = "Table",
icon = icon("table"),
tags$br(),
DT::DTOutput("table")
)
),
uiOutput("style_checkbox")
)
)
server <- function(input, output) {
output$table <- DT::renderDT({
iris
})
current_theme <- reactiveVal(FALSE)
output$style_checkbox <- renderUI({
checkboxInput("style", "Dark theme", value = current_theme())
})
output$style <- renderUI({
if (!is.null(input$style)) {
current_theme(input$style)
if (input$style) {
includeCSS("www/darkly.css")
} else {
includeCSS("www/flatly.css")
}
}
})
}
shinyApp(ui = ui, server = server)
I made the following script to show 1.pdf, but nothing shows up after clicking on start.
Any comments would be great.
Appreciate!
shinyApp(
ui <- function(){
tagList(tabPanel(""),
pageWithSidebar(
headerPanel(
""
),
sidebarPanel
(
tags$head(tags$style(type="text/css", ".well { max-width: 280px; }")),
actionButton("strt", label = "Start",style="width:32%;"),
actionButton("logout", "Logout",style="color: red; width:32%;")
),
mainPanel(tableOutput('path'))
)
)
},
server = (function(input, output,session) {
observeEvent(input$strt, {
output$path <- renderUI({tags$iframe(src="E:/shiny/Correct/www/1.pdf",style="height:800px; width:100%;scrolling=yes")})
})
})
)
I solved it as follows:
observeEvent(input$strt, {
addResourcePath("pdf_folder","E:/shiny/Correct")
output$path <- renderUI({tags$iframe(src="pdf_folder/1.pdf",style="height:800px; width:100%;scrolling=yes")})
})
I want to change the font family of the title of my Valuebox to Nexa Bold, and the subtitle of the valuebox to Fs Albert. I know this font family is non standard, so please what should I write in the css file given that I am beginner to HTML and css.
Thank you
Here is a reproductible example
require(shiny)
require(shinydashboard)
header <- dashboardHeader(title="ReproductibleExample")
sidebar <- dashboardSidebar(disable=T)
body <- dashboardBody(
includeCSS("C:/Users/Ccic/Shiny Interface Beta 06_04_2017/Dahsborad/www/custom.css"),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "custom.css")
),
valueBoxOutput("box_01"),
textOutput("print"))
ui <- dashboardPage(header, sidebar, body)
server<-shinyServer(function(input, output,session) {
output$box_01=renderValueBox({
valueBox("Probability ","80%",
icon("glyphicon glyphicon-oil", lib="glyphicon"), color = "red" )
})
})
shinyApp(ui,server)
and here is my css file :
.box.box-solid.box-success>.box-header {
font-family: 'Nexa Bold', sans-serif;
color:#fff;
background:#586F7C
}
.box.box-solid.box-success{
border-bottom-color:#586F7C;
border-left-color:#586F7C;
border-right-color:#586F7C;
border-top-color:#586F7C;
}
.small-box.bg-red { background-color: #AEB4A9 !important; color: #FFFFFF !important; }
but it does not work for me !
I am using R-3.2.0 hosted on Red Hat Linux version 6.5 with shiny package (version 0.12.0). I am trying to utilize shinydashboard functionality to design a few reports. The RStudio version is 0.98.1103
I have successfully setup ui.R and server.R
ui.R - :
ibrary(shinydashboard)
library(htmlwidgets)
library(rpivotTable)
library(leaflet)
dashboardPage(
dashboardHeader(title="Reports",
dropdownMenu(type = "task",
messageItem(
from = "Download",
message = "test",
icon = icon("gear")
),
messageItem(
"Download",
message = "TEST",
icon = icon("life-ring"),
href= "http://www.google.com"
)
)
),
dashboardSidebar(
sidebarMenu(
menuItem("Srts", tabName = "ServiceItems", icon = icon("dashboard"))
)
),
dashboardBody(
tags$head(tags$style(
type = 'text/css',
'#test{ overflow-x: scroll; }')),
rpivotTableOutput('PivotTable')
)
)
server.R -:
library(shiny)
library(ggplot2)
library(wordcloud)
library(devtools)
library(htmlwidgets)
library(rpivotTable)
library(leaflet)
shinyServer(function(input, output) {
PivotTable <- read.csv("Book2.csv",head=TRUE,sep= ',')
output$PivotTable <- rpivotTable::renderRpivotTable({
rpivotTable(PivotTable, rows="Ar", col="DTM", aggregatorName="Count",
vals="Ar", rendererName="Table")})
tableFirst<-as.data.frame(sort(table(PivotTable$Area),decreasing=TRUE))
})
The following code to enable scrolling in the dashboard body was taken from https://github.com/smartinsightsfromdata/rpivotTable/issues/19 :-
tags$head(tags$style(
type = 'text/css',
'#test{ overflow-x: scroll; }')),
rpivotTableOutput('PivotTable')
The issue I face is that the code added to help scrolling does not work. I have stripped my code of all tabs , layouts etc but I am still enable to get scrolling to work.
I have observed that if I remove the dashboardPage command, scrolling does work but the display is very awkward and not really presentable.
However, when I combine the codes as follows (in RStudio) and run the scrolling works just fine.
library(shiny)
library(shinydashboard)
library(rpivotTable)
library(ggplot2)
PivotTable <- read.csv("Book2.csv",head=TRUE,sep= ',')
header <- dashboardHeader(title="Reports",
dropdownMenu(type = "task",
messageItem(
from = "Download",
message = "test",
icon = icon("gear")
),
messageItem(
"Download",
message = "TEST",
icon = icon("life-ring"),
href= "http://www.google.com"
)
)
)
sidebar <- dashboardSidebar()
body <- dashboardBody(
tags$head(tags$style(HTML('
.skin-blue.main-header .logo {
background-color: #3c8dbc;
}
.skin-blue .main-header .logo:hover {
background-color: #3c8dbc;
}
'))
),
tags$head(tags$style(type = 'text/css',
'#test{ overflow-x: scroll; }')),
rpivotTableOutput("test")
)
shinyApp(
ui = dashboardPage(header, sidebar, body),
server = function(input, output) {
output$test <- rpivotTable::renderRpivotTable({
rpivotTable(PivotTable, rows="Ar", col="DTM", aggregatorName="Count",vals="Ar", rendererName="Table")})
})
However, I cannot provide this as a final solution because the business users that need this are not adept at copying and pasting code on RStudio (If there is a possible way that I can use the combined code just like the usual one I can consider that as well).
Can someone please help me understand the issue with my original code that prevents scrolling.
Thanks a lot !
The problem is your CSS selector otherwise everything looks OK. Your setting the scroll-property on a element with ID test but I can't find a element with this ID in your example. Try something like this:
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
dashboardSidebar(),
dashboardBody(
tags$head(
tags$style(
HTML("
#myScrollBox{
overflow-y: scroll;
overflow-x: hidden;
height:120px;
}
")
)
),
# Boxes need to be put in a row (or column)
fluidRow(
div(id="myScrollBox",
plotOutput("plot1", height = 250)),
box(
title = "Controls",
sliderInput("slider", "Number of observations:", 1, 100, 50)
)
)
)
)
server <- function(input, output) {
set.seed(122)
histdata <- rnorm(500)
output$plot1 <- renderPlot({
data <- histdata[seq_len(input$slider)]
hist(data)
})
}
shinyApp(ui, server)
You need to change the CSS selector to the element you want to put the scroll on, in the example this is "myScrollBox".
The only thing which you should be taking in to consideration is to pass the exact same id before CSS code, so in this code replace #test to #PivotTable and bingo... your code should work...
tags$head(tags$style(
type = 'text/css',
'#test{ overflow-x: scroll; }')),
rpivotTableOutput('PivotTable')
I try to make a loading screen as in this nice example http://daattali.com:3838/loading-screen/. Unfortunately I cannot figure out how to do exactly the same effect with 'navbarPage'.
In this slightly modified app below there are two tab panels called "start" and "end". When the app starts none of the tab panels are active. One have to quickly click on the first tab to see the loading screen but this is not what I would like. Is there a way to make it so quick and easy as in the mentioned example?
Thank you for the help!
library(shinyjs)
appCSS <- "
#loading-content {
position: absolute;
background: #000000;
opacity: 0.9;
z-index: 100;
left: 0;
right: 0;
height: 100%;
text-align: center;
color: #FFFFFF;
}
"
shinyApp(
ui = navbarPage(
useShinyjs(),
inlineCSS(appCSS),
tabPanel(title = "Start",
# Loading message
div(
id = "loading-content",
h2("Loading...")
),
# The main app code goes here
div(
id = "app-content",
p("This is a simple example of a Shiny app with a loading screen."),
p("You can view the source code",
tags$a(href = 'https://github.com/daattali/shiny-server/blob/master/loading-screen',
"on GitHub")
)
)
),
tabPanel(title = "End",
h2("Second tab"))
),
server = function(input, output, session) {
# Simulate work being done for 1 second
Sys.sleep(2)
# Hide the loading message when the rest of the server function has executed
hide(id = "loading-content", anim = TRUE, animType = "fade")
}
)
EDIT: The original link to the loading screen app has been taken down. It can now be accessed on github here
Well, I believe that you will enjoy with this solution but it is not perfect. The key is the tagList, you can add whatever you want before the navbar.
Furthermore I add the padding to your CSS code and now, there is a title in the navbar.
Unfortunately the navbarPage is not possible to hide of a not complex way.
library(shiny)
library(shinyjs)
appCSS <- "
#loading-content {
position: absolute;
padding: 10% 0 0 0;
background: #000000;
opacity: 0.9;
z-index: 100;
left: 0;
right: 0;
height: 100%;
text-align: center;
color: #FFFFFF;
}
"
shinyApp(
ui =
tagList(
useShinyjs(),
inlineCSS(appCSS),
# Loading message
div(
id = "loading-content",
h2("Loading...")
),
navbarPage("Test",
tabPanel(title = "Start",
# The main app code goes here
div(
id = "app-content",
p("This is a simple example of a Shiny app with a loading screen."),
p("You can view the source code",
tags$a(href = 'https://github.com/daattali/shiny-server/blob/master/loading-screen',
"on GitHub")
)
)
),
tabPanel(title = "End",
h2("Second tab"))
) #close navbarPage
), #close tagList
server = function(input, output, session) {
# Simulate work being done for 1 second
Sys.sleep(5)
# Hide the loading message when the rest of the server function has executed
hide(id = "loading-content", anim = TRUE, animType = "fade")
}
)