1
votes

I'm making an R Shiny app where the graph type switches between line and stacked area. I want to have a slider which fliters the input data by y-axis values. When the graph type is stacked, the maximum y-axis value is obviously a lot higher than for a line graph. How do I update the maximum value for the slider when the graph type changes? As shown in the code below, I'm trying to use observeEvent, but this isn't having the desired effect. Any help would be greatly appreciated (I acknowledge that plotly could handle some of this but in general, I don't like the package).

library(shiny)
library(tidyverse)

# simulate some grouped data
mydata=bind_rows(lapply(LETTERS[1:5],function(x){
  as_tibble(data.frame(xvals=seq(1,100,1))) %>% 
    mutate(grp=x) })) %>% 
  rowwise() %>% 
  mutate(yvals=runif(1)) %>%
  ungroup() %>% 
  group_by(grp) %>% 
  arrange(xvals) %>% 
  mutate(yvals=cumsum(yvals)) %>% 
  ungroup()


ui=fluidPage(
  titlePanel("Dev reactive yaxis"),
  sidebarLayout(
    sidebarPanel(
      radioButtons('graphType',"",c("line","stacked"),"line"),
      uiOutput("ylimits")),
    mainPanel(plotOutput("myplot"))))


server=function(input,output,session) {

  ## y slider
  output$ylimits=renderUI({
    # req(ymax())
    req(input$graphType)
    if(input$graphType=="line"){
      ymax=max(mydata$yvals,na.rm=T)
    } else{
      temp=mydata %>% 
        filter(yvals==max(yvals,na.rm=T))
      ymax=sum(temp$yvals,na.rm=T)
    }
    
    sliderInput('yslider','',min=0,max=ymax,value=c(0,ymax))
  })
  
  ## update slider when graph type changes. This doesn't seem to work :(
  observeEvent(input$graphType=="stacked",{
    # rv$ymax<-funGety
    
    ## get max value for yaxis
     if(input$graphType=="line"){
      ymax=max(mydata$yvals,na.rm=T)
    } else{
      temp=mydata %>% 
        filter(yvals==max(yvals,na.rm=T))
      ymax=sum(temp$yvals,na.rm=T)
    }
    updateSliderInput(session=session,'yslider','',min=0,max=ymax,value=c(0,ymax))
  })
  
  
  ## plot data
  pdat=reactive({
    req(input$yslider)
    mydata %>% 
      filter(yvals>input$yslider[1]&yvals<input$yslider[2])
  })
  
  ## make plot
  myplot=reactive({
    req(pdat())
    req(input$graphType)
    ggplot(pdat(),aes(xvals,yvals))+
      { if (input$graphType=="line") geom_line(aes(colour=grp)) else geom_area(aes(fill=grp)) }
  })
  
  ## render plot
  output$myplot=renderPlot({
    req(myplot())
    myplot()
  })
}

shinyApp(ui=ui,server=server)
When the graph is stacked, you want the slider bar to be what, like the ~239 of each of them stacked? If that's the case, the issue I see is none of the yvals from each group will be in the 200's, they will still max in the 50s. Meaning if the slider bar was at 100, 150, or 200, nothing would filter out, until you drop below 50, where it will begin to filter. - Silentdevildoll
If you did want it to filter at the ~239 or so, then your code is really close already. The observeEvent would be unneeded, all you would need to do is change the "else" of the ylimits renderUI to temp=mydata %>% group_by(grp)%>% filter(yvals==max(yvals,na.rm=T)) This way it would sum up each of the groups - Silentdevildoll