0

I have a nice plotting function done with ggplot that has also built in functionality for plotting vertical lines and these are part of my larger Shiny app. I tried to make a minimal reproducible example for my problem. Here it is:

library(shiny)
library(ggplot2)

ui <- fluidPage(
  fluidRow(
    column(6, offset=1,
           plotOutput("plot", width="100%", height="500px")
    )
  ),
  fluidRow(
    column(2, offset=1,
           actionButton(inputId="go", label="Plot")
    ),
    column(2, offset=1,
           selectInput(inputId="number", label="Number of lines:",
                       choices=list("No lines"="0",
                                    "One line"="1",
                                    "Two lines"="2",
                                    "Three lines"="3"))
    )
  ),
  fluidRow(
    uiOutput("dynamic")
  )
)

server <- function(input, output, session) {

  # Function for n number of input boxes for
  # vertical line interception points in UI
  vertical_line_UI <- function(n) {
    fluidRow(
      column(4, offset=1,
             numericInput(inputId=sprintf("line%s", n),
                          label=sprintf("Line%s:", n),
                          value=5))
    )
  }

  # Rendering above in UI
  output$dynamic = renderUI({
    if (as.integer(input$number) > 0) {
      lapply(1:as.integer(input$number), vertical_line_UI)
    }
  })

  # Vertical line interception points
  lines <- eventReactive(input$go, {
    if (as.integer(input$number) > 0 ) {
      c(input$line1, input$line2, input$line3)
    } else {
      NULL
    }
  })

  # Plot function
  plot_function <- function(data, lines=NULL) {
    p <- ggplot(data=data.frame(x=1:10, y=1:10),
                aes(x=x, y=y)) + geom_line() + theme_bw()
    if (!is.null(lines)) {
      for (n in 1:length(lines)) {
        p <- p + geom_vline(xintercept=lines[n])
      }
    }
    return(p)
  }

  # Rendering plot
  plot <- eventReactive(input$go, {
    plot_function(lines=lines())
  })

  output$plot <- renderPlot({
    plot()
  })

}

shinyApp(ui = ui, server = server)

What I would like to do is have a nicer way than manually writing c(input$line1, input$line2, input$line3, ..., input$lineN) for N number of vertical lines. I would probably cap it at 10-15 anyways.

So I suppose my problem could be narrowed down how to express

  lines <- eventReactive(input$go, {
    if (as.integer(input$number) > 0 ) {
      c(input$line1, input$line2, input$line3)
    } else {
      NULL
    }
  })

in more fluid way for N number of inputs instead of manually writing each one of them down. If I five vertical lines I would only have 5 input variables etc.

Tsingis
  • 508
  • 3
  • 8
  • 25

0 Answers0