1

I would like to create a Shiny document which shows two grobs alongside one another and would like the text inside each grob to be the selected value of a sliderInput.

I am able to easily output two grobs side-by-side in a non-reactive context (first example below) but obviously cannot extract the slider value. However, when I try to output them inside a renderPlot reactive context, I am able to extract the slider value, but only the second grob shows up and the connection arrow is not visible.

Can anyone offer a solution that shows both grobs and the reactive value?

---
runtime: shiny
output:
  html_document
---

```{r global-options, include = FALSE}
## set global options
knitr::opts_chunk$set(echo = F, error = F, warning = F, message = F)
```

```{r echo = F, error = F, warning = F, message = F}
## libraries
library(shiny)
library(Gmisc)
library(grid)
library(knitr)

## slider input
sliderInput("nSelect", "Select N:", min = 1, max = 10, value = 5)
```

```{r fig.width = 10, fig.height = 1}
## output grobs normally, but no way to use reactive slider values
g1 <- boxGrob(5,
        x = 0.3,
        y = 0.5)
g2 <- boxGrob(5,
        x = 0.8,
        y = 0.5)
g1
g2
connectGrob(g1, g2, type = "horizontal")
```

```{r fig.width = 10, fig.height = 1}
## output grobs using render plot (allows inputs)
renderPlot({
g3 <- boxGrob(input$nSelect,
        x = 0.3,
        y = 0.5)
g4 <- boxGrob(input$nSelect,
        x = 0.8,
        y = 0.5)
connectGrob(g3, g4, type = "horizontal")
g3
g4
})
```

enter image description here

DJC
  • 1,491
  • 6
  • 19
  • 2
    Your `renderPlot` renders `g4` since this is the last statement of its body. Close it after you write `connectGrob(g3, g4, type = "horizontal")` (i.e. delete the lines `g3` and `g4`). – Stéphane Laurent Apr 09 '21 at 18:24
  • Thanks Stephane - I tried that but doing so only renders the connector arrow - the boxes on either side of it don't render, at least not on my machine/r setup – DJC Apr 09 '21 at 18:31
  • 1
    @-DJC: Ah sorry, I never used `connectGrob` and I thought it rendered the two connected boxes with the arrow. Isn't there a way to group `g3`, `g4` and the connector in a single object? I'm not familiar with `grid`, I don't know. – Stéphane Laurent Apr 09 '21 at 18:35
  • Not to my knowledge - I tried arranging them using various grid arrangements, but my understanding is that the placement of the connector line is contingent on both grobs being placed on a page as it uses those coordinates to place the line. Might end up using DiagrammeR, which is also a great package, to create my actual flowcharts although much prefer the way the nodes/edges look with grob setup – DJC Apr 09 '21 at 18:38

1 Answers1

1

Within the renderPlot you need to explicitly call print(), i.e. all you need to do is:

renderPlot({
  g3 <- boxGrob(input$nSelect,
                x = 0.3,
                y = 0.5)
  g4 <- boxGrob(input$nSelect,
                x = 0.8,
                y = 0.5)
  print(connectGrob(g3, g4, type = "horizontal"))
  print(g3)
  print(g4)
})

This is an R-feature where anything within an expression won't print unless it is the last element, i.e. you can omit the print() for g4 as it will be printed just by being the last.

Max Gordon
  • 5,367
  • 2
  • 44
  • 70