Search code examples
cssrshinyfluid-layout

shiny renderPlot with dynamic height


Problem I want to change the height of a rendered plot dynamically, so that if it contains a lot of data points more space is allocated to the plot. Content below the plot should then simply be moved.

The height argument of renderPlot can be used for that, but then the plot overflows into the next element and I want to avoid that.

I can circumvent that by using uiOutput, but I was wondering whether I can get the same behaviour without falling back on renderUI?

Expected Outcome

I would like the div below my plot to be moved when the plot sizes changes, without using renderUI

Screenshots

Div does not move Too small

Overflow into div Overflow!! Code

library(shiny)
library(ggplot2)

ui <- fluidPage(
   fluidRow(
      column(width = 2, sliderInput("n", "Number of Rows:", 1, 49, 10)),
      column(width = 10, plotOutput("plot"))
   ),
   fluidRow( ## the plot oevrflows into this div when the plot grows
      column(width = 12, div(style = "background:red; height: 100px"))
   ),
   fluidRow(
    column(width = 10, offset = 2, uiOutput("ui"))
   ),
   fluidRow( ## this div is properly moved down as the plot grows
      column(width = 12, div(style = "background:red; height: 100px"))
   )
)

server <- function(input, output, session) {
   data <- reactive(data.frame(id = factor(1:input$n, 1:input$n), 
                               y  = rpois(input$n, 200)))
   output$plot <- renderPlot(
     qplot(id, y, geom = "col", fill = y, data = data()) + 
        coord_flip(), height = function() 20 * NROW(data())
   )

   output$ui <- renderUI(plotOutput("plot2", height = 20 * NROW(data())))

   output$plot2 <- renderPlot(
     qplot(id, y, geom = "col", fill = y, data = data()) + 
        coord_flip()
   )
}



Solution

  • You can write plotOutput("plot", height = "auto") in the ui part. The default height of plotOutput are fixed 400 pixels. By setting height="auto" the plot automatically adjusts to the content.