R Shinydashboard:各种菜单子项的动态和静态tabItem的混合

时间:2019-04-15 04:14:01

标签: r shiny menuitem shinydashboard

我正在构建一个包含三个部分的应用程序:

  1. 概述
  2. 详细结果
  3. 帮助

详细结果部分应显示许多子项的结果,一次是一个子项。

我对“结果”部分的一个标签感兴趣,因为我不想为每个子项目的每个标签编写代码。每个子项目都有相同的内容,例如直方图。

但是,当我运行示例时,我松开了子项目的ID。 是否可以具有这样的布局,但保留所有菜单项和菜单子项的ID?

很高兴看到替代方法。

下面是一个说明问题的示例。该解决方案将以概览方式显示该表格,并在任何子项目的结果中显示直方图,并在帮助部分中显示HTML输出。

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(), 
  dashboardSidebar(
    sidebarMenu(id = "SideBarMENU", 

                menuItem("Overview", tabName = "OVERVIEW", selected = TRUE),
                menuItem("Results",  startExpanded = TRUE,
                         menuSubItem("Sepal.Length", tabName = "RESULTS"),
                         menuSubItem("Sepal.Width" , tabName = "RESULTS"),
                         menuSubItem("Petal.Length", tabName = "RESULTS"),
                         menuSubItem("Petal.Width" , tabName = "RESULTS")
                ), 
                menuItem("Help", tabName = "HELP")
    )

  ),
  dashboardBody(
    tabItems(
      tabItem("OVERVIEW", 
              box("Overview box", 
                  tableOutput("overview"))
      ),
      tabItem("RESULTS", 
              box("Results box", 
                  plotOutput("results")
              )
      ),
      tabItem("HELP", 
              box("HELP box", 
                  textOutput("help"))
      ) 
    )
  )
)

server <- function(input, output, session) {


  data <- reactive({

    print(input$SideBarMENU)

    if(input$SideBarMENU %in% names(iris)){
      iris[[input$SideBarMENU]]
    } else {
      rnorm(100, 1000, 10)
    }
  })


  output$results <- renderPlot({
    hist(data())
  })


  output$overview <- renderTable({
    head(iris)
  })



  output$help <- renderText({
    HTML("A wiki is a website on which users collaboratively.....")
  })



}

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:1)

基本上,您需要两个组件:

  1. 动态内容/情节

  2. 动态仪表板主体

第一部分更简单:

1。动态内容/情节

您可以按照其他一些SO帖子中的说明在循环中创建输出:

// get data from your method
DataTable table = GetData("select * from MyTable");

// iterate over the rows of the datatable
foreach (var row in table.AsEnumerable())  // AsEnumerable() returns IEnumerable<DataRow>
{
    var id = row.Field<int>("ID");                           // int
    var name = row.Field<string>("Name");                    // string
    var orderValue = row.Field<decimal>("OrderValue");       // decimal
    var interestRate = row.Field<double>("InterestRate");    // double
    var isActive = row.Field<bool>("Active");                // bool
    var orderDate = row.Field<DateTime>("OrderDate");        // DateTime
}

2。动态仪表板主体

这部分比较复杂。您需要动态if(table?.Rows?.Count() > 0) { ... } ,并且它们必须与静态零件混合。为了将 lapply(nms, function(name){ output[[name]] <- renderUI ({ box("Results Box", plotOutput(paste0("plot_", name))) }) output[[paste0("plot_", name)]] <- renderPlot({ hist(iris[[input$SideBarMENU]], main = "") }) }) 的列表移交给tabitems(),您可以使用tabitem()进行转换,请参见下面的链接。要将它们与静态元素组合,请将静态元素转换为tabitems()元素,并在调用do.call(tabItems, ..)之前将它们全部合并到list()中。

list()

类似的组件可以在这里找到:answer 并在此处shinydashboard does not work with uiOutput循环do.call(tabItems, ..)

注意:

我修改了 output$tabItms <- renderUI ({ itemsDyn <- lapply(nms, function(name){ tabItem(tabName = name, uiOutput(name)) }) items <- c( list( tabItem("OVERVIEW", box("Overview box", tableOutput("overview")) ) ), itemsDyn, list( tabItem("HELP", box("HELP box", textOutput("help")) ) ) ) do.call(tabItems, items) })

tabItems()

因为tabItem名称不允许使用点。

可复制的示例:

names(iris)