【问题标题】:Can the Shiny conditionalPanel be used Horizontally?Shiny conditionalPanel 可以水平使用吗?
【发布时间】:2019-10-22 10:17:28
【问题描述】:

我正在使用 sidebarLayout() 开发一个闪亮的应用程序,我希望根据 sidebarPanel() 中的输入值在 mainPanel() 中并排显示一个或两个图。

如果只显示一个图,我希望该图占据 mainPanel() 水平空间的 100%。但是,如果要显示两个图,我希望每个图都占用 mainPanel() 空间的 50%。

我还希望每个特定列的内容占据其自己列中的所有可用水平空间。

我已经尝试了一些东西。

  1. 有一个fluidRow()包含一个列和一个conditionalPanel()

    • 但是,我无法使其正常工作,因为 fluidRow() 希望每个元素都提供一个宽度参数,而 conditionalPanel() 似乎不兼容。
  2. conditionalPanel() 在 splitLayout() 的右侧

    • 这只会隐藏右侧,不允许左侧绘图占用所有 mainPanel() 空间。
  3. 右 div 内的 conditionalPanel() 显示:table-cell

    • 但这与上述 1 的结果相同
library(ggplot2)
library(shiny)

ui <- fluidPage(
  tags$head(
    tags$style("
               #my_container {
                 display: table;
                 width: 100%;
               }

               .col {
                 display: table-cell;
               }

               #col_left {
                 background-color: #ffa;
               }

               #col_right {
                 background-color: #faf;
               }
               ")
  ), 

  sidebarPanel(
    checkboxInput("checkbox", 
                  "View Both", 
                  value = TRUE), 
    width = 2
  ), 

  mainPanel(
    div(id = "my_container", 
        div(id = "col_left", 
            class ="col", 
            plotOutput("plot_output_1")),
        div(id = "col_right", 
            class = "col", 
            conditionalPanel("input.checkbox == 1", 
                             plotOutput("plot_output_2")))
    ), 
    width = 10
  )
)

server <- shinyServer(function(input, output) {
  output$plot_output_1 <- renderPlot({
    ggplot(
      data.frame(x = runif(3), y = rnorm(3)), 
      aes(x = x, y = y)) + 
      geom_point()
  })

  output$plot_output_2 <- renderPlot({
    ggplot(
      data.frame(x = runif(3), y = rnorm(3)), 
      aes(x = x, y = y)) + 
      geom_point()
  })
})

shinyApp(ui, server)
  1. 我还尝试添加 javascript 消息来更改 div 宽度。
    • 这似乎在右列被隐藏而左列(示例中的黄色背景)显示的意义上起作用。但是,尽管由于对输入的依赖而被重绘,但左列中的绘图并未被重绘以占用新空间。
library(ggplot2)
library(shiny)

ui <- fluidPage(
  tags$head(
    tags$style("
               #my_container {
                 display: table;
                 width: 100%;
               }

               .my_col {
                 display: table-cell;
               }

               #col_left {
                 background-color: #ffa;
               }

               #col_right {
                 background-color: #faf;
               }
               "
    ), 

    tags$script("
      Shiny.addCustomMessageHandler('n_show.onchange', function(value) {
        var col_left = document.getElementById('col_left');
        var col_right = document.getElementById('col_right');

        if(value == 'one') {
          col_left.style.width = '100%';
          col_right.style.width = '0%';
        } else {
          col_left.style.width = '50%'; 
          col_right.style.width = '50%';
        }
      });
      "
    )
  ), 

  sidebarPanel(
    selectInput(inputId = "n_show", label = "Number of Plots", choices = c("one", "two"), selected = "two"), 
    width = 2
  ), 

  mainPanel(
    div(id = "my_container", 
        div(id = "col_left", 
            class = "my_col", 
            plotOutput("plot_output_1")),
        div(id = "col_right", 
            class = "my_col", 
            conditionalPanel("input.n_show == 'two'", 
                             plotOutput("plot_output_2")))
    ), 
    width = 10
  )
)

server <- shinyServer(function(input, output, session) {
  output$plot_output_1 <- renderPlot({
    input$n_show

    ggplot(
      data.frame(x = runif(3), y = rnorm(3)), 
      aes(x = x, y = y)) + 
      geom_point()
  })

  output$plot_output_2 <- renderPlot({
    input$n_show

    ggplot(
      data.frame(x = runif(3), y = rnorm(3)), 
      aes(x = x, y = y)) + 
      geom_point()
  })

  observeEvent(input$checkbox, {
    session$sendCustomMessage("n_show.onchange", input$n_show)
  })
})

shinyApp(ui, server)

我怀疑这并不像我做的那么难,但我的 css 知识/技能似乎不能胜任这项任务——至少在闪亮的背景下。

【问题讨论】:

    标签: css r shiny shiny-reactivity


    【解决方案1】:

    renderUI的解决方案:

    library(ggplot2)
    library(shiny)
    
    ui <- fluidPage(
      tags$head(
        tags$style("
                   #col_left {
                     background-color: #ffa;
                   }
                   #col_right {
                     background-color: #faf;
                   }
                   ")
        ), 
    
      sidebarPanel(
        checkboxInput("checkbox", 
                      "View Both", 
                      value = TRUE), 
        width = 2
      ), 
    
      mainPanel(
        uiOutput("plots"), 
        width = 10
      )
        )
    
    server <- shinyServer(function(input, output) {
    
      output$plot_output_1 <- renderPlot({
        ggplot(
          data.frame(x = runif(3), y = rnorm(3)), 
          aes(x = x, y = y)) + 
          geom_point(size = 6)
      })
    
      output$plot_output_2 <- renderPlot({
        ggplot(
          data.frame(x = runif(3), y = rnorm(3)), 
          aes(x = x, y = y)) + 
          geom_point(size = 6)
      })
    
      output$plots <- renderUI({
        if(input$checkbox){
          fluidRow(
            column(6, div(id="col_left", plotOutput("plot_output_1"))),
            column(6, div(id="col_right", plotOutput("plot_output_2")))
          )
        }else{
          fluidRow(
            column(12, div(id="col_left", plotOutput("plot_output_1")))
          )
        }
      })
    })
    
    shinyApp(ui, server)
    

    【讨论】:

      猜你喜欢
      • 2016-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      相关资源
      最近更新 更多