From 896998074e3974a3c4dbc43782337f47240ba765 Mon Sep 17 00:00:00 2001 From: pvictor Date: Wed, 22 Feb 2023 10:45:29 +0100 Subject: [PATCH] added support for boxplot in apex() --- NAMESPACE | 1 + R/apex-options.R | 53 +++++++++++++++++++++++++++++++-------- R/apex-utils.R | 12 +++++---- R/apex.R | 25 +++++++++++++++--- R/parse-data.R | 26 +++++++++++++++++++ man/ax_plotOptions.Rd | 13 ++++++---- man/bar_opts.Rd | 4 +-- man/boxplot_opts.Rd | 31 +++++++++++++++++++++++ man/bubble_opts.Rd | 4 +-- man/heatmap_opts.Rd | 4 +-- man/pie_opts.Rd | 4 +-- man/radialBar_opts.Rd | 4 +-- vignettes/apexcharter.Rmd | 12 +++++++++ 13 files changed, 160 insertions(+), 33 deletions(-) create mode 100644 man/boxplot_opts.Rd diff --git a/NAMESPACE b/NAMESPACE index 694a955..e1ee0d8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -52,6 +52,7 @@ export(ax_xaxis) export(ax_yaxis) export(ax_yaxis2) export(bar_opts) +export(boxplot_opts) export(bubble_opts) export(config_update) export(events_opts) diff --git a/R/apex-options.R b/R/apex-options.R index 9ab3e1a..f35e486 100644 --- a/R/apex-options.R +++ b/R/apex-options.R @@ -115,7 +115,7 @@ events_opts <- function(click = NULL, #' @title Bar options #' -#' @description Use these options in \code{\link{ax_plotOptions}}. +#' @description Use these options in [ax_plotOptions()]. #' #' @param horizontal Logical. This option will turn a column chart into a horizontal bar chart. #' @param endingShape Available Options: \code{"flat"} or \code{"rounded"}. @@ -128,7 +128,7 @@ events_opts <- function(click = NULL, #' #' @note See \url{https://apexcharts.com/docs/options/plotoptions/bar/}. #' -#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +#' @return A \code{list} of options that can be used in [ax_plotOptions()]. #' #' @export #' @@ -170,7 +170,7 @@ bar_opts <- function(horizontal = NULL, #' @title Heatmap options #' -#' @description Use these options in \code{\link{ax_plotOptions}}. +#' @description Use these options in [ax_plotOptions()]. #' #' @param radius Numeric. Radius of the rectangle inside heatmap. #' @param enableShades Logical. Enable different shades of color depending on the value @@ -180,7 +180,7 @@ bar_opts <- function(horizontal = NULL, #' #' @note See \url{https://apexcharts.com/docs/options/plotoptions/heatmap/}. #' -#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +#' @return A \code{list} of options that can be used in [ax_plotOptions()]. #' #' @export #' @@ -228,7 +228,7 @@ heatmap_opts <- function(radius = NULL, #' @title Radial bar options #' -#' @description Use these options in \code{\link{ax_plotOptions}}. +#' @description Use these options in [ax_plotOptions()]. #' #' @param size Numeric. Manual size of the radialBars instead of calculating automatically from default height / width. #' @param inverseOrder Logical. Whether to make the first value of series innermost or outermost. @@ -243,7 +243,7 @@ heatmap_opts <- function(radius = NULL, #' #' @note See \url{https://apexcharts.com/docs/options/plotoptions/radialbar/}. #' -#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +#' @return A \code{list} of options that can be used in [ax_plotOptions()]. #' #' @export #' @@ -301,7 +301,7 @@ radialBar_opts <- function(size = NULL, #' @title Pie options #' -#' @description Use these options in \code{\link{ax_plotOptions}}. +#' @description Use these options in [ax_plotOptions()]. #' #' @param size Numeric. Custom size of the pie which will override the default size calculations. #' @param donut List with two fields \code{size} (Donut / ring size in percentage relative to the total pie area.) @@ -314,7 +314,7 @@ radialBar_opts <- function(size = NULL, #' #' @note See \url{https://apexcharts.com/docs/options/plotoptions/pie/}. #' -#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +#' @return A \code{list} of options that can be used in [ax_plotOptions()]. #' #' @export #' @@ -351,7 +351,7 @@ pie_opts <- function(size = NULL, #' @title Bubble options #' -#' @description Use these options in \code{\link{ax_plotOptions}}. +#' @description Use these options in [ax_plotOptions()]. #' #' @param minBubbleRadius Minimum radius size of a bubble. #' If a bubble value is too small to be displayed, this size will be used. @@ -361,7 +361,7 @@ pie_opts <- function(size = NULL, #' #' @note See \url{https://apexcharts.com/docs/options/plotoptions/bubble/}. #' -#' @return A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +#' @return A \code{list} of options that can be used in [ax_plotOptions()]. #' @export #' #' @examples @@ -386,3 +386,36 @@ bubble_opts <- function(minBubbleRadius, maxBubbleRadius, ...) { ) } + + + +#' @title Boxplot options +#' +#' @description Use these options in [ax_plotOptions()]. +#' +#' @param color.upper Color for the upper quartile (Q3 to median) of the box plot. +#' @param color.lower Color for the lower quartile (median to Q1) of the box plot. +#' @param ... Additional parameters. +#' +#' @note See \url{https://apexcharts.com/docs/options/plotoptions/boxplot/}. +#' +#' @return A \code{list} of options that can be used in [ax_plotOptions()]. +#' @export +#' +#' @examples +#' data("mpg", package = "ggplot2") +#' apex(mpg, aes(class, hwy), "boxplot") %>% +#' ax_plotOptions( +#' boxPlot = boxplot_opts(color.upper = "#848484", color.lower = "#848484" ) +#' ) +boxplot_opts <- function(color.upper, color.lower, ...) { + dropNulls( + list( + colors = dropNulls(list( + upper = color.upper, + lower = color.lower + )), + ... + ) + ) +} diff --git a/R/apex-utils.R b/R/apex-utils.R index 0516d97..8785d6e 100644 --- a/R/apex-utils.R +++ b/R/apex-utils.R @@ -185,11 +185,12 @@ ax_chart <- function(ax, #' Specific options for chart #' #' @template ax-default -#' @param bar See \code{\link{bar_opts}}. -#' @param heatmap See \code{\link{heatmap_opts}}. -#' @param radialBar See \code{\link{radialBar_opts}}. -#' @param pie See \code{\link{pie_opts}}. -#' @param bubble See \code{\link{bubble_opts}}. +#' @param bar See [bar_opts()]. +#' @param heatmap See [heatmap_opts()]. +#' @param radialBar See [radialBar_opts()]. +#' @param pie See [pie_opts()]. +#' @param bubble See [bubble_opts()]. +#' @param boxPlot See [boxplot_opts()]. #' @param ... Additional parameters. #' #' @@ -234,6 +235,7 @@ ax_plotOptions <- function(ax, radialBar = NULL, pie = NULL, bubble = NULL, + boxPlot = NULL, ...) { params <- c(as.list(environment()), list(...))[-1] .ax_opt2(ax, "plotOptions", l = dropNulls(params)) diff --git a/R/apex.R b/R/apex.R index 5b7474d..0529646 100644 --- a/R/apex.R +++ b/R/apex.R @@ -54,7 +54,8 @@ apex <- function(data, mapping, "heatmap", "treemap", "timeline", - "candlestick" + "candlestick", + "boxplot" ) ) data <- as.data.frame(data) @@ -67,7 +68,7 @@ apex <- function(data, mapping, type <- "bubble" } mapdata <- lapply(mapping, rlang::eval_tidy, data = data) - if (is.null(mapdata$y) & !type %in% c("candlestick", "timeline", "heatmap", "rangeArea")) { + if (is.null(mapdata$y) & !type %in% c("candlestick", "boxplot", "timeline", "heatmap", "rangeArea")) { mapdata <- compute_count(mapdata) } if (type %in% c("pie", "donut", "radialBar", "polarArea")) { @@ -118,7 +119,9 @@ apex <- function(data, mapping, # Construct series #' @importFrom rlang %||% make_series <- function(mapdata, mapping, type = NULL, serie_name = NULL, force_datetime_names = FALSE) { - if (identical(type, "candlestick")) { + if (identical(type, "boxplot")) { + series <- parse_boxplot_data(mapdata, serie_name = serie_name) + } else if (identical(type, "candlestick")) { if (!all(c("x", "open", "high", "low", "close") %in% names(mapping))) stop("For candlestick charts 'x', 'open', 'high', 'low', and 'close' aesthetics must be provided.", call. = FALSE) if (!is.null(mapdata$group)) @@ -250,6 +253,8 @@ correct_type <- function(type) { "area" } else if (identical(type, "timeline")) { "rangeBar" + } else if (identical(type, "boxplot")) { + "boxPlot" } else { type } @@ -308,6 +313,9 @@ choose_config <- function(type, mapdata) { datetime <- is_x_datetime(mapdata) range_x <- range_num(mapdata$x) range_y <- range_num(mapdata$y) + if (identical(type, "boxplot")) { + box_horiz <- !is.numeric(mapdata$y) & is.numeric(mapdata$x) + } switch( type, "bar" = config_bar(horizontal = TRUE), @@ -323,6 +331,7 @@ choose_config <- function(type, mapdata) { "bubble" = config_scatter(range_x = range_x, range_y = range_y, datetime = datetime), "timeline" = config_timeline(), "candlestick" = config_candlestick(), + "boxplot" = config_boxplot(horizontal = box_horiz), list() ) } @@ -436,3 +445,13 @@ config_candlestick <- function() { ) } +config_boxplot <- function(horizontal = FALSE) { + list( + plotOptions = list( + bar = list( + horizontal = horizontal + ) + ) + ) +} + diff --git a/R/parse-data.R b/R/parse-data.R index 4b71751..67c5d79 100644 --- a/R/parse-data.R +++ b/R/parse-data.R @@ -127,3 +127,29 @@ parse_candlestick_data <- function(.list) { )) } + +parse_boxplot_data <- function(.list, serie_name = NULL) { + if (!is.numeric(.list$y) & is.numeric(.list$x)) { + .list[c("x", "y")] <- .list[c("y", "x")] + } + boxed <- boxplot(y ~ x, data = .list, plot = FALSE) + list(dropNulls(list( + serie_name = serie_name, + type = "boxPlot", + data = lapply( + X = seq_along(boxed$names), + FUN = function(i) { + list( + x = boxed$names[i], + y = c( + boxed$stats[1, i], + boxed$stats[2, i], + boxed$stats[3, i], + boxed$stats[4, i], + boxed$stats[5, i] + ) + ) + } + ) + ))) +} diff --git a/man/ax_plotOptions.Rd b/man/ax_plotOptions.Rd index cf5f843..81fe330 100644 --- a/man/ax_plotOptions.Rd +++ b/man/ax_plotOptions.Rd @@ -11,21 +11,24 @@ ax_plotOptions( radialBar = NULL, pie = NULL, bubble = NULL, + boxPlot = NULL, ... ) } \arguments{ \item{ax}{An \code{\link[=apexchart]{apexchart()}} \code{htmlwidget} object.} -\item{bar}{See \code{\link{bar_opts}}.} +\item{bar}{See \code{\link[=bar_opts]{bar_opts()}}.} -\item{heatmap}{See \code{\link{heatmap_opts}}.} +\item{heatmap}{See \code{\link[=heatmap_opts]{heatmap_opts()}}.} -\item{radialBar}{See \code{\link{radialBar_opts}}.} +\item{radialBar}{See \code{\link[=radialBar_opts]{radialBar_opts()}}.} -\item{pie}{See \code{\link{pie_opts}}.} +\item{pie}{See \code{\link[=pie_opts]{pie_opts()}}.} -\item{bubble}{See \code{\link{bubble_opts}}.} +\item{bubble}{See \code{\link[=bubble_opts]{bubble_opts()}}.} + +\item{boxPlot}{See \code{\link[=boxplot_opts]{boxplot_opts()}}.} \item{...}{Additional parameters.} } diff --git a/man/bar_opts.Rd b/man/bar_opts.Rd index fd636bc..18839d1 100644 --- a/man/bar_opts.Rd +++ b/man/bar_opts.Rd @@ -33,10 +33,10 @@ bar_opts( \item{...}{Additional parameters.} } \value{ -A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +A \code{list} of options that can be used in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \description{ -Use these options in \code{\link{ax_plotOptions}}. +Use these options in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \note{ See \url{https://apexcharts.com/docs/options/plotoptions/bar/}. diff --git a/man/boxplot_opts.Rd b/man/boxplot_opts.Rd new file mode 100644 index 0000000..762adb0 --- /dev/null +++ b/man/boxplot_opts.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/apex-options.R +\name{boxplot_opts} +\alias{boxplot_opts} +\title{Boxplot options} +\usage{ +boxplot_opts(color.upper, color.lower, ...) +} +\arguments{ +\item{color.upper}{Color for the upper quartile (Q3 to median) of the box plot.} + +\item{color.lower}{Color for the lower quartile (median to Q1) of the box plot.} + +\item{...}{Additional parameters.} +} +\value{ +A \code{list} of options that can be used in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. +} +\description{ +Use these options in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. +} +\note{ +See \url{https://apexcharts.com/docs/options/plotoptions/boxplot/}. +} +\examples{ +data("mpg", package = "ggplot2") +apex(mpg, aes(class, hwy), "boxplot") \%>\% + ax_plotOptions( + boxPlot = boxplot_opts(color.upper = "#848484", color.lower = "#848484" ) + ) +} diff --git a/man/bubble_opts.Rd b/man/bubble_opts.Rd index aaaac3d..54613c8 100644 --- a/man/bubble_opts.Rd +++ b/man/bubble_opts.Rd @@ -16,10 +16,10 @@ If a bubble value is too large to cover the chart, this size will be used.} \item{...}{Additional parameters.} } \value{ -A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +A \code{list} of options that can be used in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \description{ -Use these options in \code{\link{ax_plotOptions}}. +Use these options in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \note{ See \url{https://apexcharts.com/docs/options/plotoptions/bubble/}. diff --git a/man/heatmap_opts.Rd b/man/heatmap_opts.Rd index 538356b..b686e65 100644 --- a/man/heatmap_opts.Rd +++ b/man/heatmap_opts.Rd @@ -24,10 +24,10 @@ heatmap_opts( \item{...}{Additional parameters.} } \value{ -A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +A \code{list} of options that can be used in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \description{ -Use these options in \code{\link{ax_plotOptions}}. +Use these options in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \note{ See \url{https://apexcharts.com/docs/options/plotoptions/heatmap/}. diff --git a/man/pie_opts.Rd b/man/pie_opts.Rd index b66539d..65142b9 100644 --- a/man/pie_opts.Rd +++ b/man/pie_opts.Rd @@ -31,10 +31,10 @@ and \code{background} (The background color of the pie).} \item{...}{Additional parameters.} } \value{ -A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +A \code{list} of options that can be used in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \description{ -Use these options in \code{\link{ax_plotOptions}}. +Use these options in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \note{ See \url{https://apexcharts.com/docs/options/plotoptions/pie/}. diff --git a/man/radialBar_opts.Rd b/man/radialBar_opts.Rd index e4d7d63..0c14548 100644 --- a/man/radialBar_opts.Rd +++ b/man/radialBar_opts.Rd @@ -39,10 +39,10 @@ radialBar_opts( \item{...}{Additional parameters.} } \value{ -A \code{list} of options that can be used in \code{\link{ax_plotOptions}}. +A \code{list} of options that can be used in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \description{ -Use these options in \code{\link{ax_plotOptions}}. +Use these options in \code{\link[=ax_plotOptions]{ax_plotOptions()}}. } \note{ See \url{https://apexcharts.com/docs/options/plotoptions/radialbar/}. diff --git a/vignettes/apexcharter.Rmd b/vignettes/apexcharter.Rmd index f1d1cba..3ed893a 100644 --- a/vignettes/apexcharter.Rmd +++ b/vignettes/apexcharter.Rmd @@ -244,4 +244,16 @@ apex( +## Boxplot + +Create boxplot (without outliers for now) with: + +```{r boxplot} +data("mpg", package = "ggplot2") +apex(mpg, aes(hwy, class), "boxplot") %>% + ax_plotOptions( + boxPlot = boxplot_opts(color.upper = "#8BB0A6", color.lower = "#8BB0A6" ) + ) %>% + ax_stroke(colors = list("#2A5769")) +```