Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Sidebar in a shiny app depending on tab selected

Tags:

tabs

r

csv

shiny

I am trying to build a shiny app where the sidebar is dynamic based on the tab that is selected. The sidebar is populated by a csv file. Right now it is just reading a CSV file named machines.csv. I would want that to be able to read for example austin.csv, dallas.cav based on the tab name. There will be 7 tabs total. Also I am having trouble with the plot area. I want the plot to render to the correct tab (which is always the selected tab).

The code I have is here. The app is at http://45.55.208.171:3838/

Only the first two machines have data right now. And the Dallas tab I can not get to work because it seems I can't use the same render plot ID. Not sure how to make that dynamic based on the tab as well.

library(shiny)
library(ggplot2)
library(scales)
library(grid)
library(RColorBrewer)
library(lubridate)
library(ggrepel)
library(plyr)
library(dplyr)
library(DT)
library(RCurl)
library(readr)
library(stringr)
Machine <-read.csv("machines.csv")
Sys.setenv(TZ="US/Central")
SDate <- Sys.Date()
ui <- fluidPage(
  titlePanel("Printer Utilization"),
  sidebarLayout(
    sidebarPanel(width = 2,
                 radioButtons("typeInput", "Machine", t(Machine[1]) , width = 4),
                 dateInput("RepDate", "Date of Report",format = "mm-dd-yyyy",value = "08-03-2016"),
                 downloadButton("downloadplot", "Download")),
    mainPanel(
      tabsetPanel(id = "plants",
        tabPanel("Austin",value = "Austin", plotOutput("plants",width = "120%",height = "600px")),
        tabPanel("Dallas",value = "Dallas", plotOutput("Dallas",width = "120%",height = "600px")),

        tabPanel("Table", div(DT::dataTableOutput("log"), style = "font-size:50%")))
    )))

server <- function(input, output) {
  output$plants <-renderPlot({
    Sys.setenv(TZ="US/Central")
    SDate <- Sys.Date()
    SDate <-as.POSIXct(SDate,format="%Y%m%d")+18000
    RepDate.1 <- reactive({ as.POSIXct(input$RepDate,format="%Y%m%d", tz="US/Central")}+18000)
    typeInput.1 <- reactive({input$typeInput})
    RDate <- RepDate.1()
    Machine.1<-reactive({subset(Machine,MNames.i==typeInput.1())})
    Serial = Machine.1()$Serial.i
    IP = Machine.1()$IP.i
    Type = Machine.1()$Type.i
    if (Type=="b"){
      if (SDate==RepDate.1())
      {
        extension <- ".ACL"
        logdata <- (read.csv(paste(Serial, as.character(RDate,format="%Y%m%d"), extension, sep = "") , sep = ';'))
        RDate <- RDate-86400
        extension <- ".CSV"
        logdata <- (rbind(read.csv(paste(Serial, as.character(RDate,format="%Y%m%d"), extension, sep = "") , sep = ';'),logdata))
      }
      if (SDate!=RepDate.1())
      {
        extension <- ".CSV"
        try(logdata <- (read.csv(paste(Serial, as.character(RDate,format="%Y%m%d"), extension, sep = "") , sep = ';')))
        RDate <-RDate-86400
        logdata <- (rbind(read.csv(paste(Serial, as.character(RDate,format="%Y%m%d"), extension, sep = "") , sep = ';'),logdata))
        RDate <-RDate+172800
        if (RDate==SDate)
        {extension <- ".ACL"}
        try(logdata <- (rbind(read.csv(paste(Serial, as.character(RDate,format="%Y%m%d"), extension, sep = "") , sep = ';'),logdata)))
      }

      logdata <- subset(logdata, (startdate == as.character(input$RepDate,format="%Y-%m-%d")) | (readydate == as.character(input$RepDate,format="%Y-%m-%d")))
      logdata$jobname <- sub(":.*", "", logdata$jobname)
      logdata$starttime.ct   <- as.POSIXct(paste(logdata$startdate, logdata$starttime, sep = " ", format = "%Y%m%d %H:%M:%S", tz="US/Central"))
      logdata$starttime.ct <- force_tz(logdata$starttime.ct,tzone="US/Central")
      logdata$readytime.ct     <- as.POSIXct(paste(logdata$readydate, logdata$readytime, sep = " ", format = "%Y%m%d %H:%M:%S", tz="US/Central"))
      logdata$readytime.ct <- force_tz(logdata$readytime.ct,tzone="US/Central")
      logdata$idletime.ct     <- as.POSIXct(logdata$idletime, format = "%H:%M:%S")
      logdata$idletime.hour   <-as.POSIXlt(logdata$idletime.ct)$hour + as.POSIXlt(logdata$idletime.ct)$min/60 + as.POSIXlt(logdata$idletime.ct)$sec/3600
      logdata$activetime.ct     <- as.POSIXct(logdata$activetime, format = "%H:%M:%S")
      logdata$activetime.hour   <-as.POSIXlt(logdata$activetime.ct)$hour + as.POSIXlt(logdata$activetime.ct)$min/60 + as.POSIXlt(logdata$activetime.ct)$sec/3600

      Sreadytime <- (strptime(logdata$readytime.ct,format="%Y-%m-%d %H:%M:%S"))
      Sstarttime <- (strptime(logdata$starttime.ct,format="%Y-%m-%d %H:%M:%S"))
      Rtime <- (Sreadytime-Sstarttime)/3600
      Idletime <- (strptime(logdata$idletime.ct,format="%Y-%m-%d %H:%M:%S"))
      Utilization <- sum(logdata$activetime.hour/24)
      Utilization <- paste(round(Utilization*100,digits=1),"%",sep="")
      output <- format(sum(logdata$nofprinteda4bw)+sum(logdata$nofprinteda3bw*2), big.mark=",")
      ymax.r = (logdata$idletime.hour/(logdata$idletime.hour+logdata$activetime.hour))
      logdata$jobname <- strtrim(logdata$jobname, 18)
    }
    if (Type=="c"){
      url <- paste("http://",IP,"/xjutil/log.csv", sep="")
      dat <- readLines(url) 
      dat <- dat[-1]
      dat <- dat[-1]
      varnames <- unlist(strsplit(dat[1], ",")) 
      nvar <- length(varnames)
      varnames<-make.names(varnames, unique=TRUE)
      k <- 1 
      dat1 <- matrix(NA, ncol = nvar, dimnames = list(NULL, varnames))

      while(k <= length(dat)){
        k <- k + 1
        #if(dat[k] == "") {k <- k + 1
        #print(paste("data line", k, "is an empty string"))
        if(k > length(dat)) {break}
        #}
        temp <- dat[k]
        # checks if there are enough commas or if the line was broken
        while(length(gregexpr(",", temp)[[1]]) < nvar-1){
          k <- k + 1
          temp <- paste0(temp, dat[k])
        }
        temp <- unlist(strsplit(temp, ","))
        message(k)
        dat1 <- rbind(dat1, temp)
      }

      dat1 = dat1[-1,]     
      logdata<-as.data.frame(dat1)

      logdata$starttime.ct <-strptime(logdata$timestamp.printing,format="%Y %m %d %H %M %S", tz="US/Central")
      logdata$readytime.ct <-strptime(logdata$timestamp.done.printing,format="%Y %m %d %H %M %S", tz="US/Central")

      logdata$date.timestamp.printing <- as.character(substr(logdata$timestamp.printing, 1, 10))
      logdata$date.timestamp.done.printing <- as.character(substr(logdata$timestamp.done.printing, 1, 10))

      logdata <- subset(logdata, (date.timestamp.printing == as.character(RepDate.1(), format = "%Y %m %d")) | (date.timestamp.done.printing == as.character(RepDate.1(), format = "%Y %m %d")))
      logdata$title <- sub(":.*", "", logdata$title)

      logdata$activetime <- logdata$readytime.ct - logdata$starttime.ct
      Utilization <- sum(logdata$activetime/86400)
      Utilization <- paste(round(Utilization*100,digits=1),"%",sep="")

      output<-format(sum(as.numeric(logdata$total.pages.printed)),big.mark = ",")
      output<-""
      ymax.r = 0
      logdata$jobname <- logdata$title
      logdata$jobname <- strtrim(logdata$jobname, 18)
    }
    if (Type=="a"){
      url <- paste("http://",IP,"/logs/","?C=M;O=D", sep="")
      html <- paste(readLines(url), collapse="\n")
      matched <- str_match_all(html, "<a href=\"(1100.*?)\"")
      links <- matched[[1]][, 2]
      print(links)
      for (i in links[1:15])
      {
        url <- paste("http://",IP,"/logs/", sep="")
        url.a <- paste(url,as.character(i) ,sep = "")
        print(url.a)
        if (exists("logdata")){
          logdata <- rbind(read.csv(url.a, header=TRUE, fill = TRUE, sep = ","), logdata)
        }
        else{
          logdata <- read.csv(url.a, header=TRUE, fill = TRUE, sep = ",")
          print(url.a)
        }
      }
      logdata$size <- logdata$SqFt
      logdata <- logdata %>% distinct(Start.time, .keep_all = TRUE)
      logdata$Start.time <- strptime(logdata$Start.time, format="%a %b %d %H:%M:%S %Y")
      logdata$Total.time <- as.POSIXlt(logdata$Total.time, format = "%H:%M:%S")
      logdata$Total.time <- as.POSIXlt(logdata$Total.time)$hour + as.POSIXlt(logdata$Total.time)$min/60 + as.POSIXlt(logdata$Total.time)$sec/3600
      logdata$readytime.ct <- as.POSIXct(logdata$Start.time)+(logdata$Total.time * 3600)
      logdata$starttime.ct <- as.POSIXct(logdata$Start.time)
      logdata$starttime <- strptime(logdata$starttime.ct,format="%Y-%m-%d")
      logdata$End.time <- as.POSIXct(logdata$Start.time)+(logdata$Total.time * 3600)
      logdata <- subset(logdata, as.character(starttime,format="%Y-%m-%d") == as.character(RepDate.1(),format="%Y-%m-%d") | (strptime(End.time,format="%Y-%m-%d") == as.character(RepDate.1(),format="%Y-%m-%d")))
      Utilization <- (sum(logdata$Total.time))/60
      Utilization <- paste(round(Utilization*100,digits=1),"%",sep="")
      output<-0
      #ymax.r = logdata$SqFt.hr/300
      ymax.r = 0
      logdata$jobname <- logdata$File.name
    }  
    p<-ggplot(logdata, aes(xmin = starttime.ct, xmax = readytime.ct, ymin = 0, ymax = 1-ymax.r, fill = factor(jobname))) + geom_rect(alpha = .9) +
      labs(title=paste(typeInput.1(),RepDate.1(), Utilization, output,sep=" "),x="Time of day",y="Run Time") + theme(legend.position="bottom", legend.title = element_blank(), legend.title = element_text(size=10),legend.title=element_blank()) + guides(fill=guide_legend(nrow=5)) +
      scale_x_datetime(labels = date_format("%H:%M", tz="US/Central"),breaks = date_breaks("1 hour"),expand=c(0,0)) +
      coord_cartesian(xlim = as.POSIXct(c(RepDate.1()+86400,RepDate.1()),format="%Y%m%d %H:%M:%S", tz="US/Central")) +
      scale_y_continuous(labels=percent,expand=c(0,0),limits=c(0,1)) 
    print(p)
    file<-ggsave("myplot.pdf",device = "pdf",plot = p,width=16, height=10,paper="special")
  })

  output$downloadplot <- downloadHandler(

    filename="myplot.pdf",  # desired file name on client 
    content=function(con) {
      file.copy("myplot.pdf", con)
    }
  )
  outputOptions(output, "downloadplot", suspendWhenHidden=FALSE)

}
shinyApp(ui = ui, server = server)
like image 432
Michael Ciesielczyk Avatar asked Nov 09 '22 10:11

Michael Ciesielczyk


1 Answers

How about this? Here, I hardcoded choice_set variable, but I suppose you can define it using external data file.

Keys.

  • Keep your data in reactiveValues, so it can be referred to from server operations.
  • Use observeEvent(input$tabset, ...) to trigger server operation only when the tabset value has been changed.
  • Use updateRadioButtons to change the properties of the input components.

R

library(shiny)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(radioButtons("radio", "radio", c("A", "B"))),
    mainPanel(
      tabsetPanel(id = "tabset",
                  tabPanel("alphabet", value = "alpha"),
                  tabPanel("number", value = "number"))
)))


server <- function(input, output, session)
{
  RV <- reactiveValues(
    choise_set = list(
      alpha = c("A", "B"),
      number = c("1", "2", "3")
    )
  )

  observeEvent(input$tabset, {
    updateRadioButtons(session, "radio",
                       choices = RV$choise_set[[input$tabset]])
  })
}

runApp(list(ui = ui, server = server))
like image 71
Kota Mori Avatar answered Nov 15 '22 07:11

Kota Mori