Search code examples
rshinyposixutcposixct

time conversion in R using the timevis package


In the following I have a shiny app which add an item to timeline using timevis package. The problem is when user add the first item everything is fine, as soon as user tries to add more item, the date behaves awkward ! it is ignoring the provided date and always put the new item on 1970 ! Any idea how to fix this :

library(shiny)
library(timevis)
library(dplyr)

randomID <- function() {
  paste(sample(c(letters, LETTERS, 0:9), 16, replace = TRUE), collapse = "")
}

prettyDate <- function(d) {
  if (is.null(d)) return()
  posix <- as.POSIXct(d, format = "%Y-%m-%dT%H:%M:%OS", tz = "UTC")
  corrected <- lubridate::with_tz(posix, tzone = Sys.timezone())
  format(corrected, "%Y-%m-%d %H:%M:%OS %Z")
}

ui <- fluidPage(
  timevisOutput("timeline"),
  textInput("addText", tags$h4("Add item:"), "New item"),
  dateInput("addStart", "Start date:", Sys.Date()),
  textInput("addGroup", "Group:", "gym"),
  actionButton("addBtn", "Add"),
  uiOutput("removeIdsOutput", inline = TRUE),
  actionButton("removeItem", "Remove"),
  tableOutput("table")
)

server <- function(input, output, session) {
  
  timelineData <- reactiveVal(data.frame(id = character(), 
                                         content = character(),
                                         start = character(),
                                         group = character(),
                                         type = character(), 
                                         stringsAsFactors = FALSE))
  
  observeEvent(input$addBtn, {
    newItem <- data.frame(id = randomID(),
                          content = input$addText,
                          start = as.POSIXct(input$addStart, tz = "UTC"),
                          group = input$addGroup,
                          
                          stringsAsFactors = FALSE)
    timelineData(rbind(timelineData(), newItem))
  })
  
  output$timeline <- renderTimevis({
    # Creating the groups data.frame
    groupList <- unique(timelineData()$group)
    groupData <- data.frame(id = groupList, content = groupList)
    
    timevis(data = timelineData(), groups = groupData, options = list(editable = TRUE))
  })
  
  output$table <- renderTable({
    data <- timelineData()
    data$start <- prettyDate(data$start)
    data
  })
  
  output$removeIdsOutput <- renderUI({
    if(nrow(timelineData()) > 0){
      selectInput("removeIds", tags$h4("Remove item"), timelineData()$id)
    }else{
      NULL
    }
  })
  
  observeEvent(input$removeItem, {
    if(!is.null(input$removeIds)){
      timelineData(timelineData() %>%
                     filter(id != input$removeIds))
    }
  })
  
  observe({
    timelineData(input$timeline_data)
  })
  
}

shinyApp(ui = ui, server = server)

Solution

  • You are setting start = character() in the definition of timelineData. But then you should also convert the item which is read into a character:

    newItem <- data.frame(id = randomID(),
                          content = input$addText,
                          start = as.character(input$addStart),
                          group = input$addGroup,
                          stringsAsFactors = FALSE)
    

    enter image description here