0

In order to be able to resize a graph output from generated with DiagrammeR package (has explained here : https://github.com/rich-iannone/DiagrammeR/issues/93), I need to encapsulate grVizOutput within a renderUI in the server and call it via uiOutput in the ui.

This piece of code keeps returning me the following error:

Error in as.vector: cannot coerce type 'closure' to vector of type 'character'

Note: calling grVizOutput directly in the UI works but do not let me dynamically resize the diagramme.

Any idea why this is not working as expected?

library(shiny)
library(DiagrammeR)
library(magrittr)

##------------------------------------------
## ui function

ui <- shinyUI(fluidPage( 
  fluidRow(
    column(
      width = 8,
      uiOutput('d')
    )
  )
)
)


##------------------------------------------
## server function

server <- function(input, output){

  output$d <- renderUI({
    grVizOutput(
      renderGrViz({grViz("digraph boxes_and_circles {

              # a 'graph' statement
              graph [overlap = true, fontsize = 10]

              # several 'node' statements
              node [shape = box,
              fontname = Helvetica]
              A; B; C; D; E; F

              node [shape = circle,
              fixedsize = true,
              width = 0.9] // sets as circles
              1; 2; 3; 4; 5; 6; 7; 8

              # several 'edge' statements
              A->1 B->2 B->3 B->4 C->A
              1->D E->A 2->4 1->5 1->F
              E->6 4->6 5->7 6->7 3->8
      }")})
    )
  })
}


##------------------------------------------
## run app

shinyApp(ui = ui, server = server)

2 Answers2

1

So you need another output - render event. renderGrViz can't be inside of grVizOutput.

library(shiny)
library(DiagrammeR)
library(magrittr)

##------------------------------------------
## ui function

ui <- shinyUI(fluidPage( 
    fluidRow(
        column(
            width = 8,
            uiOutput('d')
        )
    ),
    sliderInput(inputId = "height", label = "Height", min = 0, max = 2000, value = 300, step = 200),
    sliderInput(inputId = "width", label = "Width", min = 0, max = 2000, value = 300, step = 200)
)
)


##------------------------------------------
## server function

server <- function(input, output){
    
    output$d <- renderUI({
        grVizOutput(
            "gvout", height = input$height, width = input$width
        )
    })
    
    output$gvout <- renderGrViz({grViz("digraph boxes_and_circles {

              # a 'graph' statement
              graph [overlap = true, fontsize = 10]

              # several 'node' statements
              node [shape = box,
              fontname = Helvetica]
              A; B; C; D; E; F

              node [shape = circle,
              fixedsize = true,
              width = 0.9] // sets as circles
              1; 2; 3; 4; 5; 6; 7; 8

              # several 'edge' statements
              A->1 B->2 B->3 B->4 C->A
              1->D E->A 2->4 1->5 1->F
              E->6 4->6 5->7 6->7 3->8
      }")})
}


##------------------------------------------
## run app

shinyApp(ui = ui, server = server)

enter image description here

lz100
  • 6,990
  • 6
  • 29
1

You can use shinyjqui to resize:

library(shiny)
library(shinyjqui)
library(DiagrammeR)

ui <- shinyUI(fluidPage( 
  fluidRow(
    column(
      width = 8,
      jqui_resizable(grVizOutput("grviz"))
    )
  )
)
)    

##------------------------------------------
## server function

server <- function(input, output){
  
  output[["grviz"]] <- renderGrViz({
    grViz("digraph boxes_and_circles {

              # a 'graph' statement
              graph [overlap = true, fontsize = 10]

              # several 'node' statements
              node [shape = box,
              fontname = Helvetica]
              A; B; C; D; E; F

              node [shape = circle,
              fixedsize = true,
              width = 0.9] // sets as circles
              1; 2; 3; 4; 5; 6; 7; 8

              # several 'edge' statements
              A->1 B->2 B->3 B->4 C->A
              1->D E->A 2->4 1->5 1->F
              E->6 4->6 5->7 6->7 3->8
      }")
  })
}
    
##------------------------------------------
## run app

shinyApp(ui = ui, server = server)

enter image description here

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Thanks a lot! This solution works even within the module oriented shiny app! (was not the case and I do not know why with the solution of @lz100). – Damien Georges Sep 30 '21 at 15:50
  • I would argue this solution is hard for users to resize the plot larger than their screen size, particularly for small screen users to get a big plot. Imagine your screen is 1000x1000px and you want a 2000x2000px plot. Resize over the 1000px edge with jqui will be very hard to handle. – lz100 Sep 30 '21 at 20:45