4

since couple of days I am trying to find solution to plot appearing wrongly (beyond box width) in shiny app while using function show/hide sidebar.

Here is example code:

library(shiny)
library(shinydashboard)
library(ggplot2)
library(shinyjs)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    useShinyjs(),
    extendShinyjs(text = 'shinyjs.hideSidebar = function(params) { $("body").addClass("sidebar-collapse") }'),
    extendShinyjs(text='shinyjs.showSidebar = function(params) { $("body").removeClass("sidebar-collapse") }'),
    fluidRow(tabsetPanel(id='tabs',
                         tabPanel(value=1,title="Plot1",
                                  fluidRow(
                                    column(12,
                                  plotOutput('plot1', height=800)))),
                         tabPanel(value=2, title="Plot2",
                                  fluidRow(
                                    column(12,
                                  plotOutput('plot2', height=800))))
             )
      )))
  )
)

server <- function(input, output, session) { 
  output$plot1 <- renderPlot({
    out <- ggplot(data.frame(X1=rnorm(1000)),aes(X1))+
      geom_density(fill='light blue')+
      theme_minimal()
    print(out)
  })
  output$plot2 <- renderPlot({
    out <- ggplot(data.frame(X1=rnorm(1000)),aes(X1))+
      geom_density(fill='light blue')+
      theme_minimal()
    print(out)
  })

  observe({
    if (input$tabs == 1) {
      js$hideSidebar()
    }
    else {
      js$showSidebar()
    }
  })
}

shinyApp(ui, server)

As we can see in this example code, i would like the sidebar to appear when the user opens the second tab (sidebar collapsed when input$tabs == 1). It is working pretty good, except when i press to see tab2, then go back to tab1 and again to tab2, the plot is resized and the x axis is cut:

enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
Mal_a
  • 3,670
  • 1
  • 27
  • 60
  • You are redefining the dataset you plot every time you click the tabs because the call to `rnorm()` is in `renderPlot`. Isn't that the source of your problem? – ddiez Jan 24 '17 at 10:23
  • Oh, I retract my previous comment. I used a fixed dataset and now got your point (might be better to do so in your example to remove confusion caused by the plot changing). – ddiez Jan 24 '17 at 10:26
  • Just an unrelated side comment: you can define both the js functions in one call/in one string. You don't need to call `extendShinyjs()` twice – DeanAttali Feb 05 '17 at 07:16

2 Answers2

3

A "hacky" way to do this is to trigger a window resize event when you add/remove the sidebar to force the plot to be redrawn at the right size after the sidebar is shown/hidden:

extendShinyjs(text = 'shinyjs.hideSidebar = function(params) { $("body").addClass("sidebar-collapse"); 
              $(window).trigger("resize"); }'),
extendShinyjs(text='shinyjs.showSidebar = function(params) { $("body").removeClass("sidebar-collapse"); 
              $(window).trigger("resize"); }')
NicE
  • 21,165
  • 3
  • 51
  • 68
0

I do not of a correct fix to this issue but a workaround is to set also width in your call to plotOutput() (e.g. I tried width=800). Then the dimensions of the plot will be fixed and (once the window is resized to the appropriate dimensions) the plot is not cut.

ddiez
  • 1,087
  • 11
  • 26
  • Thanks for the answer, however it is important for me that the plot is responsive, therefore setting the width as fixed is not the solution for me. Thanks anyway! – Mal_a Jan 24 '17 at 10:32
  • 1
    No problem! Added shinydashboard tag since I feel it might be a problem there. Maybe someone else will give you a better solution. – ddiez Jan 24 '17 at 10:37