I want to be able to navigate to a particular sidebar from the Navbar action button.
I know bs4Dash is a bootstrapping theme, but I am trying to customize a dashboard by moving the sidebar to the top of the navbar.
The only way I know possible is using action buttons like what I have done so far. However, in doing so I still haven't been able to successfully toggle to the right sidebar.
Here is the code
library(shiny)
library(bs4Dash)
shinyApp(
ui = bs4DashPage(
header = bs4DashNavbar(
skin = "light",
status = "white",
border = FALSE,
sidebarIcon = icon("bars"),
compact = FALSE,
controlbarIcon = icon("th"),
actionButton(inputId = "controlbarToggle", label = "Toggle Controlbar", class = "mx-2"),
actionButton(inputId = "socialcardToggle", label = "Toggle Tab 2", class = "mx-2"),
actionButton(inputId = "controlbarToggle", label = "Toggle Controlbar", class = "mx-2")
),
sidebar = bs4DashSidebar(
inputId = "sidebar",
disable = FALSE,
title = "My Dashboard",
skin = "light",
status = "primary",
brandColor = NULL,
url = NULL,
src = "https://cdn-icons-png.flaticon.com/512/2922/2922561.png",
elevation = 4,
opacity = 0.8,
expand_on_hover = TRUE,
bs4SidebarUserPanel(
image = "https://cdn-icons-png.flaticon.com/512/2922/2922510.png",
name = "Dennis"
),
bs4SidebarMenu(
id = "sidebarmenu",
bs4SidebarHeader("Menu1"),
bs4SidebarMenuItem(
"Tab 1",
tabName = "tab1",
icon = icon("user")
#startExpanded = FALSE
),
bs4SidebarMenuItem(
"Tab 2",
tabName = "tab2",
icon = icon("user")
#startExpanded = FALSE
)
)
),
controlbar = bs4DashControlbar(
"Text",
inputId = "controlbar",
disable = FALSE,
skin = "dark",
title = "Controlbar",
width = 250
),
footer = bs4DashFooter(left = "#Dennis", right = NULL),
title = "Basic Dashboard",
body = bs4DashBody(
bs4TabItems(
bs4TabItem(
tabName = "tab1",
bs4Card(
title = "Closable Box Tab 1 with dropdown",
closable = TRUE,
width = 12,
status = "warning",
solidHeader = FALSE,
collapsible = TRUE,
labelText = 1,
labelStatus = "danger",
labelTooltip = "Hi Bro!",
dropdownIcon = "wrench",
p("Box Content")
)
),
bs4TabItem(
tabName = "tab2",
bs4Card(
title = "Closable Box Tab 2 with dropdown",
closable = TRUE,
width = 12,
status = "warning",
solidHeader = FALSE,
collapsible = TRUE,
labelText = 1,
labelStatus = "danger",
labelTooltip = "Hi Bro!",
dropdownIcon = "wrench",
p("Box Content Tab 2")
)
)
)
)
),
server = function(input, output, session) {
observeEvent(input$controlbarToggle, {
updateControlbar(id = "controlbar")
})
observe(print(input$sidebar))
observe(print(input$sidebarmenu))
}
)
Thanks for your assistance in advance.
Related
There is this weird sort of overlap with header and sidebar and I just want clean lines and borders between the sidebar and header. When the close the sidebar the black part still appears and it shouldn't really.
Here is my code:
header = dashboardHeader(title = HTML("Shiny Seurat"), titleWidth = 140, tags$li(tags$a(href='http://mycompanyishere.com',tags$img(src="https://marcomm.wustl.edu/wp-content/uploads/2015/07/1lineposRGB1000-01-23yyr3u-e1517349355451.png", height = "60px", align = "right")), class = "dropdown"))
sidebar = dashboardSidebar(width = 150,
sidebarMenu(id = "sidebar",
menuItem("Upload", tabName = "Upload", icon = icon("Upload")),
menuItem("Colors", tabName = "Colors", icon = icon("Colors")),
menuItem("PCA", tabName = "PCA", icon = icon("PCA")),
menuItem("TSNE",icon = icon("TSNE"), menuSubItem("TSNE",tabName = "TSNE", icon = icon("TSNE")),
menuSubItem("TSNE-Plot",tabName = "TSNE-Plot", icon = icon("TSNE"))),
menuItem("UMAP", icon = icon("UMAP"),
menuSubItem("UMAP", tabName = "UMAP", icon = icon("UMAP")),
menuSubItem("Plot", tabName = "Plot", icon = icon("UMAP"))),
menuItem("Expression", tabName = "Expression", icon = icon("Expression")),
menuItem("Differential", tabName = "Differential", icon = icon("Differential"))))
This would fix it:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(
title = HTML("Shiny Seurat"),
titleWidth = 140,
tags$li(
tags$a(
id = "top-logo",
href='http://mycompanyishere.com',
style = "padding-top: 0",
tags$img(src="https://marcomm.wustl.edu/wp-content/uploads/2015/07/1lineposRGB1000-01-23yyr3u-e1517349355451.png", style = "height: 50px; float:right")
),
class = "dropdown")
),
dashboardSidebar(
width = 150, sidebarMenu(
id = "sidebar",
menuItem("Upload", tabName = "Upload", icon = icon("Upload")),
menuItem("Colors", tabName = "Colors", icon = icon("Colors")),
menuItem("PCA", tabName = "PCA", icon = icon("PCA")),
menuItem("TSNE",icon = icon("TSNE"), menuSubItem("TSNE",tabName = "TSNE", icon = icon("TSNE")),
menuSubItem("TSNE-Plot",tabName = "TSNE-Plot", icon = icon("TSNE"))),
menuItem("UMAP", icon = icon("UMAP"),
menuSubItem("UMAP", tabName = "UMAP", icon = icon("UMAP")),
menuSubItem("Plot", tabName = "Plot", icon = icon("UMAP"))),
menuItem("Expression", tabName = "Expression", icon = icon("Expression")),
menuItem("Differential", tabName = "Differential", icon = icon("Differential"))
)
),
dashboardBody(
tags$style(
"
#top-logo:hover {background: rgb(60 141 188)}
"
)
)
)
server <- function(input, output) { }
shinyApp(ui, server)
I am trying to add a navlistPanel to a box() in bs4Dash and when I set the column width to 12, the tabItems squeeze next to each other like this:
Adding the widths = c(4,8) argument to navlistPanel also gives me the same result. If I set the column width to 4 or less, the navlistPanel is properly formatted.
My goal is to have a box() with column = 12 and a vertical tab menu inside it with width = 4 and have the tabs look correct.
I've also tried using tabsetPanel with vertical = TRUE, but the content doesn't show up in the right location, it shows up below. See picture #2:
Reprexes for both are below:
library(shiny)
library(bs4Dash)
ui <- dashboardPage(
header = dashboardHeader(
title = dashboardBrand(
title = "My dashboard",
color = "primary",
href = "https://adminlte.io/themes/v3",
image = "https://adminlte.io/themes/v3/dist/img/AdminLTELogo.png"
)),
sidebar = bs4DashSidebar(),
controlbar = dashboardControlbar(),
body = dashboardBody(fluidRow(column(
12,
box(
title = "Title",
status = "primary",
solidHeader = TRUE,
collapsible = FALSE,
maximizable = TRUE,
color = "white",
height = 175,
width = NULL,
navlistPanel(
"Header",
tabPanel("First"),
tabPanel("Second"),
tabPanel("Third")
)
)
))),
help = FALSE,
dark = NULL,
scrollToTop = FALSE
)
server = function(input, output, session) {
}
shinyApp(ui, server)
library(shiny)
library(bs4Dash)
ui <- dashboardPage(
header = dashboardHeader(
title = dashboardBrand(
title = "My dashboard",
color = "primary",
href = "https://adminlte.io/themes/v3",
image = "https://adminlte.io/themes/v3/dist/img/AdminLTELogo.png"
)),
sidebar = bs4DashSidebar(),
controlbar = dashboardControlbar(),
body = dashboardBody(fluidRow(column(
12,
box(
title = "Title",
status = "primary",
solidHeader = TRUE,
collapsible = FALSE,
maximizable = TRUE,
color = "white",
height = 175,
width = NULL,
tabsetPanel(
id = NULL,
vertical = TRUE,
tabPanel("First",
"The content is below and I want it to the right of the tabset"),
tabPanel("Second"),
tabPanel("Third")
)
)
))),
help = FALSE,
dark = NULL,
scrollToTop = FALSE
)
server = function(input, output, session) {
}
shinyApp(ui, server)
I am trying to make a multipage shiny dashboard. I would like the sidebar to collapse when you pick a page, with the ability to reopen it to pick a new page. For example, when you pick page 2 the sidebar collapses and you can reopen it later if you want to go back to page 1. Right now it is stuck open, i.e. when you click page 2 the sidebar does not collapse. I used useShinyjs(), which is what I thought makes it collapsible with no luck. Any help is much appreciated :)
library(shiny)
library(dplyr)
library(shiny)
library(shinydashboard)
library(shinyjs)
library(shinyWidgets)
library(shinyBS)
library(plotly)
Stores <- data.frame(Store = c("Store 1", "Store 2", "Store 3", "Store 4", "Store 5"),
Sales = c(8247930, 423094, 204829, 903982, 7489472, 429085, 208955, 7492852, 5285034, 2958275,1598753, 28487593, 4892049, 583042, 509275, 5904728, 5098325, 5920947, 4920946, 2049583),
Avg_cust = c(325,542,582,482,904, 594, 304, 493, 690, 403, 694, 104, 493, 596, 403, 506, 304, 305, 632, 478),
Year = c(rep(2012,5), rep(2013,5), rep(2014,5), rep(2015,5)))
ui <- dashboardPage(
header = dashboardHeader(
title = "Store Performance",
titleWidth = "100%"),
sidebar = dashboardSidebar(
useShinyjs(),
width = 200,
collapsed = FALSE,
sidebarMenu(id = "tabs",
menuItem("Page 1", tabName = "pg1"),
menuItem("Page 2", tabName = "pg2"))),
skin = "black",
body = dashboardBody(
useShinyjs(),
tabItems(
tabItem("pg1",
fluidRow(
column(width = 3,
box(
title = "Options",
status = 'warning',
solidHeader = TRUE,
width = 12,
collapsible = FALSE,
collapsed = FALSE,
pickerInput(
inputId = "YR",
label = "Year:",
choices = c(2012,2013,2014,2015),
selected = 2015,
multiple = FALSE))),
column(width = 9,
boxPlus(plotlyOutput("All"),
status = 'warning',
width = 12,
solidHeader = TRUE,
collapsible = FALSE,
closable = FALSE,
collapsed = FALSE)))),
tabItem("pg2",
fluidRow(
column(width = 9,
boxPlus(title = "Add graph here",
width = 12,
status = "warning",
solidHeader = TRUE,
collapsible = FALSE,
closable = FALSE,
collapsed = FALSE)),
column(width = 3,
box(
title = "Options",
status = 'warning',
solidHeader = TRUE,
width = 12,
collapsible = FALSE,
collapsed = FALSE,
pickerInput(
inputId = "st",
label = "Store:",
choices = unique(Stores$Store),
selected = "Store 1",
multiple = FALSE
))))))))
server <- function(input, output) {
observeEvent({
input$YR
},
output$All <- renderPlotly({
plot_ly(Stores[Stores$Year == input$YR,], x = ~Avg_cust, y = ~Sales,
hoverinfo = "text", text = ~Store)%>%
layout(title = "Store Performance",
xaxis = list(title = "Customers"),
yaxis = list(title = "Sales"))
})
)
}
shinyApp(ui = ui, server = server)
Only using useShinyjs() doesn't do the trick. It only sets up shinyjs, but you need to tell it what to do. The idea here is to add the class "sidebar-collapse" to the body, as this hides the sidebar. The sidebar should always been hidden if a tab was switched, so have to add an observer that listens if a tab was switched. Then you can use shinyjs to add the class with addClass. The input of the tabswitch is the id of the sidebarMenu:
library(shiny)
library(dplyr)
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyjs)
library(shinyWidgets)
library(shinyBS)
library(plotly)
Stores <- data.frame(Store = c("Store 1", "Store 2", "Store 3", "Store 4", "Store 5"),
Sales = c(8247930, 423094, 204829, 903982, 7489472, 429085, 208955, 7492852, 5285034, 2958275,1598753, 28487593, 4892049, 583042, 509275, 5904728, 5098325, 5920947, 4920946, 2049583),
Avg_cust = c(325,542,582,482,904, 594, 304, 493, 690, 403, 694, 104, 493, 596, 403, 506, 304, 305, 632, 478),
Year = c(rep(2012,5), rep(2013,5), rep(2014,5), rep(2015,5)))
ui <- dashboardPage(
header = dashboardHeader(
title = "Store Performance"),
sidebar = dashboardSidebar(
width = 200,
collapsed = FALSE,
sidebarMenu(id = "tabs",
menuItem("Page 1", tabName = "pg1"),
menuItem("Page 2", tabName = "pg2"))),
skin = "black",
body = dashboardBody(
useShinyjs(),
tabItems(
tabItem("pg1",
fluidRow(
column(width = 3,
box(
title = "Options",
status = 'warning',
solidHeader = TRUE,
width = 12,
collapsible = FALSE,
collapsed = FALSE,
pickerInput(
inputId = "YR",
label = "Year:",
choices = c(2012,2013,2014,2015),
selected = 2015,
multiple = FALSE))),
column(width = 9,
box(plotlyOutput("All"),
status = 'warning',
width = 12,
solidHeader = TRUE,
collapsible = FALSE,
closable = FALSE,
collapsed = FALSE)))),
tabItem("pg2",
fluidRow(
column(width = 9,
box(title = "Add graph here",
width = 12,
status = "warning",
solidHeader = TRUE,
collapsible = FALSE,
closable = FALSE,
collapsed = FALSE)),
column(width = 3,
box(
title = "Options",
status = 'warning',
solidHeader = TRUE,
width = 12,
collapsible = FALSE,
collapsed = FALSE,
pickerInput(
inputId = "st",
label = "Store:",
choices = unique(Stores$Store),
selected = "Store 1",
multiple = FALSE
))))))))
server <- function(input, output) {
output$All <- renderPlotly({
plot_ly(Stores[Stores$Year == input$YR,], x = ~Avg_cust, y = ~Sales,
hoverinfo = "text", text = ~Store)%>%
layout(title = "Store Performance",
xaxis = list(title = "Customers"),
yaxis = list(title = "Sales"))
})
observeEvent(input$tabs, {
addClass(selector = "body", class = "sidebar-collapse")
})
}
shinyApp(ui = ui, server = server)
BTW: you also need the package shinydashboardPlus. Also, I removed your observer because I don't know what you want to achieve. Lastly, I reduced the width of the header, because otherwise the button to show the sidebar is hidden.
For more information how it works, have a look here and here.
I have a shinydashboard that looks like this:
# Packages
library(shinydashboard)
library(tidyverse)
library(readxl)
library(scales)
theme_set(theme_light())
header <- dashboardHeader(
title = "Test App",
titleWidth = 215
)
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("Test Tab", tabName = "test_tab",
icon = icon("paper-plane"), startExpanded = TRUE)
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName = "test_tab",
fluidRow(
column(width = 4,
h2("Column X"),
valueBoxOutput("first_value", width = NULL),
box(flexdashboard::gaugeOutput("second_value", width = "90%", height = "100px"),
title = "Second Value", status = "primary", solidHeader = TRUE,
collapsible = FALSE, width = NULL
)
),
column(width = 8,
h2("Column Y"),
box(
title = "#3", status = "primary", solidHeader = TRUE,
collapsible = FALSE, width = 4
),
box(
title = "#4", status = "primary", solidHeader = TRUE,
collapsible = FALSE, width = 4
)
)
),
fluidRow(
h2("Row A"),
column(width = 12,
box(title = "Third Value", status = "primary", solidHeader = TRUE,
width = 2.4),
box("Fourth Value", status = "primary", solidHeader = TRUE,
width = 2.4),
box("Fifth Value", status = "primary", solidHeader = TRUE,
width = 2.4),
box("Sixth Value", status = "primary", solidHeader = TRUE,
width = 2.4),
box("Seventh Value", status = "primary", solidHeader = TRUE,
width = 2.4)
)
)
)
)
)
# Put them together into a dashboardPage
ui <- dashboardPage(skin = "blue", header = header,
sidebar = sidebar,
body = body)
server <- function(input, output) {
output$first_value <- renderValueBox({
valueBox(
comma_format()(100000),
subtitle = "First Value",
icon = icon("list"), color = "purple"
)
})
output$second_value = flexdashboard::renderGauge({
flexdashboard::gauge(0.12 * 100,
symbol = '%',
min = 0,
max = 100)
})
}
shinyApp(ui, server)
I'm trying to get the box()es below RowA to line up in a five column format, like this:
Third Value | Fourth Value | Fifth Value | Sixth Value
I'm not sure how I'd do that here. I've tried to put 5 boxes inside column() inside a fluidRow() which should work, but unfortunately, the boxes keep on showing up horizontally...
Is there anyway to display the boxes in column format? If not, can you guide me to other functions that resemble what I have?
You've specified your column widths for each of these five boxes to be 2.4 (12/5 I guess).
Column widths should be whole numbers. If you substitute 2 for 2.4 it'll work fine.
Note that you will have an empty column to the right of box 5 corresponding to the 2 (12 - 2*5) positions left over.
This is based on bootstrap column layout. For more information see this tutorial.
I am trying to build a dashboard using semantic.dashboard library. I see that all the components are aligned at the center. How can I change the layout?
I have taken the following code from examples in the semantic.dashboard repo. It works absolutely fine when I run it. I see that there is a space between the sidebar menu and boxes in the main body. I want the components to be aligned without any space from the side bar menu. Is there any way I could achieve this?
library(shiny)
library(shiny.semantic)
library(semantic.dashboard)
library(ggplot2)
library(plotly)
library(DT)
ui <- dashboardPage(
dashboardHeader(
dropdownMenuOutput("dropdown"),
dropdownMenu(type = "notifications",
taskItem("Project progress...", 50.777, color = "red")),
dropdownMenu(
icon = uiicon("red warning sign"),
notificationItem("This is an important notification!", color = "red")
)
),
dashboardSidebar(side = "left",
sidebarMenu(
menuItem(
tabName = "plot_tab",
text = "My plot",
icon = icon("home")
),
menuItem(
tabName = "table_tab",
text = "My table",
icon = icon("smile")
)
)),
dashboardBody(tabItems(
tabItem(tabName = "plot_tab",
fluidRow(
valueBox(
"Unread Mail",
44,
icon("mail"),
color = "blue",
width = 5
)
),
fluidRow(
box(
title = "Sample box",
color = "blue",
width = 11,
selectInput(
inputId = "variable1",
choices = names(mtcars),
label = "Select first variable",
selected = "mpg"
),
selectInput(
inputId = "variable2",
choices = names(mtcars),
label = "Select second variable",
selected = "cyl"
),
plotlyOutput("mtcars_plot")
),
tabBox(
title = "Sample box",
color = "blue",
width = 5,
collapsible = FALSE,
tabs = list(
list(menu = "First Tab", content = "Some text..."),
list(menu = "Second Tab", content = plotlyOutput("mtcars_plot2"))
)
)
)),
tabItem(
tabName = "table_tab",
fluidRow(
valueBox(
"Unread Mail",
144,
icon("mail"),
color = "blue",
width = 6,
size = "small"
),
valueBox(
"Spam",
20,
icon("mail"),
color = "red",
width = 5,
size = "small"
),
valueBox(
"Readed Mail",
666,
icon("mail"),
color = "green",
width = 5,
size = "small"
)
),
fluidRow(
box(
title = "Classic box",
color = "blue",
ribbon = FALSE,
title_side = "top left",
width = 14,
tags$div(
dataTableOutput("mtcars_table")
,
style = paste0("color:", semantic_palette[["blue"]], ";")
)
)
)
)
)),
theme = "slate"
)
server <- function(input, output) {
output$mtcars_plot <-
renderPlotly(plot_ly(
mtcars,
x = ~ mtcars[, input$variable1],
y = ~ mtcars[, input$variable2],
type = "scatter",
mode = "markers"
))
output$mtcars_plot2 <-
renderPlotly(plot_ly(
mtcars,
x = ~ mtcars[, input$variable1],
y = ~ mtcars[, input$variable2],
type = "scatter",
mode = "markers"
))
output$mtcars_table <-
renderDataTable(mtcars, options = list(dom = 't'))
output$dropdown <- renderDropdownMenu({
dropdownMenu(
messageItem("User", "Test message", color = "teal", style = "min-width: 200px"),
messageItem("Users", "Test message", color = "teal", icon = "users"),
messageItem(
"See this",
"Another test",
icon = "warning",
color = "red"
)
)
})
}
shinyApp(ui, server)
It looks like the issue is behind the dashboardBody function. It uses a ui stackable container grid for each tab which is causing the large amount of padding.
There are two ways around it:
Hack around the dashboardBody function and remove "container" from the class:
dash_body <- function (...) {
shiny::div(
class = "pusher container", style = "min-height: 100vh;",
shiny::div(
class = "ui segment", style = "min-height: 100vh;",
shiny::tags$div(class = "ui stackable grid", ...)
),
semantic.dashboard:::body_js
)
}
Add CSS to remove the padding for this class (add first row in the dashboardBody arguments):
tags$style(".pusher.container .ui.segment .ui.stackable.container.grid {margin:0px!important;}")