Skip to content
This repository has been archived by the owner on Nov 2, 2023. It is now read-only.

grid_plot width is not dynamic #231

Open
mattaws opened this issue Oct 21, 2018 · 2 comments
Open

grid_plot width is not dynamic #231

mattaws opened this issue Oct 21, 2018 · 2 comments

Comments

@mattaws
Copy link

mattaws commented Oct 21, 2018

My grid_plot only uses half my page. it stretches if I specify the px width, but I want it to fill the page dynamically and responsively, regardless of screen resolution
screen shot 2018-10-20 at 7 29 45 pm

I have tried to use width = '100%' in the figure, rbokeh output, and grid_plot settings. Examples below and I attached a screenshot of how the unspecificed (no px specified) outputs

Within dashboardBody:
rbokehOutput("rt", width = "100%", height = "800px")

Within server output (it changes when I specify 1800, errors on '100%':

` output$rt <-

renderRbokeh({

  grid_plot(

    list(s1, s2, s3),

    ncol = 3,

    width = 1800, 

    height = 500,

    same_axes = FALSE

  )

})`
@Atrebas
Copy link

Atrebas commented Oct 22, 2018

rbokeh::grid_plot seems to only accept absolute values as width.
A possible solution, not yet perfect at this stage, is to dynamically retrieve the width of the screen, then pass it to grid_plot. Building on top of this SO answer, we have something like this:

library(shinydashboard)
library(rbokeh)

bk1 <- figure() %>%
  ly_bar(variety, data = lattice::barley) %>%
  theme_axis("x", major_label_orientation = 90)

bk2 <- figure() %>%
  ly_points(Sepal.Length, Sepal.Width, data = iris,
            color = Species, glyph = Species,
            hover = list(Sepal.Length, Sepal.Width))


ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    tags$head(tags$script('
                                var dimension = [0, 0];
                                $(document).on("shiny:connected", function(e) {
                                    dimension[0] = window.innerWidth;
                                    dimension[1] = window.innerHeight;
                                    Shiny.onInputChange("dimension", dimension);
                                });
                                $(window).resize(function(e) {
                                    dimension[0] = window.innerWidth;
                                    dimension[1] = window.innerHeight;
                                    Shiny.onInputChange("dimension", dimension);
                                });
                            ')),
    fluidRow(
      valueBox(10, "Box"),
      valueBox(20, "Box"),
      valueBox(30, "Box")
    ),
    fluidRow(
      box(width = 12,
          rbokehOutput("bk", width = "100%", height = "400px")
      )
    )
  )
)


server <- function(input, output, session) {
  
  output$bk <- renderRbokeh({
    print(input$dimension)
    grid_plot(list(bk1, bk2), width = input$dimension[1] )
  })
  
}

shinyApp(ui, server)

It requires some refinements: we don't need the height and it would be better to retrieve the width of the parent element rather than the window. Or there may be a better solution.

@Atrebas
Copy link

Atrebas commented Oct 23, 2018

For what it's worth, below is an updated version. It's a bit better with: (i) js code handled in an external file, (ii) width only, and (iii) sidebar collapsing taken into account. One drawback is that the plots are re-rendered each time the width changes.
Here is the js code (should be in www/adjust_width.js). Disclaimer: I'm a js newbie.

var dimension = [500]; 
$(document).on("shiny:connected", function (e) {
    if ($("body").hasClass("sidebar-collapse")) {
        dimension[0] = window.innerWidth;
    } else {
        dimension[0] = window.innerWidth - 230;
    }
    Shiny.onInputChange("dimension", dimension);
});
$(window).resize(function (e) {
    if ($("body").hasClass("sidebar-collapse")) {
        dimension[0] = window.innerWidth;
    } else {
        dimension[0] = window.innerWidth - 230;
    }
    Shiny.onInputChange("dimension", dimension);
});

And the R code:

library(shinydashboard)
library(rbokeh)

## ---------------------------------
## bokeh figures

bk1 <- figure() %>%
  ly_bar(variety, data = lattice::barley) %>%
  theme_axis("x", major_label_orientation = 90)

bk2 <- figure() %>%
  ly_points(Sepal.Length, Sepal.Width, data = iris,
            color = Species, glyph = Species,
            hover = list(Sepal.Length, Sepal.Width))

## ---------------------------------
## ui

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    ## ! adjust_width.js must be in the www folder
    tags$head(tags$script(src = "adjust_width.js")), 
    fluidRow(
      valueBox(10, "Box"),
      valueBox(20, "Box"),
      valueBox(30, "Box")
    ),
    box(width = 12, 
        rbokehOutput("bk", width = "100%")
    )
  )
)

## server

server <- function(input, output, session) {
  output$bk <- renderRbokeh({
    
    width = input$dimension[1] - 100
    if (length(width) == 0) { width = 500 } # starting value
    print(width)
    
    grid_plot(list(bk1, bk2), 
              width  = width,
              height = 400)
  })
}

## launch app

shinyApp(ui, server)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants