Comparing changes
Open a pull request
- 14 commits
- 25 files changed
- 0 comments
- 1 contributor
If step == 1, attr("steps") returns 'undefined', which was not checked.
- +8 −3 DESCRIPTION
- +7 −2 NEWS.md
- +16 −7 R/input-time.R
- +23 −3 R/utils.R
- +1 −1 R/zzz.R
- +33 −16 README.Rmd
- +65 −28 README.md
- +17 −3 cran-comments.md
- +3 −0 inst/WORDLIST
- +9 −4 inst/example/app.R
- +12 −0 inst/example/rsconnect/shinyapps.io/burgerga/shinyTimeExample.dcf
- +22 −1 inst/www/input_binding_time.js
- BIN man/figures/timeInput.png
- +0 −1 man/shinyTime.Rd
- +2 −2 man/shinyTimeExample.Rd
- +12 −6 man/timeInput.Rd
- +2 −2 man/updateTimeInput.Rd
- +6 −0 revdep/.gitignore
- +38 −0 revdep/README.md
- +5 −0 revdep/email.yml
- +1 −0 revdep/failures.md
- +1 −0 revdep/problems.md
- +3 −0 tests/spelling.R
- +4 −0 tests/testthat.R
- +10 −0 tests/testthat/test-round-time.R
| @@ -1,11 +1,11 @@ | ||
| Package: shinyTime | ||
| Type: Package | ||
| Title: A Time Input Widget for Shiny | ||
| Version: 0.2.1 | ||
| Version: 1.0.0 | ||
| Authors@R: person("Gerhard", "Burger", email = "burger.ga@gmail.com", role = c("aut", "cre")) | ||
| Description: Provides a time input widget for Shiny. This widget allows intuitive time input in the | ||
| '[hh]:[mm]:[ss]' or '[hh]:[mm]' (24H) format by using a separate numeric input for each time | ||
| component. The interface with R uses 'DateTimeClasses' objects. See the project page for more | ||
| component. The interface with R uses date-time objects. See the project page for more | ||
| information and examples. | ||
| License: GPL-3 | file LICENSE | ||
| LazyData: TRUE | ||
| @@ -14,4 +14,9 @@ Imports: | ||
| shiny | ||
| URL: https://github.com/burgerga/shinyTime | ||
| BugReports: https://github.com/burgerga/shinyTime/issues | ||
| RoxygenNote: 5.0.1 | ||
| RoxygenNote: 6.1.1 | ||
| Encoding: UTF-8 | ||
| Language: en-US | ||
| Suggests: | ||
| testthat (>= 2.1.0), | ||
| spelling | ||
| @@ -5,6 +5,10 @@ Also [Keep a CHANGELOG](http://keepachangelog.com/). | ||
|
|
||
| ## [Unreleased] | ||
|
|
||
| ## [1.0.0] - 2019-05-28 | ||
| ### Added | ||
| - Input time with minutes rounded to the nearest user-specified multiple | ||
|
|
||
| ## [0.2.1] - 2016-10-07 | ||
| ### Added | ||
| - Updated style to match other shiny inputs | ||
| @@ -23,6 +27,7 @@ time (invalid values are set to 0) | ||
| ### Added | ||
| - Initial release | ||
|
|
||
| [Unreleased]: https://github.com/burgerga/shinyTime/compare/v0.2.0...HEAD | ||
| [0.2.0]: https://github.com/burgerga/shinyTime/compare/v0.1.0...v0.2.0 | ||
| [Unreleased]: https://github.com/burgerga/shinyTime/compare/v1.0.0...HEAD | ||
| [1.0.0]: https://github.com/burgerga/shinyTime/compare/v0.2.1...v1.0.0 | ||
| [0.2.1]: https://github.com/burgerga/shinyTime/compare/v0.2.0...v0.2.1 | ||
| [0.2.0]: https://github.com/burgerga/shinyTime/compare/v0.1.0...v0.2.0 | ||
| @@ -18,10 +18,11 @@ NULL | ||
| #' | ||
| #' @inheritParams shiny::textInput | ||
| #' @param value The desired time value. Must be a instance of \code{\link{DateTimeClasses}}. | ||
| #' @param seconds Show input for seconds. Defaults to FALSE | ||
| #' @param seconds Show input for seconds. Defaults to TRUE. | ||
| #' @param minute.steps Round time to multiples of \code{minute.steps} (should be a whole number). If not NULL sets \code{seconds} to \code{FALSE}. | ||
| #' | ||
| #' @family shinyTime functions | ||
| #' @seealso \code{\link{strptime}}, \code{\link{strftime}} | ||
| #' @seealso \code{\link{strptime}}, \code{\link{strftime}}, \code{\link{DateTimeClasses}} | ||
| #' | ||
| #' @examples | ||
| #' ## Only run examples in interactive R sessions | ||
| @@ -38,17 +39,25 @@ NULL | ||
| #' timeInput("time3", "Time:", value = strptime("12:34:56", "%T")), | ||
| #' | ||
| #' # Use %H:%M format | ||
| #' timeInput("time4", "Time:", seconds = FALSE) | ||
| #' timeInput("time4", "Time:", seconds = FALSE), | ||
| #' | ||
| #' # Use multiples of 5 minutes | ||
| #' timeInput("time5", "Time:", minute.steps = 5) | ||
| #' ) | ||
| #' | ||
| #' shinyApp(ui, server = function(input, output) { }) | ||
| #' } | ||
| #' | ||
| #' @importFrom htmltools tagList singleton tags | ||
| #' @export | ||
| timeInput <- function(inputId, label, value = NULL, seconds = TRUE) { | ||
| timeInput <- function(inputId, label, value = NULL, seconds = TRUE, minute.steps = NULL) { | ||
| if(is.null(value)) value <- getDefaultTime() | ||
| value_list <- parseTimeFromValue(value) | ||
| if(!is.null(minute.steps)) { | ||
| stopifnot(is.wholenumber(minute.steps)) | ||
| seconds = F | ||
| value <- roundTime(value, minute.steps) | ||
| } | ||
| value_list <- dateToTimeList(value) | ||
| style <- "width: 8ch" | ||
| input.class <- "form-control" | ||
| tagList( | ||
| @@ -60,7 +69,7 @@ timeInput <- function(inputId, label, value = NULL, seconds = TRUE) { | ||
| tags$div(class = "input-group", | ||
| tags$input(type="number", min="0", max="23", step="1", value = value_list$hour, | ||
| style = style, class = paste(c(input.class, 'shinytime-hours'), collapse = " ")), | ||
| tags$input(type="number", min="0", max="59", step="1", value = value_list$min, | ||
| tags$input(type="number", min="0", max="59", step=minute.steps, value = value_list$min, | ||
| style = style, class = paste(c(input.class, 'shinytime-mins'), collapse = " ")), | ||
| if(seconds) tags$input(type="number", min="0", max="59", step="1", value = value_list$sec, | ||
| style = style, class = paste(c(input.class, 'shinytime-secs'), collapse = " ")) else NULL | ||
| @@ -98,7 +107,7 @@ timeInput <- function(inputId, label, value = NULL, seconds = TRUE) { | ||
| #' | ||
| #' @export | ||
| updateTimeInput <- function(session, inputId, label = NULL, value = NULL) { | ||
| value <- parseTimeFromValue(value) | ||
| value <- dateToTimeList(value) | ||
| message <- dropNulls(list(label=label, value = value)) | ||
| session$sendInputMessage(inputId, message) | ||
| } | ||
| @@ -19,7 +19,7 @@ dropNulls <- function(x) { | ||
| x[!vapply(x, is.null, FUN.VALUE=logical(1))] | ||
| } | ||
|
|
||
| parseTimeFromValue <- function(value){ | ||
| dateToTimeList <- function(value){ | ||
| if(is.null(value)) return(NULL) | ||
| posixlt_value <- unclass(as.POSIXlt(value)) | ||
| time_list <- lapply(posixlt_value[c('hour', 'min', 'sec')], function(x) { | ||
| @@ -28,6 +28,26 @@ parseTimeFromValue <- function(value){ | ||
| return(time_list) | ||
| } | ||
|
|
||
| timeListToDate <- function(value) { | ||
| strptime(paste(c(value$hour, value$min, value$sec), collapse = ':'), "%T") | ||
| } | ||
|
|
||
| timeStringToDate <- function(string) { | ||
| strptime(string, format = "%T") | ||
| } | ||
|
|
||
| getDefaultTime <- function(){ | ||
| return(as.POSIXlt("0:0:0", format = "%H:%M:%S")) | ||
| } | ||
| timeStringToDate("00:00:00") | ||
| } | ||
|
|
||
| # From ?is.integer | ||
| is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol | ||
|
|
||
| roundTime <- function(time, minutes) { | ||
| stopifnot(is.wholenumber(minutes)) | ||
| # Copied from plyr:::round_any.numeric | ||
| round_any <- function(x, accuracy, f=round){f(x/accuracy) * accuracy} | ||
| s <- round_any(unclass(as.POSIXct(time)), 60 * minutes) | ||
| # Inspired by lubridate::origin | ||
| structure(s, class = c("POSIXct", "POSIXt"), tzone = "UTC") | ||
| } | ||
| @@ -15,7 +15,7 @@ | ||
| # Replace NULL by 0 | ||
| data[sapply(data, is.null)] <- 0 | ||
| # Convert to time object | ||
| strptime(paste(unlist(data), collapse = ':'), "%T") | ||
| timeListToDate(data) | ||
| }) | ||
| } | ||
|
|
||
| @@ -1,5 +1,4 @@ | ||
| --- | ||
| title: shinyTime | ||
| output: github_document | ||
| --- | ||
|
|
||
| @@ -13,20 +12,31 @@ knitr::opts_chunk$set( | ||
| ) | ||
| ``` | ||
|
|
||
| # shinyTime <a href='https://burgerga.shinyapps.io/shinyTimeExample/' target="_blank"><img src='man/figures/timeInput.png' align="right" height="138.5" /></a> | ||
|
|
||
|
|
||
|  | ||
|  | ||
| [](https://travis-ci.org/burgerga/shinyTime) | ||
|
|
||
| This package provides a `timeInput` widget for Shiny. This widget allows intuitive time input in the | ||
| `[hh]:[mm]:[ss]` or `[hh]:[mm]` (24H) format by using a separate numeric input for each time | ||
| component. Setting and getting of the time in R is done with 'DateTimeClasses' objects. | ||
| ## Overview | ||
|
|
||
| #Usage | ||
| shinyTime provides a `timeInput` widget for Shiny. This widget allows intuitive time input in the | ||
| `[hh]:[mm]:[ss]` or `[hh]:[mm]` (24H) format by using a separate numeric input for each time | ||
| component. Setting and getting of the time in R is done with date-time objects. | ||
|
|
||
| As the `shinyTime` package mimics the existing shiny functionality, using the package is easy. Some | ||
| examples of adding an input widget to the UI: | ||
| ## Installation | ||
|
|
||
| ```{r eval = FALSE} | ||
| # Install from CRAN | ||
| install.packages("shinyTime") | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| As the `shinyTime` package mimics the existing shiny functionality, using the package is easy: | ||
|
|
||
| ```{r eval = FALSE} | ||
| ui <- fluidPage( | ||
| # Using the default time 00:00:00 | ||
| timeInput("time1", "Time:"), | ||
| @@ -39,17 +49,20 @@ ui <- fluidPage( | ||
| # Use %H:%M format | ||
| timeInput("time4", "Time:", seconds = FALSE) | ||
| # Use multiples of 5 minutes | ||
| timeInput("time5", "Time:", minute.steps = 5) | ||
| ) | ||
| ``` | ||
|
|
||
| Note that setting an inital value is done with a | ||
| [`DateTime`](http://www.inside-r.org/r-doc/base/DateTimeClasses) object, in the same way as setting | ||
| Note that setting an initial value is done with a | ||
| [date-time object](https://www.rdocumentation.org/packages/base/topics/DateTimeClasses), in the same way as setting | ||
| a date in `dateInput` can be done with a `Date` object. | ||
|
|
||
| The value retrieved will also be a `DateTime` object. You need to convert it to character to be able | ||
| to print the time, as the default character representation does not include it. An example: | ||
| The value retrieved will also be a date-time object. You need to convert it to character to be able | ||
| to show the time, as the default character representation does not include time. For example: | ||
|
|
||
| ``` | ||
| ```{r eval=FALSE} | ||
| server <- function(input, output) { | ||
| # Print the time in [hh]:[mm]:[ss] everytime it changes | ||
| observe(print(strftime(input$time1, "%T"))) | ||
| @@ -59,7 +72,11 @@ server <- function(input, output) { | ||
| } | ||
| ``` | ||
|
|
||
| For a fully functional app go to the | ||
| [ShinyApps example](https://burgerga.shinyapps.io/shinyTimeExample/) (can be a bit slow) or try the | ||
| `shinyTime::shinyTimeExample()` function after installing the package with | ||
| `install.packages('shinyTime')`. | ||
| For a demo, visit the [online example app](https://burgerga.shinyapps.io/shinyTimeExample/) or try the | ||
| `shinyTime::shinyTimeExample()` function. | ||
|
|
||
| ## Donate | ||
|
|
||
| If this package is helpful to you please consider getting me a coffee to keep the work going ;) | ||
|
|
||
| <a href='https://ko-fi.com/L4L6LMTN' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi3.png?v=2' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a> | ||
| @@ -1,40 +1,77 @@ | ||
| shinyTime | ||
| ================ | ||
|
|
||
| <!-- README.md is generated from README.Rmd. Please edit that file --> | ||
|   [](https://travis-ci.org/burgerga/shinyTime) | ||
|
|
||
| This package provides a `timeInput` widget for Shiny. This widget allows intuitive time input in the `[hh]:[mm]:[ss]` or `[hh]:[mm]` (24H) format by using a separate numeric input for each time component. Setting and getting of the time in R is done with 'DateTimeClasses' objects. | ||
| # shinyTime <a href='https://burgerga.shinyapps.io/shinyTimeExample/' target="_blank"><img src='man/figures/timeInput.png' align="right" height="138.5" /></a> | ||
|
|
||
| Usage | ||
| ===== | ||
|  | ||
|  [](https://travis-ci.org/burgerga/shinyTime) | ||
|
|
||
| As the `shinyTime` package mimics the existing shiny functionality, using the package is easy. Some examples of adding an input widget to the UI: | ||
| ## Overview | ||
|
|
||
| ui <- fluidPage( | ||
| # Using the default time 00:00:00 | ||
| timeInput("time1", "Time:"), | ||
| shinyTime provides a `timeInput` widget for Shiny. This widget allows | ||
| intuitive time input in the `[hh]:[mm]:[ss]` or `[hh]:[mm]` (24H) format | ||
| by using a separate numeric input for each time component. Setting and | ||
| getting of the time in R is done with date-time objects. | ||
|
|
||
| # Set to current time | ||
| timeInput("time2", "Time:", value = Sys.time()), | ||
| ## Installation | ||
|
|
||
| # Set to custom time | ||
| timeInput("time3", "Time:", value = strptime("12:34:56", "%T")), | ||
|
|
||
| # Use %H:%M format | ||
| timeInput("time4", "Time:", seconds = FALSE) | ||
| ) | ||
| ``` r | ||
| # Install from CRAN | ||
| install.packages("shinyTime") | ||
| ``` | ||
|
|
||
| Note that setting an inital value is done with a [`DateTime`](http://www.inside-r.org/r-doc/base/DateTimeClasses) object, in the same way as setting a date in `dateInput` can be done with a `Date` object. | ||
| ## Usage | ||
|
|
||
| The value retrieved will also be a `DateTime` object. You need to convert it to character to be able to print the time, as the default character representation does not include it. An example: | ||
| As the `shinyTime` package mimics the existing shiny functionality, | ||
| using the package is easy: | ||
|
|
||
| server <- function(input, output) { | ||
| # Print the time in [hh]:[mm]:[ss] everytime it changes | ||
| observe(print(strftime(input$time1, "%T"))) | ||
|
|
||
| # Print the time in [hh]:[mm] everytime it changes | ||
| observe(print(strftime(input$time4, "%R"))) | ||
| } | ||
| ``` r | ||
| ui <- fluidPage( | ||
| # Using the default time 00:00:00 | ||
| timeInput("time1", "Time:"), | ||
| For a fully functional app go to the [ShinyApps example](https://burgerga.shinyapps.io/shinyTimeExample/) (can be a bit slow) or try the `shinyTime::shinyTimeExample()` function after installing the package with `install.packages('shinyTime')`. | ||
| # Set to current time | ||
| timeInput("time2", "Time:", value = Sys.time()), | ||
| # Set to custom time | ||
| timeInput("time3", "Time:", value = strptime("12:34:56", "%T")), | ||
| # Use %H:%M format | ||
| timeInput("time4", "Time:", seconds = FALSE) | ||
| # Use multiples of 5 minutes | ||
| timeInput("time5", "Time:", minute.steps = 5) | ||
| ) | ||
| ``` | ||
|
|
||
| Note that setting an initial value is done with a [date-time | ||
| object](https://www.rdocumentation.org/packages/base/topics/DateTimeClasses), | ||
| in the same way as setting a date in `dateInput` can be done with a | ||
| `Date` object. | ||
|
|
||
| The value retrieved will also be a date-time object. You need to convert | ||
| it to character to be able to show the time, as the default character | ||
| representation does not include time. For example: | ||
|
|
||
| ``` r | ||
| server <- function(input, output) { | ||
| # Print the time in [hh]:[mm]:[ss] everytime it changes | ||
| observe(print(strftime(input$time1, "%T"))) | ||
| # Print the time in [hh]:[mm] everytime it changes | ||
| observe(print(strftime(input$time4, "%R"))) | ||
| } | ||
| ``` | ||
|
|
||
| For a demo, visit the [online example | ||
| app](https://burgerga.shinyapps.io/shinyTimeExample/) or try the | ||
| `shinyTime::shinyTimeExample()` function. | ||
|
|
||
| ## Donate | ||
|
|
||
| If this package is helpful to you please consider getting me a coffee to | ||
| keep the work going | ||
| ;) | ||
|
|
||
| <a href='https://ko-fi.com/L4L6LMTN' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi3.png?v=2' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a> |
| @@ -1,7 +1,21 @@ | ||
| ## Test environments | ||
| * travis-ci, Ubuntu 12.04, R 3.3.1 | ||
| * travis-ci, Ubuntu 14.04, R 3.6 | ||
| * local machine, Ubuntu 18.04, R 3.6 | ||
| * local machine, Windows 10, R 3.6 | ||
| * win-builder (devel and release) | ||
|
|
||
| ## R CMD check results | ||
| There were no ERRORs, NOTEs or WARNINGs. | ||
|
|
||
| There were no ERRORs, NOTEs or WARNINGs. | ||
|
|
||
| However, for win-builder release I get: | ||
| ``` | ||
| Error in library.dynam(lib, package, package.lib) : | ||
| DLL 'Rcpp' not found: maybe not installed for this architecture?" | ||
| ``` | ||
|
|
||
| but on my local Windows 10, and win-builder devel everything is fine, | ||
| so I think this might be an issue with the build system. | ||
| (the version currently on CRAN also fails: https://cloud.r-project.org//web/checks/check_results_shinyTime.html) | ||
|
|
||
| ## Downstream dependencies | ||
| Checked with revdepcheck, no problems. |
| @@ -0,0 +1,3 @@ | ||
| CHANGELOG | ||
| hh | ||
| ss |