使用闪亮的模块

时间:2020-09-24 09:04:17

标签: r shiny

我正在尝试构建一个闪亮的仪表板,并且希望合并闪亮的模块。在每个选项卡中,应用程序的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)

1 个答案:

答案 0 :(得分:1)

您对模块的常规使用是正确的,但是我认为您的actionbutton模块过于精细。您基本上只将模块包装在一个UI元素周围,因此产生的开销多于实用性。但是,我认为在您的情况下,将selectInput和绘图输出组合到一个模块中是有意义的。您可以在下面的示例中看到这一点。我还更改了以下几点:

  • 我使用reactive而不是isolateeventReactive
  • 我使用闪亮的1.5.0版中的新模块界面
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)