In my Shiny UI I have
ui <- checkboxGroupInput("my_cbgi", "Choose Something", c("A", "B", "C", "D"))
And I would like it so that the choices (the text) A and B are colored red, but C and D are not. I tried HTML but then in the UI weird boxes like "attribs" and "children" showed up.
Thanks in advance
Since shiny_1.0.1, checkboxGroupInput have a choiceNames and choiceValues arguments for passing arbitrary UI to display to the user, check this example :
library("shiny")
ui <- fluidPage(
checkboxGroupInput(
inputId = "my_cbgi",
label = "Choose Something",
choiceNames = list(
tags$span("A", style = "color: red;"),
tags$span("B", style = "color: red;"),
tags$span("C", style = "color: blue;"),
tags$span("D", style = "font-weight: bold;")
),
choiceValues = c("A", "B", "C", "D")
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Great Victorp, I improved your answer adding a varying behaviour to it.
library("shiny")
my.options <- c('A', 'B', 'C')
my.colors <- c('red', 'green', 'blue')
my.fun <- function() {
res <- list()
for (o in my.options) {
res[[length(res)+1]] <- tags$span(o,
style = paste0('color: ', my.colors[which(my.options == o)],';'))
}
res
}
ui <- fluidPage(
checkboxGroupInput(inputId = "myId", label = "Options",
choiceNames = my.fun(),
choiceValues = my.colors
)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
Related
The code at the bottom works as desired except for widget alignment, as illustrated below. Any recommendations for how to align all widgets together in-line (except for the necessary wrapping which is working fine in the code) as illustrated and described below? In the illustration, the red describes what I'd like to change, and the black are just some casual observations.
Code:
library(rhandsontable)
library(shiny)
rowNames1 <- c("A", "B", "C", "Sum")
data1 <- data.frame(row.names = rowNames1, "Col 1" = c(1, 1, 0, 2), check.names = FALSE)
ui <- fluidPage(
actionButton("addTbl", "Add table"),
rHandsontableOutput("hottable1"),
tags$div(id = "placeholder")
)
server <- function(input, output) {
uiTbl1 <- reactiveValues(base = data1)
observeEvent(input$hottable1,{uiTbl1$base <- hot_to_r(input$hottable1)})
output$hottable1 <- renderRHandsontable({
rhandsontable(uiTbl1$base, rowHeaderWidth = 100, useTypes = TRUE)
})
observeEvent(input$addTbl, {
divID <- gsub("\\.", "", format(Sys.time(), "%H%M%OS3"))
dtID <- paste0(divID, "DT")
uiTbl1[[paste0(divID,"tbl")]] <- data1
insertUI(
selector = "#placeholder",
ui = tags$div(
id = divID,
style = "display:inline-block;
margin-right: 10px;
margin-top: 10px;
vertical-align: top;",
rHandsontableOutput(dtID),
hr()
)
)
output[[dtID]] <- renderRHandsontable({
req(uiTbl1[[paste0(divID,"tbl")]])
rhandsontable(uiTbl1[[paste0(divID,"tbl")]], rowHeaderWidth = 100, useTypes = TRUE)
})
})
}
shinyApp(ui, server)
Reflecting S. Laurent's solution in the comments, below is complete code including alignment parameters for super-clean output of multiple dynamic tables:
Code:
library(rhandsontable)
library(shiny)
rowNames1 <- c("A", "B", "C", "Sum")
data1 <- data.frame(row.names = rowNames1, "Col 1" = c(1, 1, 0, 2), check.names = FALSE)
ui <- fluidPage(
br(), actionButton("addTbl", "Add table"),
tags$div(id = "placeholder",
tags$div(
style = "display: inline-block;
margin-right: 6px;
margin-top: 10px;
vertical-align: top;",
rHandsontableOutput("hottable1")
)
)
)
server <- function(input, output) {
uiTbl1 <- reactiveValues(base = data1)
observeEvent(input$hottable1,{uiTbl1$base <- hot_to_r(input$hottable1)})
output$hottable1 <- renderRHandsontable({
rhandsontable(uiTbl1$base,rowHeaderWidth = 100, useTypes = TRUE)
})
observeEvent(input$addTbl, {
divID <- gsub("\\.", "", format(Sys.time(), "%H%M%OS3"))
dtID <- paste0(divID, "DT")
uiTbl1[[paste0(divID,"tbl")]] <- data1
insertUI(
selector = "#placeholder",
ui = tags$div(
id = divID,
style = "display:inline-block;
margin-right: 10px;
margin-top: 10px;
vertical-align: top;",
rHandsontableOutput(dtID)
)
)
output[[dtID]] <- renderRHandsontable({
req(uiTbl1[[paste0(divID,"tbl")]])
rhandsontable(uiTbl1[[paste0(divID,"tbl")]],rowHeaderWidth = 100, useTypes = TRUE)
})
})
}
shinyApp(ui, server)
Illustration of the addition of 10 dynamic tables:
I am trying with the below code.
library(shiny)
app <- shinyApp(
ui = fluidPage(
DT::dataTableOutput("mydatatable")
),
server = shinyServer(function(input, output, session) {
mycars <- reactive({ head(mtcars)})
output$mydatatable = DT::renderDataTable(mycars(), selection = 'single',
rownames = FALSE, options = list(dom = 't'))
selected_row <- reactiveVal(value = NULL)
observeEvent(input$mydatatable_rows_selected,{
selected_row(input$mydatatable_rows_selected)
})
observeEvent(selected_row(),
{
showModal(modalDialog(
title = "You have selected a row!",
ifelse(
mycars()$mpg[selected_row()] > 21,
tags$div(HTML(paste('cyl = ', tags$span(style = "color:red", mycars()$cyl[selected_row()]), sep = ""))),
tags$div(HTML(paste('cyl = ', tags$span(style = "color:blue", mycars()$cyl[selected_row()]), sep = "")))
)
))
})
})
)
app
Here I am trying to change color of 'cyl' value to red if 'mpg' value is greater than 21 else 'cyl' value will print in blue.
I have tried with few html codes but failed.
Thanks!
For this purpose the dataframe does not have to be reactive, so I removed that part in here. Make use of the formatStyle functionality:
app <- shinyApp(
ui = fluidPage(
DT::dataTableOutput("mydatatable")
),
server = shinyServer(function(input, output, session) {
mycars <- mtcars
output$mydatatable = DT::renderDataTable(datatable(mycars) %>%
formatStyle('cyl', 'mpg',
color = styleInterval(21.001, c('blue', 'red'))),
selection = 'single',
rownames = FALSE, options = list(dom = 't'))
})
)
app
I have generated few plots using plotly and saved them as offline html (I don't want to generate them live as it would take so long to generate them in the background). The followings are the two plots taken from plotly site and I saved them as html.
#Graph 1
Animals <- c("giraffes", "orangutans", "monkeys")
SF_Zoo <- c(20, 14, 23)
LA_Zoo <- c(12, 18, 29)
data <- data.frame(Animals, SF_Zoo, LA_Zoo)
p <- plot_ly(data, x = ~Animals, y = ~SF_Zoo, type = 'bar', name = 'SF Zoo') %>%
add_trace(y = ~LA_Zoo, name = 'LA Zoo') %>%
layout(yaxis = list(title = 'Count'), barmode = 'group')
htmlwidgets::saveWidget(p, file="zoo.html")
#Graph 2
x <- c('Product A', 'Product B', 'Product C')
y <- c(20, 14, 23)
text <- c('27% market share', '24% market share', '19% market share')
data <- data.frame(x, y, text)
p <- plot_ly(data, x = ~x, y = ~y, type = 'bar', text = text,
marker = list(color = 'rgb(158,202,225)',
line = list(color = 'rgb(8,48,107)',
width = 1.5))) %>%
layout(title = "January 2013 Sales Report",
xaxis = list(title = ""),
yaxis = list(title = ""))
htmlwidgets::saveWidget(p, file="product.html")
I have written some shiny codes that can show html output from Rmarkdown but not the html that i generated from plotly above. Note that the first choice(sample) in the selectInput() is what I generated from default Rmarkdown html and that works. I also generated multiple rmarkdown html and I could also switch between htmls in the shiny app but not for plotly html.
ui= fluidPage(
titlePanel("opening web pages"),
sidebarPanel(
selectInput(inputId='test',label=1,choices=c("sample","zoo","product"))
),
mainPanel(
htmlOutput("inc")
)
)
server = function(input, output) {
getPage<-function() {
return(includeHTML(paste0("file:///C:/Users/home/Documents/",input$test,".html")))
}
output$inc<-renderUI({getPage()})
}
shinyApp(ui, server)
You can use an iframe for this - also have a look at addResourcePath:
ui = fluidPage(
titlePanel("opening web pages"),
sidebarPanel(selectInput(
inputId = 'test',
label = 1,
choices = c("sample", "zoo", "product")
)),
mainPanel(htmlOutput("inc"))
)
server = function(input, output) {
myhtmlfilepath <- getwd() # change to your path
addResourcePath('myhtmlfiles', myhtmlfilepath)
getPage <- function() {
return(tags$iframe(src = paste0("myhtmlfiles/", input$test, ".html"), height = "100%", width = "100%", scrolling = "yes"))
}
output$inc <- renderUI({
req(input$test)
getPage()
})
}
shinyApp(ui, server)
I am wondering if there is a way to remove the index column (1st column) from the data table in Shiny.
For example, column of (1, 2, 3) before Name column as shown in the screenshot below:
Below is my code:
header <- dashboardHeader(
title = "Test"
)
sidebar <- dashboardSidebar(
)
body <- dashboardBody(
box(title = "Test", width = 7, status = "warning", DT::dataTableOutput("df"))
)
# UI
ui <- dashboardPage(header, sidebar, body)
# Server
server <- function(input, output, session) {
output$df = DT::renderDataTable(df, options = list(
autoWidth = TRUE,
columnDefs = list(list(width = '10px', targets = c(1,3)))))
}
# Shiny dashboard
shiny::shinyApp(ui, server)
Thanks in advance.
There is some excellent documentation of the package available at https://rstudio.github.io/DT/ I would highly recommend reading through.
At any rate, use the rownames = FALSE argument provided by the DT package as follows:
library(shinydashboard)
library(DT)
df <- mtcars
header <- dashboardHeader(
title = "Test"
)
sidebar <- dashboardSidebar(
)
body <- dashboardBody(
box(title = "Test", width = 7, status = "warning", DT::dataTableOutput("df"))
)
# UI
ui <- dashboardPage(header, sidebar, body)
# Server
server <- function(input, output, session) {
output$df = DT::renderDataTable(df, rownames = FALSE,
options = list(
autoWidth = TRUE,
columnDefs = list(list(width = '10px', targets = c(1,3)))))
}
# Shiny dashboard
shiny::shinyApp(ui, server)
After the success of the dynamic box in shiny here : R/Shiny : Color of boxes depend on select I need you to use these boxes but in a loop.
Example :
I have an input file which give this :
BoxA
BoxB
BoxC
I want in the renderUI loop these values as a variable to generate dynamically a Box A, B and C. (if I have 4 value, i will have 4 boxes etC.)
Here is my actually code:
for (i in 1:nrow(QRSList))
{
get(QRSOutputS[i]) <- renderUI({
column(4,
box(title = h3(QRSList[1], style = "display:inline; font-weight:bold"),
selectInput("s010102i", label = NULL,
choices = list("Non commencé" = "danger", "En cours" = "warning", "Terminé" = "success"),
selected = 1) ,width = 12, background = "blue", status = get(QRSIntputS[i])))
})
column(4,
observeEvent(input$s010102i,{
get(QRSOutputS[i]) <- renderUI({
box(title = h3(QRSList[1], style = "display:inline; font-weight:bold"),
selectInput("s010102i", label = NULL,
choices = list("Not good" = "danger", "average" = "warning", "good" = "success"),
selected = get(QRSIntputS[i])) ,width = 12, background = "blue",status = get(QRSIntputS[i]))
})
The aim is to replace these box names to a variable like input$s010102 for example. But get and assign function does not exist.
Any idea ?
Thanks a lot
Here is an example how to generate boxes dynamically
library(shinydashboard)
library(shiny)
QRSList <- c("Box1","Box2","Box3","Box4","Box5")
ui <- dashboardPage(
dashboardHeader(title = "render Boxes"),
dashboardSidebar(
sidebarMenu(
menuItem("Test", tabName = "Test")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "Test",
fluidRow(
tabPanel("Boxes",uiOutput("myboxes"))
)
)
)
)
)
server <- function(input, output) {
v <- list()
for (i in 1:length(QRSList)){
v[[i]] <- box(width = 3, background = "blue",
title = h3(QRSList[i], style = "display:inline; font-weight:bold"),
selectInput(paste0("slider",i), label = NULL,choices = list("Not good" = "danger", "average" = "warning", "good" = "success"))
)
}
output$myboxes <- renderUI(v)
}
shinyApp(ui = ui, server = server)