Search code examples
rshinyflexdashboard

adjust plot given screen size with reactive value


I am trying to adjust plots in flexdashboard by taking the pixelratio provided by the user session, this works fine when I am rendering plot with renderPlot but I am struggling to assign dynamic heights / widths to plots that are rendered with renderPlotly

I extract the user pixel ratio as followed

pixelratio <- reactive({
  session$clientData$pixelratio
})

attempt 1

output$myplot <- renderPlotly(myplot())
plotlyOutput("myplot", height = function() {900 / pixelratio()}, width = 825)

the first attempt is giving the following error msg :

Error : CSS units must be single element numeric or character vector

attempt 2

output$myplot <- renderPlotly(myplot())
plotlyOutput("myplot", height = 900 / pixelratio(), width = 825)

the second attempt is submitting the following error msg:

Error : Operation not allowed without an active reactive context.
* You tried to do something that can only be done from inside a reactive consumer

Is there a way to get pixelratio in order to autoscale plotlyOutput?


Solution

  • You can set the height in the plotl_ly function and set height = "auto" in plotlyOutput.

    library(shiny)
    library(plotly)
    library(dplyr)
    library(tibble)
    
    state <- data.frame(state.x77, state.region, state.abb) %>% 
      rename(Region = state.region) %>% 
      rownames_to_column("State")
    
    
    ui <- fluidPage(
      br(),
      plotlyOutput("myplotly", width = 825, height = "auto")
    )
    
    server <- function(input, output, session){
      
      pixelratio <- reactive({
        session$clientData$pixelratio
      })
      
      output[["myplotly"]] <- renderPlotly({
        plot_ly(
          data = state,
          x = ~ Income,
          y = ~ Murder,
          type = "scatter",
          mode = "markers",
          text = ~ paste(State, "<br>Income: ", Income, '<br>Murder Rate:', Murder),
          height = 900 / pixelratio()
        )
        
      })
      
      observe({
        print(pixelratio())
      })
    }
    
    shinyApp(ui, server)