From 4908ef2cf3c9e70f05c0c7e4de4018c9319e7853 Mon Sep 17 00:00:00 2001 From: Stefan Kuethe Date: Fri, 13 Sep 2024 12:35:12 +0200 Subject: [PATCH 1/4] Add func to create multi column headers --- NAMESPACE | 3 ++ R/columns.R | 42 ++++++++++++++++++++- R/experimental.R | 29 ++++++++++++++ R/tabulator.R | 1 + examples/experimental/multi_column_header.R | 7 ++++ examples/formatters/column_editor.R | 9 +++++ examples/formatters/formatter_money.R | 7 +++- examples/misc/header_filter.R | 8 ++++ man/set_column_editor.Rd | 29 ++++++++++++++ man/set_formatter_datetime.Rd | 4 +- man/set_formatter_money.Rd | 9 ++++- man/set_header_filter.Rd | 27 +++++++++++++ man/set_multi_column_header.Rd | 25 ++++++++++++ man/tabulator.Rd | 2 +- 14 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 examples/experimental/multi_column_header.R create mode 100644 examples/formatters/column_editor.R create mode 100644 examples/misc/header_filter.R create mode 100644 man/set_column_editor.Rd create mode 100644 man/set_header_filter.Rd create mode 100644 man/set_multi_column_header.Rd diff --git a/NAMESPACE b/NAMESPACE index d1412dd..ee40f28 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,6 +6,7 @@ export(delete_selected_rows) export(list_to_data_frame) export(redo) export(renderTabulator) +export(set_column_editor) export(set_formatter_color) export(set_formatter_datetime) export(set_formatter_html) @@ -19,6 +20,8 @@ export(set_formatter_textarea) export(set_formatter_tick_cross) export(set_formatter_toggle_switch) export(set_formatter_traffic_light) +export(set_header_filter) +export(set_multi_column_header) export(tabulator) export(tabulatorContext) export(tabulatorOutput) diff --git a/R/columns.R b/R/columns.R index 02f066a..05af0bf 100644 --- a/R/columns.R +++ b/R/columns.R @@ -107,7 +107,7 @@ set_formatter_money <- function( column, decimal = c(",", "."), thousand = c(".", ","), - symbol = "EUR", + symbol = "$", # "\U20AC" symbol_after = "p", negative_sign = "-", precision = FALSE, @@ -300,7 +300,7 @@ set_formatter_toggle_switch <- function( modify_col_def(widget, column, col_update) } -#' Datetime formatter +#' Datetime Formatter #' @inheritParams set_formatter_html #' @param input_format (character): The datetime input format. #' @param output_format (character): The datetime output format. @@ -365,6 +365,44 @@ set_formatter_traffic_light <- function( modify_col_def(widget, column, col_update) } +# Other + +#' Make columns editable +#' @inheritParams set_formatter_html +#' @param columns (character vector): Columns the editor is applied to. +#' @param type (character): Either \code{input} or \code{number}. +#' @example examples/formatters/column_editor.R +#' @export +set_column_editor <- function(widget, columns, type = c("input", "number")) { + col_update <- list(editor = match.arg(type)) + for (column in columns) { + widget <- modify_col_def(widget, column, col_update) + } + + return(widget) +} + +#' Add header filter +#' @inheritParams set_column_editor +#' @param columns (character vector): Columns the editor is applied to. +#' If set to \code{NULL}, the editor is applied to all columns. +#' @example examples/misc/header_filter.R +#' @export +set_header_filter <- function(widget, columns = NULL) { + if (is.null(columns)) { + columns <- colnames(widget$x$data) + } + + col_update <- list(headerFilter = TRUE) + for (column in columns) { + widget <- modify_col_def(widget, column, col_update) + } + + return(widget) +} + +# Generics + modify_col_def <- function(widget, column, col_update) { for (index in 1:length(widget$x$options$columns)) { if (widget$x$options$columns[[index]]$field == column) { diff --git a/R/experimental.R b/R/experimental.R index 0a45376..f59f6bb 100644 --- a/R/experimental.R +++ b/R/experimental.R @@ -1,4 +1,33 @@ # See example here: https://github.com/eodaGmbH/py-tabulator/blob/main/docs/examples/getting_started/shiny_core_multi_row_headers.py +#' Multi Column Header +#' @inheritParams set_formatter_html +#' @param multi_columns (list): Multi column definitions +#' @example examples/experimental/multi_column_header.R +#' @export set_multi_column_header <- function(widget, multi_columns) { + res <- list() + for (key in names(multi_columns)) { + column_names <- multi_columns[[key]] + column_defs <- purrr::map(column_names, ~ find_column(widget, .x)) + res <- append(res, list(list(title = key, columns = column_defs))) + } + # Add columns not used in multi_columns + used_cols <- unlist(multi_columns) + for (column_name in unlist(purrr::map(widget$x$options$columns, ~ .x$field))) { + if (!column_name %in% used_cols) res <- append(res, list(find_column(widget, column_name))) + } + + # return(res) + widget$x$options$columns <- res + return(widget) +} + +find_column <- function(widget, column) { + column_def <- NULL + for (item in widget$x$options$columns) { + if (item$field == column) column_def <- item + } + + return(column_def) } diff --git a/R/tabulator.R b/R/tabulator.R index 231d447..98373cc 100644 --- a/R/tabulator.R +++ b/R/tabulator.R @@ -1,5 +1,6 @@ #' Create a Tabulator Widget #' +#' Dots in column names are replaced by underscores. #' @param data (data.frame, character or list): In spreadsheet mode data needs to be a list or \code{NULL} #' for an empty spreadsheet. #' @param options (list): Setup options. See \code{\link{tabulator_options}}. diff --git a/examples/experimental/multi_column_header.R b/examples/experimental/multi_column_header.R new file mode 100644 index 0000000..6d7d735 --- /dev/null +++ b/examples/experimental/multi_column_header.R @@ -0,0 +1,7 @@ +multi_columns <- list( + Sepal = c("Sepal_Length", "Sepal_Width"), + Petal = c("Petal_Length", "Petal_Width") +) + +tabulator(iris) |> + set_multi_column_header(multi_columns) diff --git a/examples/formatters/column_editor.R b/examples/formatters/column_editor.R new file mode 100644 index 0000000..2d1ec39 --- /dev/null +++ b/examples/formatters/column_editor.R @@ -0,0 +1,9 @@ +data <- data.frame( + age = c(10, 20, 40), + first_name = c("Franz", "Ferdinand", "Julia"), + last_name = c("Young", "Bowie", "Blackey") +) + +tabulator(data, width = 500) |> + set_column_editor(c("first_name", "last_name")) |> + set_column_editor("age", type = "number") diff --git a/examples/formatters/formatter_money.R b/examples/formatters/formatter_money.R index 902db28..05c3899 100644 --- a/examples/formatters/formatter_money.R +++ b/examples/formatters/formatter_money.R @@ -9,4 +9,9 @@ data <- data.frame( ) tabulator(data, width = 300) |> - set_formatter_money("Account_Balance", symbol = "\U20AC", symbol_after = FALSE, hoz_align = "right") + set_formatter_money( + "Account_Balance", + symbol = "\U20AC", + symbol_after = FALSE, + hoz_align = "right" + ) diff --git a/examples/misc/header_filter.R b/examples/misc/header_filter.R new file mode 100644 index 0000000..6661b5d --- /dev/null +++ b/examples/misc/header_filter.R @@ -0,0 +1,8 @@ +data <- data.frame( + age = c(10, 20, 40), + first_name = c("Franz", "Ferdinand", "Julia"), + last_name = c("Young", "Bowie", "Blackey") +) + +tabulator(data) |> + set_header_filter() diff --git a/man/set_column_editor.Rd b/man/set_column_editor.Rd new file mode 100644 index 0000000..c34ccfd --- /dev/null +++ b/man/set_column_editor.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/columns.R +\name{set_column_editor} +\alias{set_column_editor} +\title{Make columns editable} +\usage{ +set_column_editor(widget, columns, type = c("input", "number")) +} +\arguments{ +\item{widget}{(\code{\link{tabulator}}) A tabulator widget.} + +\item{columns}{(character vector): Columns the editor is applied to.} + +\item{type}{(character): Either \code{input} or \code{number}.} +} +\description{ +Make columns editable +} +\examples{ +data <- data.frame( + age = c(10, 20, 40), + first_name = c("Franz", "Ferdinand", "Julia"), + last_name = c("Young", "Bowie", "Blackey") +) + +tabulator(data, width = 500) |> + set_column_editor(c("first_name", "last_name")) |> + set_column_editor("age", type = "number") +} diff --git a/man/set_formatter_datetime.Rd b/man/set_formatter_datetime.Rd index 340e6c8..22788a7 100644 --- a/man/set_formatter_datetime.Rd +++ b/man/set_formatter_datetime.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/columns.R \name{set_formatter_datetime} \alias{set_formatter_datetime} -\title{Datetime formatter} +\title{Datetime Formatter} \usage{ set_formatter_datetime( widget, @@ -27,7 +27,7 @@ set_formatter_datetime( \item{timezone}{(character): The timezone of the datetime.} } \description{ -Datetime formatter +Datetime Formatter } \examples{ data <- data.frame( diff --git a/man/set_formatter_money.Rd b/man/set_formatter_money.Rd index 15dd0c2..753fe18 100644 --- a/man/set_formatter_money.Rd +++ b/man/set_formatter_money.Rd @@ -9,7 +9,7 @@ set_formatter_money( column, decimal = c(",", "."), thousand = c(".", ","), - symbol = "EUR", + symbol = "$", symbol_after = "p", negative_sign = "-", precision = FALSE, @@ -54,5 +54,10 @@ data <- data.frame( ) tabulator(data, width = 300) |> - set_formatter_money("Account_Balance", symbol_after = FALSE) + set_formatter_money( + "Account_Balance", + symbol = "\U20AC", + symbol_after = FALSE, + hoz_align = "right" + ) } diff --git a/man/set_header_filter.Rd b/man/set_header_filter.Rd new file mode 100644 index 0000000..d8bd8b5 --- /dev/null +++ b/man/set_header_filter.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/columns.R +\name{set_header_filter} +\alias{set_header_filter} +\title{Add header filter} +\usage{ +set_header_filter(widget, columns = NULL) +} +\arguments{ +\item{widget}{(\code{\link{tabulator}}) A tabulator widget.} + +\item{columns}{(character vector): Columns the editor is applied to. +If set to \code{NULL}, the editor is applied to all columns.} +} +\description{ +Add header filter +} +\examples{ +data <- data.frame( + age = c(10, 20, 40), + first_name = c("Franz", "Ferdinand", "Julia"), + last_name = c("Young", "Bowie", "Blackey") +) + +tabulator(data) |> + set_header_filter() +} diff --git a/man/set_multi_column_header.Rd b/man/set_multi_column_header.Rd new file mode 100644 index 0000000..ee5bbc6 --- /dev/null +++ b/man/set_multi_column_header.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/experimental.R +\name{set_multi_column_header} +\alias{set_multi_column_header} +\title{Multi Column Header} +\usage{ +set_multi_column_header(widget, multi_columns) +} +\arguments{ +\item{widget}{(\code{\link{tabulator}}) A tabulator widget.} + +\item{multi_columns}{(list): Multi column definitions} +} +\description{ +Multi Column Header +} +\examples{ +multi_columns <- list( + Sepal = c("Sepal_Length", "Sepal_Width"), + Petal = c("Petal_Length", "Petal_Width") +) + +tabulator(iris) |> + set_multi_column_header(multi_columns) +} diff --git a/man/tabulator.Rd b/man/tabulator.Rd index 9ce3aec..ecafa2f 100644 --- a/man/tabulator.Rd +++ b/man/tabulator.Rd @@ -39,5 +39,5 @@ which is needed for xlsx downloads.} \item{...}{Named arguments that are appended to the \code{options} parameter.} } \description{ -Create a Tabulator Widget +Dots in column names are replaced by underscores. } From 9a7d9597703b2b3c2b45ef20c9e1302935250031 Mon Sep 17 00:00:00 2001 From: Stefan Kuethe Date: Fri, 13 Sep 2024 14:16:20 +0200 Subject: [PATCH 2/4] Update docs --- R/columns.R | 1 - R/spreadsheet.R | 25 ++++++++++++++++++++++ R/tabulator.R | 4 ++-- R/tabulator_options.R | 33 ++++++++++++++++++------------ man/set_formatter_progress.Rd | 3 ++- man/set_formatter_traffic_light.Rd | 3 ++- man/tabulator.Rd | 2 +- man/tabulator_options.Rd | 32 +++++++++++++++++------------ 8 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 R/spreadsheet.R diff --git a/R/columns.R b/R/columns.R index 05af0bf..14788c3 100644 --- a/R/columns.R +++ b/R/columns.R @@ -211,7 +211,6 @@ set_formatter_star <- function(widget, column, number_of_stars, hoz_align = "cen #' If set to \code{NA} the minimum value of the column is used. #' @param max (numeric): The maximum value for progress bar. #' If set to \code{NA} the maximum value of the column is used. -#' @param max description #' @param color (character): Either a single color or a vector of colors #' @param legend (character, \code{TRUE}, JavaScript function): If set to \code{TRUE} the value of the cell is displayed. #' Set to \code{NA} to display no value at all. diff --git a/R/spreadsheet.R b/R/spreadsheet.R new file mode 100644 index 0000000..eec92ed --- /dev/null +++ b/R/spreadsheet.R @@ -0,0 +1,25 @@ +## #' @export +# TODO: Is this useful? +set_spreadsheet_mode <- function( + widget, + spreadsheet_rows = NULL, + spreadsheet_columns = NULL, + spreadsheet_column_definition = NULL, + spreadsheet_sheets = NULL, + spreadsheet_sheet_tabs = NULL, + ...) { + spreadsheet_options <- list( + spreadsheet = TRUE, + spreadsheetRows = spreadsheet_rows, + spreadsheetColumns = spreadsheet_columns, + spreadsheetColumnDefinition = spreadsheet_column_definition, + spreadsheetSheets = spreadsheet_sheets, + spreadsheetSheetTabs = spreadsheet_sheet_tabs, + ... + ) + widget$x$options <- keys_to_camel_case(utils::modifyList( + utils::modifyList(widget$x$options, default_spreadsheet_options), + compact(spreadsheet_options) + )) + return(widget) +} diff --git a/R/tabulator.R b/R/tabulator.R index 98373cc..fd445d9 100644 --- a/R/tabulator.R +++ b/R/tabulator.R @@ -10,7 +10,7 @@ #' @param theme (character): Theme to apply to the table. #' @param width Width of the widget. #' @param height Height of the widget. -#' @param element_id description +#' @param element_id The unique ID of the widget. #' @param ... Named arguments that are appended to the \code{options} parameter. #' @import htmlwidgets #' @export @@ -36,7 +36,7 @@ tabulator <- function( if (isTRUE(options$spreadsheet)) { # ... options <- utils::modifyList(default_spreadsheet_options, options) - } else { + } else if (is.data.frame(data)) { data <- fix_colnames(data) if (getOption("rtabulator.auto_columns", TRUE) && is.null(options$columns)) { options$columns <- create_columns(data, editor = editable) diff --git a/R/tabulator_options.R b/R/tabulator_options.R index 19a9e2c..f38b646 100644 --- a/R/tabulator_options.R +++ b/R/tabulator_options.R @@ -15,17 +15,21 @@ #' @param frozen_rows (numeric): Number of frozen rows. #' @param index (character): Field to be used as the unique index for each row. #' @param group_by (character): Field to group rows by. -#' @param edit_trigger_event description -#' @param selectable_rows description -#' @param pagination (bool): description -#' @param pagination_size (integer): description -#' @param pagination_add_row (character): description -#' @param spreadsheet (bool): description -#' @param spreadsheet_rows (integer): description -#' @param spreadsheet_columns (integer): description -#' @param spreadsheet_column_definition description -#' @param spreadsheet_sheets (list): description -#' @param spreadsheet_sheet_tabs (bool): description +#' @param edit_trigger_event (character): Event that triggers a cell edit. +#' @param selectable_rows (character, bool, integer) Set to \code{FALSE} to disble row selection. +#' If set to \code{TRUE} you can select as many rows as you want. +#' If set to \code{"highlight"} rows are just highlighted but do not change state when clicked. +#' An integer value sets the maximum number of rows that can be selected. +#' @param pagination (bool): Whether to enable pagination. +#' @param pagination_size (integer): Number of rows on each page. +#' @param pagination_size_selector (list): Add pagination size selector. +#' @param pagination_add_row (character): Where to add rows to the table when pagination is enabled. +#' @param spreadsheet (bool): Whether to enable spreadsheet mode. +#' @param spreadsheet_rows (integer): Number of spreadsheet rows. +#' @param spreadsheet_columns (integer): Number of spreadsheet columns. +#' @param spreadsheet_column_definition Column definition used for all columns in the sheet. +#' @param spreadsheet_sheets (list): List of sheet definitions. +#' @param spreadsheet_sheet_tabs (bool): Whether to show sheet tabs in the footer. #' @param ... Further options. #' @seealso \url{https://tabulator.info/docs/6.2/options} #' @export @@ -50,13 +54,14 @@ tabulator_options <- function( # Row Grouping group_by = NULL, # Editing - edit_trigger_event = "dblclick", + edit_trigger_event = c("dblclick", "click", "focus"), # Selection selectable_rows = "highlight", # 'highlight', bool or integer # Pagination pagination = FALSE, pagination_size = 10, - pagination_add_row = "page", + pagination_size_selector = FALSE, + pagination_add_row = c("page", "table"), # Spreadsheet spreadsheet = FALSE, spreadsheet_rows = NULL, @@ -68,6 +73,8 @@ tabulator_options <- function( params <- as.list(environment()) params$layout <- match.arg(layout) params$add_row_pos <- match.arg(add_row_pos) + params$edit_trigger_event <- match.arg(edit_trigger_event) + params$pagination_add_row <- match.arg(pagination_add_row) return(c(params, list(...))) } diff --git a/man/set_formatter_progress.Rd b/man/set_formatter_progress.Rd index c5fd331..646c3e1 100644 --- a/man/set_formatter_progress.Rd +++ b/man/set_formatter_progress.Rd @@ -24,7 +24,8 @@ set_formatter_progress( \item{min}{(numeric): The minimum value for progress bar. If set to \code{NA} the minimum value of the column is used.} -\item{max}{description} +\item{max}{(numeric): The maximum value for progress bar. +If set to \code{NA} the maximum value of the column is used.} \item{color}{(character): Either a single color or a vector of colors} diff --git a/man/set_formatter_traffic_light.Rd b/man/set_formatter_traffic_light.Rd index 6ccec0f..05eb3f2 100644 --- a/man/set_formatter_traffic_light.Rd +++ b/man/set_formatter_traffic_light.Rd @@ -21,7 +21,8 @@ set_formatter_traffic_light( \item{min}{(numeric): The minimum value for progress bar. If set to \code{NA} the minimum value of the column is used.} -\item{max}{description} +\item{max}{(numeric): The maximum value for progress bar. +If set to \code{NA} the maximum value of the column is used.} \item{color}{(character): Either a single color or a vector of colors} diff --git a/man/tabulator.Rd b/man/tabulator.Rd index ecafa2f..8f7de15 100644 --- a/man/tabulator.Rd +++ b/man/tabulator.Rd @@ -34,7 +34,7 @@ which is needed for xlsx downloads.} \item{height}{Height of the widget.} -\item{element_id}{description} +\item{element_id}{The unique ID of the widget.} \item{...}{Named arguments that are appended to the \code{options} parameter.} } diff --git a/man/tabulator_options.Rd b/man/tabulator_options.Rd index 5e843ac..c6f6f31 100644 --- a/man/tabulator_options.Rd +++ b/man/tabulator_options.Rd @@ -19,11 +19,12 @@ tabulator_options( frozen_rows = NULL, index = "id", group_by = NULL, - edit_trigger_event = "dblclick", + edit_trigger_event = c("dblclick", "click", "focus"), selectable_rows = "highlight", pagination = FALSE, pagination_size = 10, - pagination_add_row = "page", + pagination_size_selector = FALSE, + pagination_add_row = c("page", "table"), spreadsheet = FALSE, spreadsheet_rows = NULL, spreadsheet_columns = NULL, @@ -64,27 +65,32 @@ the width of the Tabulator element.} \item{group_by}{(character): Field to group rows by.} -\item{edit_trigger_event}{description} +\item{edit_trigger_event}{(character): Event that triggers a cell edit.} -\item{selectable_rows}{description} +\item{selectable_rows}{(character, bool, integer) Set to \code{FALSE} to disble row selection. +If set to \code{TRUE} you can select as many rows as you want. +If set to \code{"highlight"} rows are just highlighted but do not change state when clicked. +An integer value sets the maximum number of rows that can be selected.} -\item{pagination}{(bool): description} +\item{pagination}{(bool): Whether to enable pagination.} -\item{pagination_size}{(integer): description} +\item{pagination_size}{(integer): Number of rows on each page.} -\item{pagination_add_row}{(character): description} +\item{pagination_size_selector}{(list): Add pagination size selector.} -\item{spreadsheet}{(bool): description} +\item{pagination_add_row}{(character): Where to add rows to the table when pagination is enabled.} -\item{spreadsheet_rows}{(integer): description} +\item{spreadsheet}{(bool): Whether to enable spreadsheet mode.} -\item{spreadsheet_columns}{(integer): description} +\item{spreadsheet_rows}{(integer): Number of spreadsheet rows.} -\item{spreadsheet_column_definition}{description} +\item{spreadsheet_columns}{(integer): Number of spreadsheet columns.} -\item{spreadsheet_sheets}{(list): description} +\item{spreadsheet_column_definition}{Column definition used for all columns in the sheet.} -\item{spreadsheet_sheet_tabs}{(bool): description} +\item{spreadsheet_sheets}{(list): List of sheet definitions.} + +\item{spreadsheet_sheet_tabs}{(bool): Whether to show sheet tabs in the footer.} \item{...}{Further options.} } From da6cad86b633d4a7231c8e5351f9bd0b697a3036 Mon Sep 17 00:00:00 2001 From: Stefan Kuethe Date: Fri, 13 Sep 2024 15:26:04 +0200 Subject: [PATCH 3/4] Update README --- .Rbuildignore | 1 + README.Rmd | 40 ++++++++++++++++++++++++++++++++++++++-- README.md | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 9ef93ec..9d40670 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -9,3 +9,4 @@ _NAMESPACE ^docs$ ^pkgdown$ ^\.github$ +images/ diff --git a/README.Rmd b/README.Rmd index e91a03c..b510347 100644 --- a/README.Rmd +++ b/README.Rmd @@ -22,18 +22,54 @@ knitr::opts_chunk$set( The goal of rtabulator is to make it a breeze creating beautiful and reactive tables using [Tabulator JS](https://tabulator.info/) +## Features + +* Filters +* Grouping +* Multiple column formatters (images, html, progress bar, ...) +* Multiple themes +* Multi column headers +* Spreadsheet mode supporting multiple sheets +* Cell editing supporting validation +* Downloads (json, csv, xlsx) +* Interactivity + ## Installation +Once on CRAN you can install rtabulator with: + +``` r +install.packages("rtabulator") +``` + You can install the development version of rtabulator like so: ``` r remotes::install_github("eodaGmbH/rtabulator") ``` -## Example +## Basic Usage -```r +``` r library(rtabulator) tabulator(mtcars) + +# Set theme +tabulator(iris, theme = "midnight") + +# Format columns +tabulator(airquality) |> + set_formatter_progress( + column = "Temp", + legend = TRUE, + legend_align = "left" + ) + +# Spreadsheet mode +tabulator(data = list(), spreadsheet = TRUE) ``` + +## Documentation + +[rtabulator docs](https://eodagmbh.github.io/rtabulator/) diff --git a/README.md b/README.md index 75ebe48..83395c2 100644 --- a/README.md +++ b/README.md @@ -4,23 +4,61 @@ # rtabulator + +[![R-CMD-check](https://github.com/eodaGmbH/rtabulator/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/eodaGmbH/rtabulator/actions/workflows/R-CMD-check.yaml) The goal of rtabulator is to make it a breeze creating beautiful and reactive tables using [Tabulator JS](https://tabulator.info/) +## Features + +- Filters +- Grouping +- Multiple column formatters (images, html, progress bar, …) +- Multiple themes +- Multi column headers +- Spreadsheet mode supporting multiple sheets +- Cell editing supporting validation +- Downloads (json, csv, xlsx) +- Interactivity + ## Installation +Once on CRAN you can install rtabulator with: + +``` r +install.packages("rtabulator") +``` + You can install the development version of rtabulator like so: ``` r remotes::install_github("eodaGmbH/rtabulator") ``` -## Example +## Basic Usage ``` r library(rtabulator) tabulator(mtcars) + +# Set theme +tabulator(iris, theme = "midnight") + +# Format columns +tabulator(airquality) |> + set_formatter_progress( + column = "Temp", + legend = TRUE, + legend_align = "left" + ) + +# Spreadsheet mode +tabulator(data = list(), spreadsheet = TRUE) ``` + +## Documentation + +[rtabulator docs](https://eodagmbh.github.io/rtabulator/) From 51fbec0a3341b0d53a6d9adc8cd5c0738b911b69 Mon Sep 17 00:00:00 2001 From: Stefan Kuethe Date: Fri, 13 Sep 2024 16:13:41 +0200 Subject: [PATCH 4/4] Update docs --- DESCRIPTION | 8 +++-- NEWS.md | 9 ++++++ R/columns.R | 10 +++--- R/tabulator.R | 1 + R/tabulator_context.R | 3 +- R/tabulator_options.R | 1 + _pkgdown.yml | 36 ++++++++++++++++++++++ examples/formatters/formatter_datetime.R | 2 +- examples/formatters/formatter_html.R | 2 +- examples/formatters/formatter_money.R | 14 ++++----- examples/formatters/formatter_progress.R | 2 +- examples/formatters/formatter_textarea.R | 2 +- examples/formatters/formatter_tick_cross.R | 2 +- examples/multiple_spreadsheets.R | 4 +-- examples/tabulator_setup.R | 9 ++++++ man/create_columns.Rd | 4 +-- man/set_formatter_datetime.Rd | 2 +- man/set_formatter_html.Rd | 2 +- man/set_formatter_money.Rd | 14 ++++----- man/set_formatter_progress.Rd | 2 +- man/set_formatter_textarea.Rd | 2 +- man/set_formatter_tick_cross.Rd | 2 +- man/set_formatter_traffic_light.Rd | 10 ++++++ man/tabulator.Rd | 18 +++++++++++ man/tabulatorContext.Rd | 6 ++-- man/tabulator_options.Rd | 11 +++++++ 26 files changed, 140 insertions(+), 38 deletions(-) create mode 100644 examples/tabulator_setup.R diff --git a/DESCRIPTION b/DESCRIPTION index 02c13a0..958874b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: rtabulator Type: Package Title: R Bindings for Tabulator JS -Version: 0.1.0 -Date: 2024-09-08 +Version: 0.1.1 +Date: 2024-09-13 Authors@R: c( person("Stefan", "Kuethe", email = "crazycapivara@gmail.com", role = c("aut", "cre")), person("Nico", "Friess", email = "nico.friess@eoda.de", role = c("aut")) @@ -10,6 +10,10 @@ Authors@R: c( Maintainer: Stefan Kuethe Description: Provides R bindings for 'Tabulator JS' . Makes it a breeze to create beautiful interactive tables. +URL: + https://github.com/eodaGmbH/rtabulator + https://eodagmbh.github.io/rtabulator/ +BugReports: https://github.com/eodaGmbH/rtabulator/issues License: MIT + file LICENSE Encoding: UTF-8 LazyData: true diff --git a/NEWS.md b/NEWS.md index f7b2329..e67bf6d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# rtabulator 0.1.1 + +* Update docs +* Add pkgdown site +* Add function to create multi column headers +* Add a lot of examples +* Update README +* Make `devtools::check()` pass 🚀 + # rtabulator 0.1.0 * Add NEWS.md to track changes. diff --git a/R/columns.R b/R/columns.R index 14788c3..8dfa8dd 100644 --- a/R/columns.R +++ b/R/columns.R @@ -1,4 +1,4 @@ -#' Create columns definition from data +#' Create column definitions from data #' @param data (data.frame) data #' @param editor (bool): Whether to make columns editable. #' @param filter (bool): Whether to add a header filter to the columns. @@ -313,8 +313,7 @@ set_formatter_datetime <- function( input_format = "yyyy-MM-dd hh:ss:mm", output_format = "yy/MM/dd", invalid_placeholder = "(invalid datetime)", - timezone = NA - ) { + timezone = NA) { # Body col_update <- list( formatter = "datetime", @@ -339,6 +338,7 @@ set_formatter_color <- function(widget, column) { #' Traffic Light Formatter #' @inheritParams set_formatter_progress +#' @example examples/formatters/formatter_traffic_light.R #' @export set_formatter_traffic_light <- function( widget, @@ -348,9 +348,9 @@ set_formatter_traffic_light <- function( color = c("green", "orange", "red"), hoz_align = "center") { # Body - if (is.na(min)) min = min(widget$x$data[column]) + if (is.na(min)) min <- min(widget$x$data[column]) - if (is.na(max)) max = max(widget$x$data[column]) + if (is.na(max)) max <- max(widget$x$data[column]) col_update <- list( formatter = "traffic", diff --git a/R/tabulator.R b/R/tabulator.R index fd445d9..9ef2613 100644 --- a/R/tabulator.R +++ b/R/tabulator.R @@ -12,6 +12,7 @@ #' @param height Height of the widget. #' @param element_id The unique ID of the widget. #' @param ... Named arguments that are appended to the \code{options} parameter. +#' @example examples/multiple_spreadsheets.R #' @import htmlwidgets #' @export tabulator <- function( diff --git a/R/tabulator_context.R b/R/tabulator_context.R index 950c4d3..6fbfd1d 100644 --- a/R/tabulator_context.R +++ b/R/tabulator_context.R @@ -14,7 +14,8 @@ invoke_method <- function(widget, method_name, ...) { invisible(widget) } -#' Create a Tabulator Context +#' Create a Tabulator Context Object +#' A \code{tabulatorContext} object makes it possible to update your widget in a Shiny app. #' @param output_id (character): A tabulator output id. #' @param session shiny session object #' @export diff --git a/R/tabulator_options.R b/R/tabulator_options.R index f38b646..0bb2be7 100644 --- a/R/tabulator_options.R +++ b/R/tabulator_options.R @@ -32,6 +32,7 @@ #' @param spreadsheet_sheet_tabs (bool): Whether to show sheet tabs in the footer. #' @param ... Further options. #' @seealso \url{https://tabulator.info/docs/6.2/options} +#' @example examples/tabulator_setup.R #' @export tabulator_options <- function( # General diff --git a/_pkgdown.yml b/_pkgdown.yml index d71acfb..448e27e 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -2,3 +2,39 @@ url: ~ template: bootstrap: 5 +reference: + - title: Tabulator Widget + desc: > + Functions to create and setup a Tabulator widget + contents: + - tabulator + - tabulator_options + - set_column_editor + - set_header_filter + - set_multi_column_header + + - title: Column Formatters + desc: > + Functions to set column formatters + contents: + - starts_with("set_formatter") + + - title: Shiny Integration + contents: + - rtabulator-shiny + - tabulatorContext + - add_row + - delete_selected_rows + - trigger_download + - trigger_get_data + - trigger_get_spreadsheet_data + - undo + - redo + + - title: Utils + desc: > + Utitily functions + contents: + - list_to_data_frame + - create_columns + diff --git a/examples/formatters/formatter_datetime.R b/examples/formatters/formatter_datetime.R index 43c949d..1ec37e5 100644 --- a/examples/formatters/formatter_datetime.R +++ b/examples/formatters/formatter_datetime.R @@ -1,6 +1,6 @@ data <- data.frame( Person = c("Franz", "Ferdinand"), - Birthday =c( + Birthday = c( "2024-12-06 22:00:10", "2023-06-07 14:12:45" ) diff --git a/examples/formatters/formatter_html.R b/examples/formatters/formatter_html.R index b0b0ea7..7b1ae1f 100644 --- a/examples/formatters/formatter_html.R +++ b/examples/formatters/formatter_html.R @@ -11,5 +11,5 @@ data <- data.frame( ) ) -tabulator(data, width=200) |> +tabulator(data, width = 400) |> set_formatter_html("text_style") diff --git a/examples/formatters/formatter_money.R b/examples/formatters/formatter_money.R index 05c3899..1934129 100644 --- a/examples/formatters/formatter_money.R +++ b/examples/formatters/formatter_money.R @@ -1,14 +1,14 @@ data <- data.frame( - Account_Number= c( - 123456, - 345667, - 234567, - 234566 - ), + Account_Number = c( + 123456, + 345667, + 234567, + 234566 + ), Account_Balance = c(100, -50, 200.30, -21.5) ) -tabulator(data, width = 300) |> +tabulator(data) |> set_formatter_money( "Account_Balance", symbol = "\U20AC", diff --git a/examples/formatters/formatter_progress.R b/examples/formatters/formatter_progress.R index 033f558..2381052 100644 --- a/examples/formatters/formatter_progress.R +++ b/examples/formatters/formatter_progress.R @@ -7,7 +7,7 @@ data <- data.frame( js_func <- htmlwidgets::JS("(cellValue) => `${cellValue}%`") -tabulator(data, width = 300) |> +tabulator(data) |> set_formatter_progress("value") |> set_formatter_progress("value2", legend = TRUE, legend_align = "left") |> set_formatter_progress("value3", legend = js_func, legend_align = "right") diff --git a/examples/formatters/formatter_textarea.R b/examples/formatters/formatter_textarea.R index 24c6cc6..4ccde07 100644 --- a/examples/formatters/formatter_textarea.R +++ b/examples/formatters/formatter_textarea.R @@ -3,7 +3,7 @@ data <- data.frame( txt = c( "This\nis\nsome\ntext\nwith\nmultiple\nline\nbreaks", "- R\n- Python\n- Julia" - ) + ) ) tabulator(data, width = 200) |> diff --git a/examples/formatters/formatter_tick_cross.R b/examples/formatters/formatter_tick_cross.R index 631091b..cdb8fe2 100644 --- a/examples/formatters/formatter_tick_cross.R +++ b/examples/formatters/formatter_tick_cross.R @@ -2,7 +2,7 @@ data <- data.frame( Artist = c("Art Blackey", "Nirvana", "Bob Marley"), Grunge = c(0, 1, 0), Jazz = c(1, 0, 0), - Reggae = c(0,0,1) + Reggae = c(0, 0, 1) ) tabulator(data, width = 400) |> diff --git a/examples/multiple_spreadsheets.R b/examples/multiple_spreadsheets.R index 28a2e1f..109ed3d 100644 --- a/examples/multiple_spreadsheets.R +++ b/examples/multiple_spreadsheets.R @@ -1,4 +1,4 @@ -options <- tabulator_options( +setup <- tabulator_options( spreadsheet = TRUE, spreadsheet_sheets = list( list( @@ -13,4 +13,4 @@ options <- tabulator_options( spreadsheet_sheet_tabs = TRUE ) -tabulator(data = NULL, options, theme = "midnight") +tabulator(data = NULL, setup, theme = "midnight") diff --git a/examples/tabulator_setup.R b/examples/tabulator_setup.R new file mode 100644 index 0000000..fafaa75 --- /dev/null +++ b/examples/tabulator_setup.R @@ -0,0 +1,9 @@ +setup <- tabulator_options( + group_by = "Species", + pagination = TRUE, + pagination_size = 10, + pagination_size_selector = c(10, 20, 50), + movable_columns = TRUE, + movable_rows = TRUE +) +tabulator(iris, setup) diff --git a/man/create_columns.Rd b/man/create_columns.Rd index eedca93..392a5f3 100644 --- a/man/create_columns.Rd +++ b/man/create_columns.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/columns.R \name{create_columns} \alias{create_columns} -\title{Create columns definition from data} +\title{Create column definitions from data} \usage{ create_columns(data, editor = FALSE, filter = FALSE) } @@ -14,5 +14,5 @@ create_columns(data, editor = FALSE, filter = FALSE) \item{filter}{(bool): Whether to add a header filter to the columns.} } \description{ -Create columns definition from data +Create column definitions from data } diff --git a/man/set_formatter_datetime.Rd b/man/set_formatter_datetime.Rd index 22788a7..815b0f1 100644 --- a/man/set_formatter_datetime.Rd +++ b/man/set_formatter_datetime.Rd @@ -32,7 +32,7 @@ Datetime Formatter \examples{ data <- data.frame( Person = c("Franz", "Ferdinand"), - Birthday =c( + Birthday = c( "2024-12-06 22:00:10", "2023-06-07 14:12:45" ) diff --git a/man/set_formatter_html.Rd b/man/set_formatter_html.Rd index 8651797..3dce810 100644 --- a/man/set_formatter_html.Rd +++ b/man/set_formatter_html.Rd @@ -30,6 +30,6 @@ data <- data.frame( ) ) -tabulator(data, width=200) |> +tabulator(data, width = 400) |> set_formatter_html("text_style") } diff --git a/man/set_formatter_money.Rd b/man/set_formatter_money.Rd index 753fe18..fd3e7e6 100644 --- a/man/set_formatter_money.Rd +++ b/man/set_formatter_money.Rd @@ -44,16 +44,16 @@ Money Formatter } \examples{ data <- data.frame( - Account_Number= c( - 123456, - 345667, - 234567, - 234566 - ), + Account_Number = c( + 123456, + 345667, + 234567, + 234566 + ), Account_Balance = c(100, -50, 200.30, -21.5) ) -tabulator(data, width = 300) |> +tabulator(data) |> set_formatter_money( "Account_Balance", symbol = "\U20AC", diff --git a/man/set_formatter_progress.Rd b/man/set_formatter_progress.Rd index 646c3e1..2d9a3cc 100644 --- a/man/set_formatter_progress.Rd +++ b/man/set_formatter_progress.Rd @@ -53,7 +53,7 @@ data <- data.frame( js_func <- htmlwidgets::JS("(cellValue) => `${cellValue}\%`") -tabulator(data, width = 300) |> +tabulator(data) |> set_formatter_progress("value") |> set_formatter_progress("value2", legend = TRUE, legend_align = "left") |> set_formatter_progress("value3", legend = js_func, legend_align = "right") diff --git a/man/set_formatter_textarea.Rd b/man/set_formatter_textarea.Rd index b149e17..7be2634 100644 --- a/man/set_formatter_textarea.Rd +++ b/man/set_formatter_textarea.Rd @@ -22,7 +22,7 @@ data <- data.frame( txt = c( "This\nis\nsome\ntext\nwith\nmultiple\nline\nbreaks", "- R\n- Python\n- Julia" - ) + ) ) tabulator(data, width = 200) |> diff --git a/man/set_formatter_tick_cross.Rd b/man/set_formatter_tick_cross.Rd index fe0f88e..b3ae3ed 100644 --- a/man/set_formatter_tick_cross.Rd +++ b/man/set_formatter_tick_cross.Rd @@ -19,7 +19,7 @@ data <- data.frame( Artist = c("Art Blackey", "Nirvana", "Bob Marley"), Grunge = c(0, 1, 0), Jazz = c(1, 0, 0), - Reggae = c(0,0,1) + Reggae = c(0, 0, 1) ) tabulator(data, width = 400) |> diff --git a/man/set_formatter_traffic_light.Rd b/man/set_formatter_traffic_light.Rd index 05eb3f2..2d0d91d 100644 --- a/man/set_formatter_traffic_light.Rd +++ b/man/set_formatter_traffic_light.Rd @@ -31,3 +31,13 @@ If set to \code{NA} the maximum value of the column is used.} \description{ Traffic Light Formatter } +\examples{ +data <- data.frame( + label = 1:10, + value = 1:10 +) + +tabulator(data, width = 200) |> + set_formatter_traffic_light("value") |> + set_formatter_plaintext("label", hoz_align = "center") +} diff --git a/man/tabulator.Rd b/man/tabulator.Rd index 8f7de15..b065b50 100644 --- a/man/tabulator.Rd +++ b/man/tabulator.Rd @@ -41,3 +41,21 @@ which is needed for xlsx downloads.} \description{ Dots in column names are replaced by underscores. } +\examples{ +setup <- tabulator_options( + spreadsheet = TRUE, + spreadsheet_sheets = list( + list( + title = "First", + data = list(c(1, 2, 3)) + ), + list( + title = "Second", + data = list(c(4, 5, 6)) + ) + ), + spreadsheet_sheet_tabs = TRUE +) + +tabulator(data = NULL, setup, theme = "midnight") +} diff --git a/man/tabulatorContext.Rd b/man/tabulatorContext.Rd index da7355a..ac3ec60 100644 --- a/man/tabulatorContext.Rd +++ b/man/tabulatorContext.Rd @@ -2,7 +2,8 @@ % Please edit documentation in R/tabulator_context.R \name{tabulatorContext} \alias{tabulatorContext} -\title{Create a Tabulator Context} +\title{Create a Tabulator Context Object +A \code{tabulatorContext} object makes it possible to update your widget in a Shiny app.} \usage{ tabulatorContext(output_id, session = shiny::getDefaultReactiveDomain()) } @@ -12,5 +13,6 @@ tabulatorContext(output_id, session = shiny::getDefaultReactiveDomain()) \item{session}{shiny session object} } \description{ -Create a Tabulator Context +Create a Tabulator Context Object +A \code{tabulatorContext} object makes it possible to update your widget in a Shiny app. } diff --git a/man/tabulator_options.Rd b/man/tabulator_options.Rd index c6f6f31..010a369 100644 --- a/man/tabulator_options.Rd +++ b/man/tabulator_options.Rd @@ -97,6 +97,17 @@ An integer value sets the maximum number of rows that can be selected.} \description{ Tabulator Setup Options } +\examples{ +setup <- tabulator_options( + group_by = "Species", + pagination = TRUE, + pagination_size = 10, + pagination_size_selector = c(10, 20, 50), + movable_columns = TRUE, + movable_rows = TRUE +) +tabulator(iris, setup) +} \seealso{ \url{https://tabulator.info/docs/6.2/options} }