如何在 shiny 中组合顶部导航 (navbarPage) 和侧边栏菜单 (sidebarMenu)
How to combine top navigation (navbarPage) and a sidebar menu (sidebarMenu) in shiny
我有一个闪亮的应用程序(使用 navbarPage),它有很多选项卡,我想添加一个侧边栏菜单,无论选择哪个选项卡都可以看到。侧边栏中的输入值会影响所有选项卡的内容。
此外,应该可以隐藏 sidebarMenu,因为它在 shinydashboard 中。
我看到了两种可能的方式:
(A) 使用 shinydashboard 并以某种方式添加顶部导航栏或
(B) 使用 navbarPage 并以某种方式添加可以隐藏的侧边栏菜单。
(A) 使用shinydashboard,最接近我想要的是这个(简化的MWE):
library("shiny")
library("shinydashboard")
cases <- list(A=seq(50,500, length.out=10), B=seq(1000,10000, length.out=10))
ui <- dashboardPage(
dashboardHeader(title = "dash w/ navbarMenu"),
dashboardSidebar(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE), numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1)),
dashboardBody(
tabsetPanel(
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1", plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
))
)
)
)
server <- function(input, output) {
output$plot11 <- renderPlot({
hist(rnorm(cases[[input$case]][input$num]))
})
}
shinyApp(ui, server)
这很丑陋,因为导航栏菜单是不属于菜单一部分的选项卡集。我要的是:
基于这个post,我猜想根本不可能在顶部菜单中包含"Perspective 1"和"Perspective 2"选项卡,因此使用shinydashboard似乎不可行。
(B) 使用 navbarPage,我尝试使用 navlistPanel() 但没有成功
(1) 使其表现得像侧边栏菜单,即在页面左侧整体可见
(2) 添加隐藏功能。这是我的尝试:
library("shiny")
cases <- list(A=seq(50,500, length.out=10),
B=seq(1000,10000, length.out=10))
ui <- navbarPage(title = "nav w/ sidebarMenu",
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1",
plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
)),
navlistPanel(widths = c(2, 2), "SidebarMenu",
tabPanel(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE)),
tabPanel(numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1))
)
)
server <- function(input, output) {
output$plot11 <- renderPlot({
hist(rnorm(cases[[input$case]][input$num]))
})
}
shinyApp(ui, server)
同样,我想要的是:
我知道,有flexDashboard。它没有解决问题,原因有以下三个:
(1) 我认为隐藏侧边栏菜单是不可能的,因为它是一列而不是真正的侧边栏菜单,
(2) 它不是我在我的应用程序中需要的反应式,
(3) 我觉得dataTables不行,我也需要。
此外,我宁愿不必将代码更改为 Rmarkdown 语法。
我最好使用 navbarPage 并添加 sidebarMenu,因为我的应用程序已经使用 navbarPage 构建。
您可以使用 sidebarLayout
并执行如下操作:
ui <- fluidPage(sidebarLayout(
sidebarPanel(navlistPanel(
widths = c(12, 12), "SidebarMenu",
tabPanel(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE)),
tabPanel(numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1))
)),
mainPanel(navbarPage(title = "nav w/ sidebarMenu",
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1",
plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
)))
)
))
你得到这样的东西:
另一种选择是使用 fluidRow
函数。像这样:
ui <- fluidPage(
fluidRow(
column(3, navlistPanel(
widths = c(12, 12), "SidebarMenu",
tabPanel(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE)),
tabPanel(numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1))
)),
column(9, navbarPage(title = "nav w/ sidebarMenu",
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1",
plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
))))
)
)
要得到这个:
希望对您有所帮助!
现在有一种更简单、更优雅的方法来实现它:
和 here 以查看实际效果。
现在可以使用 bootstraplib
Github 请求实现:
https://github.com/rstudio/bootstraplib/issues/76
最小表示:
# package load ------------------------------------------------------------
library(shiny)
library(bootstraplib)
# boot dash layout funs ---------------------------------------------------
boot_side_layout <- function(...) {
div(class = "d-flex wrapper", ...)
}
boot_sidebar <- function(...) {
div(
class = "bg-light border-right sidebar-wrapper",
div(class = "list-group list-group-flush", ...)
)
}
boot_main <- function(...) {
div(
class = "page-content-wrapper",
div(class = "container-fluid", ...)
)
}
# title -------------------------------------------------------------------
html_title <-
'<span class="logo">
<div style="display:inline-block;">
<a href="https://www.google.com"><img src="https://jeroen.github.io/images/Rlogo.png" height="35"/></a>
<b>my company name</b> a subtitle of application or dashboard
</div>
</span>'
# css ---------------------------------------------------------------------
css_def <- "
body {
overflow-x: hidden;
}
.container-fluid, .container-sm, .container-md, .container-lg, .container-xl {
padding-left: 0px;
}
.sidebar-wrapper {
min-height: 100vh;
margin-left: -15rem;
padding-left: 15px;
padding-right: 15px;
-webkit-transition: margin .25s ease-out;
-moz-transition: margin .25s ease-out;
-o-transition: margin .25s ease-out;
transition: margin .25s ease-out;
}
.sidebar-wrapper .list-group {
width: 15rem;
}
.page-content-wrapper {
min-width: 100vw;
padding: 20px;
}
.wrapper.toggled .sidebar-wrapper {
margin-left: 0;
}
.sidebar-wrapper, .page-content-wrapper {
padding-top: 20px;
}
.navbar{
margin-bottom: 0px;
}
@media (max-width: 768px) {
.sidebar-wrapper {
padding-right: 0px;
padding-left: 0px;
}
}
@media (min-width: 768px) {
.sidebar-wrapper {
margin-left: 0;
}
.page-content-wrapper {
min-width: 0;
width: 100%;
}
.wrapper.toggled .sidebar-wrapper {
margin-left: -15rem;
}
}
"
# app ---------------------------------------------------------------------
ui <- tagList(
tags$head(tags$style(HTML(css_def))),
bootstrap(),
navbarPage(
collapsible = TRUE,
title = HTML(html_title),
tabPanel(
"Tab 1",
boot_side_layout(
boot_sidebar(
sliderInput(
inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30
)
),
boot_main(
fluidRow(column(6, h1("Plot 1")), column(6, h1("Plot 2"))),
fluidRow(
column(6, plotOutput(outputId = "distPlot")),
column(6, plotOutput(outputId = "distPlot2"))
)
)
)
),
tabPanel(
"Tab 2",
boot_side_layout(
boot_sidebar(h1("sidebar input")),
boot_main(h1("main output"))
)
)
)
)
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x,
breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times"
)
})
output$distPlot2 <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x,
breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times"
)
})
}
shinyApp(ui, server)
我有一个闪亮的应用程序(使用 navbarPage),它有很多选项卡,我想添加一个侧边栏菜单,无论选择哪个选项卡都可以看到。侧边栏中的输入值会影响所有选项卡的内容。 此外,应该可以隐藏 sidebarMenu,因为它在 shinydashboard 中。
我看到了两种可能的方式:
(A) 使用 shinydashboard 并以某种方式添加顶部导航栏或
(B) 使用 navbarPage 并以某种方式添加可以隐藏的侧边栏菜单。
(A) 使用shinydashboard,最接近我想要的是这个(简化的MWE):
library("shiny")
library("shinydashboard")
cases <- list(A=seq(50,500, length.out=10), B=seq(1000,10000, length.out=10))
ui <- dashboardPage(
dashboardHeader(title = "dash w/ navbarMenu"),
dashboardSidebar(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE), numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1)),
dashboardBody(
tabsetPanel(
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1", plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
))
)
)
)
server <- function(input, output) {
output$plot11 <- renderPlot({
hist(rnorm(cases[[input$case]][input$num]))
})
}
shinyApp(ui, server)
这很丑陋,因为导航栏菜单是不属于菜单一部分的选项卡集。我要的是:
基于这个post,我猜想根本不可能在顶部菜单中包含"Perspective 1"和"Perspective 2"选项卡,因此使用shinydashboard似乎不可行。
(B) 使用 navbarPage,我尝试使用 navlistPanel() 但没有成功
(1) 使其表现得像侧边栏菜单,即在页面左侧整体可见
(2) 添加隐藏功能。这是我的尝试:
library("shiny")
cases <- list(A=seq(50,500, length.out=10),
B=seq(1000,10000, length.out=10))
ui <- navbarPage(title = "nav w/ sidebarMenu",
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1",
plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
)),
navlistPanel(widths = c(2, 2), "SidebarMenu",
tabPanel(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE)),
tabPanel(numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1))
)
)
server <- function(input, output) {
output$plot11 <- renderPlot({
hist(rnorm(cases[[input$case]][input$num]))
})
}
shinyApp(ui, server)
同样,我想要的是:
我知道,有flexDashboard。它没有解决问题,原因有以下三个:
(1) 我认为隐藏侧边栏菜单是不可能的,因为它是一列而不是真正的侧边栏菜单,
(2) 它不是我在我的应用程序中需要的反应式,
(3) 我觉得dataTables不行,我也需要。
此外,我宁愿不必将代码更改为 Rmarkdown 语法。
我最好使用 navbarPage 并添加 sidebarMenu,因为我的应用程序已经使用 navbarPage 构建。
您可以使用 sidebarLayout
并执行如下操作:
ui <- fluidPage(sidebarLayout(
sidebarPanel(navlistPanel(
widths = c(12, 12), "SidebarMenu",
tabPanel(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE)),
tabPanel(numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1))
)),
mainPanel(navbarPage(title = "nav w/ sidebarMenu",
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1",
plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
)))
)
))
你得到这样的东西:
另一种选择是使用 fluidRow
函数。像这样:
ui <- fluidPage(
fluidRow(
column(3, navlistPanel(
widths = c(12, 12), "SidebarMenu",
tabPanel(selectizeInput('case', 'Pick a case', selected="A", choices = c("A", "B"), multiple = FALSE)),
tabPanel(numericInput('num', 'Number', min = 1, max = 10, value = 1, step = 1))
)),
column(9, navbarPage(title = "nav w/ sidebarMenu",
tabPanel(h4("Perspective 1"),
tabsetPanel(
tabPanel("Subtab 1.1",
plotOutput("plot11")),
tabPanel("Subtab 1.2")
)),
tabPanel(h4("Perspective 2"),
tabsetPanel(
tabPanel("Subtab 2.1"),
tabPanel("Subtab 2.2")
))))
)
)
要得到这个:
希望对您有所帮助!
现在有一种更简单、更优雅的方法来实现它:
和 here 以查看实际效果。
现在可以使用 bootstraplib
Github 请求实现: https://github.com/rstudio/bootstraplib/issues/76
最小表示:
# package load ------------------------------------------------------------
library(shiny)
library(bootstraplib)
# boot dash layout funs ---------------------------------------------------
boot_side_layout <- function(...) {
div(class = "d-flex wrapper", ...)
}
boot_sidebar <- function(...) {
div(
class = "bg-light border-right sidebar-wrapper",
div(class = "list-group list-group-flush", ...)
)
}
boot_main <- function(...) {
div(
class = "page-content-wrapper",
div(class = "container-fluid", ...)
)
}
# title -------------------------------------------------------------------
html_title <-
'<span class="logo">
<div style="display:inline-block;">
<a href="https://www.google.com"><img src="https://jeroen.github.io/images/Rlogo.png" height="35"/></a>
<b>my company name</b> a subtitle of application or dashboard
</div>
</span>'
# css ---------------------------------------------------------------------
css_def <- "
body {
overflow-x: hidden;
}
.container-fluid, .container-sm, .container-md, .container-lg, .container-xl {
padding-left: 0px;
}
.sidebar-wrapper {
min-height: 100vh;
margin-left: -15rem;
padding-left: 15px;
padding-right: 15px;
-webkit-transition: margin .25s ease-out;
-moz-transition: margin .25s ease-out;
-o-transition: margin .25s ease-out;
transition: margin .25s ease-out;
}
.sidebar-wrapper .list-group {
width: 15rem;
}
.page-content-wrapper {
min-width: 100vw;
padding: 20px;
}
.wrapper.toggled .sidebar-wrapper {
margin-left: 0;
}
.sidebar-wrapper, .page-content-wrapper {
padding-top: 20px;
}
.navbar{
margin-bottom: 0px;
}
@media (max-width: 768px) {
.sidebar-wrapper {
padding-right: 0px;
padding-left: 0px;
}
}
@media (min-width: 768px) {
.sidebar-wrapper {
margin-left: 0;
}
.page-content-wrapper {
min-width: 0;
width: 100%;
}
.wrapper.toggled .sidebar-wrapper {
margin-left: -15rem;
}
}
"
# app ---------------------------------------------------------------------
ui <- tagList(
tags$head(tags$style(HTML(css_def))),
bootstrap(),
navbarPage(
collapsible = TRUE,
title = HTML(html_title),
tabPanel(
"Tab 1",
boot_side_layout(
boot_sidebar(
sliderInput(
inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30
)
),
boot_main(
fluidRow(column(6, h1("Plot 1")), column(6, h1("Plot 2"))),
fluidRow(
column(6, plotOutput(outputId = "distPlot")),
column(6, plotOutput(outputId = "distPlot2"))
)
)
)
),
tabPanel(
"Tab 2",
boot_side_layout(
boot_sidebar(h1("sidebar input")),
boot_main(h1("main output"))
)
)
)
)
server <- function(input, output) {
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x,
breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times"
)
})
output$distPlot2 <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x,
breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times"
)
})
}
shinyApp(ui, server)