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

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

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

我已经尝试了几件事。


有fluidRow()包含一列和conditionalPanel()


但是,我无法正常工作,因为fluidRow()希望每个元素都提供一个width参数,而conditionalPanel()似乎不兼容。

splitLayout()右侧的conditionalPanel()


这仅隐藏右侧,不允许左侧图占用所有mainPanel()空间。

带有显示内容的右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)



我也尝试添加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知识/技能似乎不符合任务-至少在闪亮的背景下。

最佳答案

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)


css - 可以水平使用Shiny conditionalPanel吗?-LMLPHP

09-06 08:02