我正在尝试构建一个闪亮的仪表板,并且希望合并闪亮的模块。在每个选项卡中,应用程序的UI都与selectInput,dateRangeInput和同一数据集的操作按钮非常相似。因此,我认为如果应用模块,它将大大缩短代码。我的第一个尝试是使用actionbutton模块,如果我采用正确的方法或对改进有任何建议,希望获得您的反馈。
下面的迷你应用程序的想法是,仅当您单击相应的按钮(图1的按钮1和图2的按钮2)时,数据和图才会更新。
这是一个小例子,但是考虑一个带有20个不同选项卡的闪亮仪表板,我认为这将使仅具有button_ui的代码更易于阅读,而不必每次为每个选项卡编写按钮ui。同样,我想对select_ui和daterange_ui也有类似的要求。
ec <- data.frame(
country = c("US", "UK", "Germany", "Spain", "India"),
A = c("1", "2", "2", "3", "3"),
B = c(100, 200, 300, 400, 500)
)
## MODULE
library(shiny)
library(tidyverse)
library(ggplot2)
button_ui <- function(id) {
actionButton(NS(id, "btn"), label = "Apply")
}
button_server <- function(id) {
moduleServer(id, function(input, output, session) {
reactive(input$btn)
})
}
## BUILDING THE APP
ui <- fluidPage(
selectInput(
"choice",
"Select Country:",
multiple = TRUE,
choices = unique(ec$country),
selected = "US"),
button_ui("btn1"),
button_ui("btn2"),
plotOutput("plot1"),
br(),
plotOutput("plot2")
)
server <- function(input, output, session) {
button <- button_server("btn1")
button_a <- button_server("btn2")
dt <- reactive({button()
isolate(
ec %>% filter(country %in% input$choice)
)
})
dt1 <- reactive({button_a()
isolate(
ec %>% filter(country %in% input$choice)
)
})
output$plot1 <- renderPlot({
ggplot(dt(), aes(x = country, y = A)) +
geom_bar(stat = "identity") +
theme_test()
})
output$plot2 <- renderPlot({
ggplot(dt1(), aes(x = country, y = B)) +
geom_bar(stat = "identity") +
theme_test()
})
}
shinyApp(ui, server)
答案 0 :(得分:1)
您对模块的常规使用是正确的,但是我认为您的actionbutton模块过于精细。您基本上只将模块包装在一个UI元素周围,因此产生的开销多于实用性。但是,我认为在您的情况下,将selectInput
和绘图输出组合到一个模块中是有意义的。您可以在下面的示例中看到这一点。我还更改了以下几点:
reactive
而不是isolate
和eventReactive
ec <- data.frame(
country = c("US", "UK", "Germany", "Spain", "India"),
A = c("1", "2", "2", "3", "3"),
B = c(100, 200, 300, 400, 500)
)
## MODULE
library(shiny)
library(dplyr)
library(ggplot2)
tab_module_ui <- function(id) {
ns <- NS(id)
tabPanel(
title = paste0("Plot ", id),
selectInput(
ns("choice"),
"Select Country:",
multiple = TRUE,
choices = unique(ec$country),
selected = "US"),
actionButton(ns("btn"), label = "Apply"),
plotOutput(ns("plot"))
)
}
tab_module <- function(id) {
moduleServer(
id,
function(input, output, session) {
dt <- eventReactive(input$btn, {
ec %>% filter(country %in% input$choice)
})
output$plot <- renderPlot({
ggplot(dt(), aes(x = country, y = A)) +
geom_bar(stat = "identity") +
theme_test()
})
}
)
}
## BUILDING THE APP
ui <- fluidPage(
tabsetPanel(
tab_module_ui("plot-1"),
tab_module_ui("plot-2")
)
)
server <- function(input, output, session) {
tab_module("plot-1")
tab_module("plot-2")
}
shinyApp(ui, server)