rshinyshiny-reactivity

R Shiny output based on clicking on interactive plot


I am trying to make an Shiny app. In one row I have two columns, in the first column is a gant chart. I want to make it so that when you click on one of the bars, it shows text associated with that experience in the other column.

Here is an example of the data for my gant chart.

    > experiences_head
       Type           Institution           Degree                Major start finish                                                 name
1 Education     McGill University           B. Eng    Civil Engineering  1995   1999       McGill University - B. Eng - Civil Engineering
2 Education University of Toronto            M.Eng Chemical Engineering  2000   2002 University of Toronto - M.Eng - Chemical Engineering
3 Education University of Toronto             Ph.D Chemical Engineering  2002   2008  University of Toronto - Ph.D - Chemical Engineering
4      Work Geosyntec Consultants       Consultant                       2008   2009                   Geosyntec Consultants - Consultant
5      Work                  EMBL Bioinformatician                       2009   2013                              EMBL - Bioinformatician
6      Work                  EMBL   Data Scientist                       2013   2016                                EMBL - Data Scientist
                                notes
1                   Wastwater project
2                Treatability Studies
3 Optimizing Cuture growth conditions
4                 Biomarker protocols

I have read the 'similar' posts that come up on this, but am a bit lost. Im a bit stuck, am thinking that I need to use click in the plotoutput and observeEvents somewhere.

     source("resume_functions.R")
    ui<- 
          fluidRow(
            id = "title_bar",
            titlePanel(title = "Shiny Resume")
          ),
          fluidRow(
            # Text Section ----
            column(
              width = 8,
              
              # Description ----
              h3("Personal Summary"),
              p(Personal_summary)
            ),
          column(
            width=4,
            h3("Personality"),
            plotOutput('radar')
          )
          ),
          fluidRow(
            column(
              width=8,
              h3("Experience"),
                plotOutput("gant",click="gant_bar")
            ),
            column(
              width=4,
              h3("Competencies"),
              textOutput("exp_notes")
            )
          ),
          fluidRow(id="Skills",
                   h3("Skills"),
                   plotOutput("skills")
                   )
        
        ) # end ui
              
        server <- function(input, output) {
          
          # radar personality plo
          output$radar <- renderPlot({
            radar_plot(personality_data_w)
          })
          
          # Gant Plot ----
          output$gant <- renderPlot({
            plot_gant(experiences)
          })
          ## plot Notes based on which bar is clicked on gant
  ##
  output$exp_notes <- renderText({
    req(input$plot_click)
    browser() #interactive debugger
    near_points(experiences,input$plot_click)  # ? don't know how to specify that I want text from a specific column
  })
          # skills Plot ----
          output$skills <- renderPlot({
            skills_lolli_plot(datAnal_skills)
          })
        }

enter image description here


Solution

  • Since you have not provided the function plot_gant, I created my own version of a Gantt chart to demonstrate how to display the notes:

    library(tidyverse)
    library(shiny)
    
    experiences <- tribble(
      ~name, ~start, ~finish, ~notes,
      "Civil Engineering", 1995, 1999, "Wastwater project",
      "M.Eng Chemical Engineering", 2000, 2002, "Treatability Studies",
      "Ph.D - Chemical Engineering", 2002, 2008, "Optimizing growth conditions"
    )
    
    ui <- fluidPage(
      plotOutput("gant", click = "gant_click"),
      textOutput("notes")
    )
    
    server <- function(input, output, session) {
      output$notes <- renderText({
        req(input$gant_click)
    
        # input is continiously scaled.
        # round to get next row id
        # y if coord_flip(), x otherwise
        row_id <- round(input$gant_click$y)
    
        str_glue(
          "clicked:", experiences[[row_id, "name"]],
          "notes:", experiences[[row_id, "notes"]],
          .sep = "\n"
        )
      })
    
      output$gant <- renderPlot({
        experiences %>%
          ggplot(aes(x = name)) +
          geom_linerange(aes(ymin = start, ymax = finish), size = 10) +
          coord_flip()
      })
    }
    
    shinyApp(ui, server)