skip to Main Content

I have a shiny app which adds a gridstack.js gridstack panel to the app whenever I click a button. Now, I would like to add a plot to the panel.
Here is my code:

library(shinydashboard)
library(shiny)
library(shinyjs)
library(shinyjqui)
library(gridstackeR)
library(plotly)

ui <- fluidPage (
  useShinyjs(),
  includeCSS("www/app.css"),
  tags$head(
    tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/10.0.1/gridstack-all.min.js", type='module'),
    tags$script(HTML('
      function addFirstWidget() {
        var grid = document.querySelector('.grid-stack').gridstack;
        grid.addWidget({h:5, w: 2, content: 'This is where the plot goes'});
      }
    '))
          
  ),
  grid_stack(id="mygrid"),
  actionButton("first_widget", "First Widget"),
  
  title = "Gridstack Prototype"
)

server <- function(input, output, session) {
  observeEvent(input$first_widget, {
    # browser()
    runjs("addFirstWidget();")
  })
  
}

shinyApp(ui = ui, server = server)

The JS Function addFirstWidget() makes a new gridstack panel whenever the button is pressed.

I want to call a function that renders a plot in plotly, ggplot, or some other plotting library within the panel(I’ll know what library I use for the plot), for instance, this:

plot_ly(data = iris, x = ~Sepal.Length, y = ~Petal.Length)

However, I’m not sure how to go about actually putting this interactive plot into the panels. The interactivity must be kept, and I can’t use JS to generate the plots

2

Answers


  1. Chosen as BEST ANSWER

    okay so I messed around with it a little and this should work:

    library(shinydashboard)
    library(shiny)
    library(shinyjs)
    library(shinyjqui)
    library(gridstackeR)
    library(plotly)
    ui <- fluidPage (
      useShinyjs(),
      includeCSS("www/app.css"),
      tags$head(
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/10.0.1/gridstack-all.min.js", type='module'),
        tags$script(HTML('
          let numFirstWidgets = 0;
          function addFirstWidget() {
            var grid = document.querySelector('.grid-stack').gridstack;
            let ids = "widget" + numFirstWidgets;
            grid.addWidget(`<div class="grid-stack-item"><div class="grid-stack-item-content" id=${ids}></div></div>`, {h:3, w: 2});
            numFirstWidgets += 1;
          }
        '))
      ),
      grid_stack(id="mygrid"),
      actionButton("first_widget", "First Widget"),
      # plotlyOutput("plot"),
      title = "Gridstack Prototype"
    )
    
    server <- function(input, output, session) {
      numOfWidgets <- 0
      observeEvent(input$first_widget, {
        # browser()
        runjs("addFirstWidget();")
        insertUI(
          paste0("#widget", numOfWidgets),
          where = "afterBegin",
          plotlyOutput(paste0("plotly", numOfWidgets), height="100%"),
          output[[paste0("plotly", numOfWidgets)]] <- renderPlotly({
            plot_ly(data = iris, x = ~Sepal.Length, y = ~Petal.Length)
          })
        )
        numOfWidgets <<- numOfWidgets + 1
      })
      
      
    }
    
    shinyApp(ui = ui, server = server)
    
    

    Basically it sets the actual id of div inside of the widget to something that the insertUI looks for. So now you can insert an unlimited number of items of this widget


  2. You don’t have to include the JavaScript library since it is included by the R package.

    Here is a way using insertUI. But you have to give w and h in the UI. I firstly tried to insert grid_stack_item(plotlyOutput(...... and that was not nice.

    library(shiny)
    library(gridstackeR)
    library(plotly)
    
    ui <- fluidPage(
      grid_stack(
        id = "mygrid",
        grid_stack_item(
          id = "widget1",
          w = 6, h = 6 
        )
      ),
      
      actionButton("first_widget", "First Widget"),
      
      title = "Gridstack Prototype"
    )
    
    server <- function(input, output, session) {
      
      output$pltly <- renderPlotly({
        plot_ly(data = iris, x = ~Sepal.Length, y = ~Petal.Length)
      })
      
      observeEvent(input$first_widget, {
        insertUI(
          "#widget1",
          where = "afterBegin",
          plotlyOutput("pltly")
        )
      })
      
    }
    
    shinyApp(ui = ui, server = server)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search