Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shiny: Dynamic height adjustment of plot

Problem: In belows Shiny app the user can add information presented in valueboxes depending on the select input. If the user selects all possible choices then the UI looks as in the screenshot.

Question: Is it possible that the plot (which is in the same row as the valueboxes) adjusts in height (so the bottom of the plot is aligned with the bottom of the last valuebox)?

enter image description here

library(shiny)
library(shinydashboard)

ui <- dashboardPage(
  dashboardHeader(),
  
  dashboardSidebar(
    selectizeInput(
      inputId = "select",
      label = "Select country:",
      choices = c("CH", "JP", "GER", "AT", "CA", "HK"),
      multiple = TRUE)
  ),
  
  dashboardBody(
    fluidRow(column(2, uiOutput("ui1")),
             column(10, plotOutput("some_plot"))))#,
                # column(4, uiOutput("ui2")),
                # column(4, uiOutput("ui3")))
)

server <- function(input, output) {
  
  output$ui1 <- renderUI({
    req(input$select)
    
    lapply(seq_along(input$select), function(i) {
      fluidRow(
        valueBox(value = input$select[i],
                 subtitle = "Box 1",
                 width = 12)
      )
    })
  })
  
  output$some_plot <- renderPlot(
    plot(iris)
  )
}

shinyApp(ui = ui, server = server)
like image 552
rkraft Avatar asked Sep 14 '25 18:09

rkraft


1 Answers

You can adjust the height in the renderPlot. I have set the minimum to 3 value box height. So, it starts increasing the height after you add 3 value boxes. You can modify it, as necessary. Try the code below.

  library(shiny)
  library(shinydashboard)
  
  ui <- dashboardPage(
    dashboardHeader(),
    
    dashboardSidebar(
      selectizeInput(
        inputId = "select",
        label = "Select country:",
        choices = c("CH", "JP", "GER", "AT", "CA", "HK"),
        multiple = TRUE)
    ),
    
    dashboardBody(
      fluidRow(column(2, uiOutput("ui1")),
               column(10, plotOutput("some_plot"))))#,
    
    # column(4, uiOutput("ui2")),
    # column(4, uiOutput("ui3")))
  )
  
  server <- function(input, output) {
    plotht <- reactiveVal(360)
    observe({
      req(input$select)
      nvbox <- length(input$select)
      if (nvbox > 3) {
        plotheight <- 360 + (nvbox-3)*120
      }else plotheight <- 360
      plotht(plotheight)
    })
    
    output$ui1 <- renderUI({
      req(input$select)
      
      lapply(seq_along(input$select), function(i) {
        fluidRow(
          valueBox(value = input$select[i],
                   subtitle = "Box 1",
                   width = 12)
        )
      })
    })
    
    observe({
      output$some_plot <- renderPlot({
        plot(iris)
      }, height=plotht())
    })
 
    
  }
  
  shinyApp(ui = ui, server = server)
like image 72
YBS Avatar answered Sep 16 '25 09:09

YBS