2019-02-14 15:50:58 +01:00
|
|
|
|
2020-10-05 09:44:14 +02:00
|
|
|
#' @title Quick ApexCharts
|
2019-07-24 12:20:22 +02:00
|
|
|
#'
|
2020-02-12 11:57:24 +01:00
|
|
|
#' @description Initialize a chart with three main parameters :
|
|
|
|
#' data, mapping and type of chart.
|
2019-02-14 15:50:58 +01:00
|
|
|
#'
|
2020-02-12 11:57:24 +01:00
|
|
|
#' @param data Default dataset to use for chart. If not already
|
|
|
|
#' a \code{data.frame}, it will be coerced to with \code{as.data.frame}.
|
2019-02-14 15:50:58 +01:00
|
|
|
#' @param mapping Default list of aesthetic mappings to use for chart
|
2020-03-04 21:51:40 +01:00
|
|
|
#' @param type Specify the chart type. Available options:
|
2020-04-17 20:21:57 +02:00
|
|
|
#' \code{"column"}, \code{"bar"},
|
|
|
|
#' \code{"line"}, \code{"step"}, \code{"spline"},
|
|
|
|
#' \code{"area"}, \code{"area-step"}, \code{"area-spline"},
|
|
|
|
#' \code{"pie"}, \code{"donut"},
|
2020-10-06 09:50:27 +02:00
|
|
|
#' \code{"radialBar"}, \code{"radar"}, \code{"scatter"},
|
|
|
|
#' \code{"heatmap"}, \code{"treemap"},
|
2020-02-12 16:37:47 +01:00
|
|
|
#' \code{"timeline"}.
|
2019-02-14 15:50:58 +01:00
|
|
|
#' @param ... Other arguments passed on to methods. Not currently used.
|
2020-02-12 11:57:24 +01:00
|
|
|
#' @param auto_update In Shiny application, update existing chart
|
2020-02-12 18:21:40 +01:00
|
|
|
#' rather than generating new one. Can be \code{TRUE}/\code{FALSE} or
|
|
|
|
#' use \code{\link{config_update}} for more control.
|
2020-04-15 19:32:15 +02:00
|
|
|
#' @param synchronize Give a common id to charts to synchronize them (tooltip and zoom).
|
2020-02-12 16:37:47 +01:00
|
|
|
#' @param serie_name Name for the serie displayed in tooltip,
|
|
|
|
#' only used for single serie.
|
2019-02-14 15:50:58 +01:00
|
|
|
#' @param width A numeric input in pixels.
|
|
|
|
#' @param height A numeric input in pixels.
|
|
|
|
#' @param elementId Use an explicit element ID for the widget.
|
2019-07-24 12:20:22 +02:00
|
|
|
#'
|
|
|
|
#' @return A \code{apexcharts} \code{htmlwidget} object.
|
2019-02-14 15:50:58 +01:00
|
|
|
#'
|
|
|
|
#' @export
|
|
|
|
#'
|
2019-02-18 20:29:34 +01:00
|
|
|
#' @importFrom rlang eval_tidy as_label
|
2019-02-14 15:50:58 +01:00
|
|
|
#' @importFrom utils modifyList
|
2020-08-11 09:41:53 +02:00
|
|
|
#' @importFrom stats complete.cases
|
2019-02-14 15:50:58 +01:00
|
|
|
#'
|
2019-11-26 11:26:47 +01:00
|
|
|
#' @example examples/apex.R
|
2020-02-12 11:57:24 +01:00
|
|
|
apex <- function(data, mapping, type = "column", ...,
|
2020-02-12 18:21:40 +01:00
|
|
|
auto_update = TRUE,
|
2020-04-15 19:32:15 +02:00
|
|
|
synchronize = NULL,
|
2020-02-12 16:37:47 +01:00
|
|
|
serie_name = NULL,
|
2020-04-16 16:42:34 +02:00
|
|
|
width = NULL,
|
|
|
|
height = NULL,
|
|
|
|
elementId = NULL) {
|
2020-02-12 16:37:47 +01:00
|
|
|
type <- match.arg(
|
|
|
|
arg = type,
|
|
|
|
choices = c(
|
2020-08-11 09:41:53 +02:00
|
|
|
"column", "bar",
|
|
|
|
"line", "spline", "step",
|
|
|
|
"area", "area-spline", "area-step",
|
|
|
|
"pie", "donut",
|
|
|
|
"radialBar",
|
|
|
|
"radar",
|
2020-10-06 09:50:27 +02:00
|
|
|
"polarArea",
|
2020-08-11 09:41:53 +02:00
|
|
|
"scatter", "bubble",
|
|
|
|
"heatmap",
|
2020-09-28 16:42:42 +02:00
|
|
|
"treemap",
|
2020-08-11 09:41:53 +02:00
|
|
|
"timeline",
|
|
|
|
"candlestick"
|
2020-02-12 16:37:47 +01:00
|
|
|
)
|
|
|
|
)
|
2019-02-14 15:50:58 +01:00
|
|
|
data <- as.data.frame(data)
|
2019-07-19 14:11:41 +02:00
|
|
|
if (identical(type, "heatmap")) {
|
|
|
|
mapping <- rename_aes_heatmap(mapping)
|
|
|
|
}
|
2020-02-23 16:56:35 +01:00
|
|
|
if (identical(type, "scatter") & is_sized(mapping)) {
|
|
|
|
type <- "bubble"
|
|
|
|
}
|
2019-02-14 16:37:40 +01:00
|
|
|
mapdata <- lapply(mapping, rlang::eval_tidy, data = data)
|
2020-10-06 09:50:27 +02:00
|
|
|
if (type %in% c("pie", "donut", "radialBar", "polarArea")) {
|
2019-02-14 18:33:28 +01:00
|
|
|
opts <- list(
|
|
|
|
chart = list(type = correct_type(type)),
|
|
|
|
series = list1(mapdata$y),
|
|
|
|
labels = list1(mapdata$x)
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
opts <- list(
|
2020-04-15 19:32:15 +02:00
|
|
|
chart = dropNulls(list(
|
|
|
|
type = correct_type(type),
|
|
|
|
group = synchronize
|
|
|
|
)),
|
2020-02-12 16:37:47 +01:00
|
|
|
series = make_series(mapdata, mapping, type, serie_name)
|
2019-02-14 18:33:28 +01:00
|
|
|
)
|
|
|
|
}
|
2020-04-15 19:32:15 +02:00
|
|
|
if (!is.null(synchronize)) {
|
|
|
|
opts$yaxis$labels$minWidth <- 15
|
|
|
|
}
|
2019-03-13 09:21:03 +01:00
|
|
|
opts <- modifyList(opts, choose_config(type, mapdata))
|
2020-04-29 11:35:06 +02:00
|
|
|
if (isTRUE(getOption("apex.axis.light", default = TRUE))) {
|
|
|
|
opts$yaxis$labels$style$colors <- "#848484"
|
|
|
|
opts$xaxis$labels$style$colors <- "#848484"
|
|
|
|
}
|
2020-04-02 19:33:39 +02:00
|
|
|
ax <- apexchart(
|
2020-02-12 11:57:24 +01:00
|
|
|
ax_opts = opts,
|
2020-04-17 20:21:57 +02:00
|
|
|
width = width,
|
|
|
|
height = height,
|
2020-02-12 11:57:24 +01:00
|
|
|
elementId = elementId,
|
2020-02-12 18:21:40 +01:00
|
|
|
auto_update = auto_update
|
2019-02-15 23:33:40 +01:00
|
|
|
)
|
2020-05-27 11:42:42 +02:00
|
|
|
if (inherits(mapdata$x, c("character", "Date", "POSIXt", "numeric", "integer")) & length(mapdata$x) > 0) {
|
2020-04-02 19:33:39 +02:00
|
|
|
ax$x$xaxis <- list(
|
|
|
|
min = min(mapdata$x, na.rm = TRUE),
|
|
|
|
max = max(mapdata$x, na.rm = TRUE)
|
|
|
|
)
|
|
|
|
}
|
2020-07-26 10:46:18 +02:00
|
|
|
ax$x$data <- data
|
2020-07-26 18:38:18 +02:00
|
|
|
ax$x$mapping <- mapping
|
2020-12-02 15:50:03 +01:00
|
|
|
ax$x$type <- type
|
|
|
|
ax$x$serie_name <- serie_name
|
2020-07-26 10:46:18 +02:00
|
|
|
class(ax) <- c(class(ax), "apex")
|
2020-04-02 19:33:39 +02:00
|
|
|
return(ax)
|
2019-02-14 15:50:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Construct series
|
2020-02-12 16:37:47 +01:00
|
|
|
make_series <- function(mapdata, mapping, type = NULL, serie_name = NULL) {
|
2020-06-13 12:18:02 +02:00
|
|
|
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))
|
|
|
|
warning("'group' aesthetic in candlestick chart is not supported", call. = FALSE)
|
|
|
|
mapdata$group <- NULL
|
|
|
|
series <- parse_candlestick_data(mapdata)
|
|
|
|
} else if (identical(type, "rangeBar")) {
|
2020-02-12 16:37:47 +01:00
|
|
|
if (!all(c("x", "start", "end") %in% names(mapping)))
|
2020-06-13 12:18:02 +02:00
|
|
|
stop("For timeline charts 'x', 'start', and 'end' aesthetics must be provided.", call. = FALSE)
|
2020-02-12 16:37:47 +01:00
|
|
|
if (is.null(mapdata$group))
|
|
|
|
mapdata$group <- serie_name %||% rlang::as_label(mapping$x)
|
|
|
|
series <- parse_timeline_data(mapdata)
|
2019-05-20 15:47:01 +02:00
|
|
|
} else {
|
2020-03-03 19:34:33 +01:00
|
|
|
mapdata <- as.data.frame(mapdata, stringsAsFactors = FALSE)
|
2020-08-11 09:41:53 +02:00
|
|
|
if (isTRUE(type %in% c("scatter", "bubble"))) {
|
|
|
|
complete <- complete.cases(mapdata[c("x", "y")])
|
|
|
|
n_missing <- sum(!complete)
|
|
|
|
if (n_missing > 0) {
|
|
|
|
mapdata <- mapdata[complete, ]
|
|
|
|
warning(sprintf("apex: Removed %s rows containing missing values", n_missing), call. = FALSE)
|
|
|
|
}
|
|
|
|
}
|
2020-03-03 19:34:33 +01:00
|
|
|
if (is.character(mapdata$x))
|
|
|
|
mapdata$x[is.na(mapdata$x)] <- "NA"
|
2020-02-12 16:37:47 +01:00
|
|
|
x_order <- unique(mapdata$x)
|
|
|
|
if (is_x_datetime(mapdata)) {
|
|
|
|
add_names <- FALSE
|
2020-06-09 17:03:35 +02:00
|
|
|
x_order <- sort(x_order)
|
2020-02-12 16:37:47 +01:00
|
|
|
} else {
|
|
|
|
add_names <- names(mapping)
|
2020-01-14 11:09:24 +01:00
|
|
|
}
|
2020-02-12 16:37:47 +01:00
|
|
|
if (is.null(serie_name) & !is.null(mapping$y))
|
|
|
|
serie_name <- rlang::as_label(mapping$y)
|
2020-04-29 11:35:06 +02:00
|
|
|
series <- list(dropNulls(list(
|
2020-02-12 16:37:47 +01:00
|
|
|
name = serie_name,
|
2020-04-29 11:35:06 +02:00
|
|
|
type = multi_type(type),
|
2020-02-12 16:37:47 +01:00
|
|
|
data = parse_df(mapdata, add_names = add_names)
|
2020-04-29 11:35:06 +02:00
|
|
|
)))
|
2020-02-23 16:56:35 +01:00
|
|
|
if (is_grouped(mapping)) {
|
2020-02-12 16:37:47 +01:00
|
|
|
mapdata <- rename_aes(mapdata)
|
|
|
|
len_grp <- tapply(mapdata$group, mapdata$group, length)
|
2020-04-29 11:35:06 +02:00
|
|
|
if (length(unique(len_grp)) > 1 & !isTRUE(type %in% c("scatter", "bubble"))) {
|
2020-03-03 19:34:33 +01:00
|
|
|
warning("apex: all groups must have same length! You can use `tidyr::complete` for this.")
|
2019-02-14 15:50:58 +01:00
|
|
|
}
|
2020-02-12 16:37:47 +01:00
|
|
|
series <- lapply(
|
|
|
|
X = unique(mapdata$group),
|
|
|
|
FUN = function(x) {
|
|
|
|
data <- mapdata[mapdata$group %in% x, ]
|
|
|
|
data <- data[, setdiff(names(data), "group"), drop = FALSE]
|
2020-11-02 11:31:48 +01:00
|
|
|
data <- data[order(match(x = data[["x"]], table = x_order, nomatch = 0L)), , drop = FALSE]
|
2020-04-29 11:35:06 +02:00
|
|
|
dropNulls(list(
|
2020-02-12 16:37:47 +01:00
|
|
|
name = x,
|
2020-04-29 11:35:06 +02:00
|
|
|
type = multi_type(type),
|
2020-02-12 16:37:47 +01:00
|
|
|
data = parse_df(
|
|
|
|
data = data,
|
|
|
|
add_names = add_names
|
|
|
|
)
|
2020-04-29 11:35:06 +02:00
|
|
|
))
|
2020-02-12 16:37:47 +01:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
2019-02-14 15:50:58 +01:00
|
|
|
}
|
|
|
|
series
|
|
|
|
}
|
|
|
|
|
2019-02-18 20:29:34 +01:00
|
|
|
is_grouped <- function(x) {
|
2020-02-23 16:56:35 +01:00
|
|
|
any(c("colour", "fill", "group") %in% names(x))
|
|
|
|
}
|
|
|
|
|
|
|
|
is_sized <- function(x) {
|
|
|
|
any(c("size", "z") %in% names(x))
|
2019-02-18 20:29:34 +01:00
|
|
|
}
|
|
|
|
|
2020-02-23 16:56:35 +01:00
|
|
|
|
2019-07-19 14:11:41 +02:00
|
|
|
rename_aes_heatmap <- function(mapping) {
|
|
|
|
n_mapping <- names(mapping)
|
|
|
|
n_mapping[n_mapping == "y"] <- "group"
|
|
|
|
if ("fill" %in% n_mapping) {
|
|
|
|
n_mapping[n_mapping == "fill"] <- "y"
|
|
|
|
}
|
|
|
|
if ("colour" %in% n_mapping) {
|
|
|
|
n_mapping[n_mapping == "colour"] <- "y"
|
|
|
|
}
|
|
|
|
names(mapping) <- n_mapping
|
|
|
|
return(mapping)
|
|
|
|
}
|
|
|
|
|
2019-02-18 20:29:34 +01:00
|
|
|
rename_aes <- function(mapping) {
|
|
|
|
if ("colour" %in% names(mapping)) {
|
|
|
|
names(mapping)[names(mapping) == "colour"] <- "group"
|
|
|
|
}
|
|
|
|
if ("fill" %in% names(mapping)) {
|
|
|
|
names(mapping)[names(mapping) == "fill"] <- "group"
|
|
|
|
}
|
2020-02-23 16:56:35 +01:00
|
|
|
if ("size" %in% names(mapping)) {
|
|
|
|
names(mapping)[names(mapping) == "size"] <- "z"
|
|
|
|
}
|
2019-02-18 20:29:34 +01:00
|
|
|
mapping
|
|
|
|
}
|
2019-02-14 15:50:58 +01:00
|
|
|
|
2019-02-16 19:14:54 +01:00
|
|
|
is_x_datetime <- function(mapdata) {
|
2019-02-14 16:37:40 +01:00
|
|
|
inherits(mapdata$x, what = c("Date", "POSIXt"))
|
|
|
|
}
|
2019-02-14 18:33:28 +01:00
|
|
|
list1 <- function(x) {
|
|
|
|
if (length(x) == 1) {
|
|
|
|
list(x)
|
|
|
|
} else {
|
|
|
|
x
|
|
|
|
}
|
|
|
|
}
|
2019-02-14 15:50:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
# Change type of charts for helpers type
|
|
|
|
correct_type <- function(type) {
|
|
|
|
if (identical(type, "column")) {
|
|
|
|
"bar"
|
2020-04-17 20:21:57 +02:00
|
|
|
} else if (isTRUE(type %in% c("spline", "step"))) {
|
2019-02-14 16:37:40 +01:00
|
|
|
"line"
|
2020-04-17 20:21:57 +02:00
|
|
|
} else if (isTRUE(type %in% c("area-spline", "area-step"))) {
|
|
|
|
"area"
|
2020-02-12 16:37:47 +01:00
|
|
|
} else if (identical(type, "timeline")) {
|
|
|
|
"rangeBar"
|
2019-02-14 15:50:58 +01:00
|
|
|
} else {
|
|
|
|
type
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-29 11:35:06 +02:00
|
|
|
multi_type <- function(x) {
|
|
|
|
multis <- c("column", "area", "line",
|
|
|
|
"spline", "step", "scatter",
|
|
|
|
"bubble")
|
|
|
|
if (isTRUE(x %in% multis)) {
|
2020-04-29 18:24:39 +02:00
|
|
|
correct_type(x)
|
2020-04-29 11:35:06 +02:00
|
|
|
} else {
|
|
|
|
NULL
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-13 09:21:03 +01:00
|
|
|
range_num <- function(x) {
|
2020-05-27 11:42:42 +02:00
|
|
|
if (is.numeric(x) & length(x) > 0) {
|
2019-03-13 09:21:03 +01:00
|
|
|
range(pretty(x))
|
|
|
|
} else {
|
|
|
|
NULL
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-14 15:50:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Switch between auto configs according to type & mapping
|
2019-03-13 09:21:03 +01:00
|
|
|
choose_config <- function(type, mapdata) {
|
|
|
|
datetime <- is_x_datetime(mapdata)
|
|
|
|
range_x <- range_num(mapdata$x)
|
|
|
|
range_y <- range_num(mapdata$y)
|
2019-02-14 15:50:58 +01:00
|
|
|
switch(
|
|
|
|
type,
|
|
|
|
"bar" = config_bar(horizontal = TRUE),
|
2020-04-17 08:57:23 +02:00
|
|
|
"column" = config_bar(horizontal = FALSE, datetime = datetime),
|
2019-02-14 16:37:40 +01:00
|
|
|
"line" = config_line(datetime = datetime),
|
|
|
|
"area" = config_line(datetime = datetime),
|
|
|
|
"spline" = config_line(curve = "smooth", datetime = datetime),
|
2020-04-17 20:21:57 +02:00
|
|
|
"step" = config_line(curve = "stepline", datetime = datetime),
|
|
|
|
"area-spline" = config_line(curve = "smooth", datetime = datetime),
|
|
|
|
"area-step" = config_line(curve = "stepline", datetime = datetime),
|
2020-04-17 08:57:23 +02:00
|
|
|
"scatter" = config_scatter(range_x = range_x, range_y = range_y, datetime = datetime),
|
|
|
|
"bubble" = config_scatter(range_x = range_x, range_y = range_y, datetime = datetime),
|
2020-02-12 16:37:47 +01:00
|
|
|
"timeline" = config_timeline(),
|
2020-06-13 12:18:02 +02:00
|
|
|
"candlestick" = config_candlestick(),
|
2019-02-14 15:50:58 +01:00
|
|
|
list()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Config for column & bar charts
|
2020-04-17 08:57:23 +02:00
|
|
|
config_bar <- function(horizontal = FALSE, datetime = FALSE) {
|
2019-02-14 15:50:58 +01:00
|
|
|
config <- list(
|
2019-03-13 09:21:03 +01:00
|
|
|
dataLabels = list(enabled = FALSE),
|
2019-02-14 15:50:58 +01:00
|
|
|
plotOptions = list(
|
|
|
|
bar = list(
|
|
|
|
horizontal = horizontal
|
|
|
|
)
|
2020-04-17 08:57:23 +02:00
|
|
|
),
|
|
|
|
tooltip = list(
|
2020-04-17 16:46:34 +02:00
|
|
|
shared = TRUE,
|
|
|
|
followCursor = TRUE
|
2019-02-14 15:50:58 +01:00
|
|
|
)
|
|
|
|
)
|
|
|
|
if (isTRUE(horizontal)) {
|
|
|
|
config <- c(config, list(
|
|
|
|
grid = list(
|
|
|
|
yaxis = list(lines = list(show = FALSE)),
|
|
|
|
xaxis = list(lines = list(show = TRUE))
|
|
|
|
)
|
|
|
|
))
|
|
|
|
}
|
2020-04-17 08:57:23 +02:00
|
|
|
if (isTRUE(datetime)) {
|
|
|
|
config$xaxis$type <- "datetime"
|
|
|
|
}
|
2019-02-14 15:50:58 +01:00
|
|
|
config
|
|
|
|
}
|
2019-02-14 16:37:40 +01:00
|
|
|
|
|
|
|
# Config for line, spline, area, area-spline
|
|
|
|
config_line <- function(curve = "straight", datetime = FALSE) {
|
|
|
|
config <- list(
|
2019-03-13 09:21:03 +01:00
|
|
|
dataLabels = list(enabled = FALSE),
|
2019-02-14 16:37:40 +01:00
|
|
|
stroke = list(
|
2020-03-03 19:34:33 +01:00
|
|
|
curve = curve,
|
|
|
|
width = 2
|
2020-04-29 18:24:39 +02:00
|
|
|
),
|
|
|
|
yaxis = list(
|
|
|
|
decimalsInFloat = 2
|
2019-02-14 16:37:40 +01:00
|
|
|
)
|
|
|
|
)
|
|
|
|
if (isTRUE(datetime)) {
|
|
|
|
config <- c(config, list(
|
|
|
|
xaxis = list(type = "datetime")
|
|
|
|
))
|
|
|
|
}
|
|
|
|
config
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-04-17 08:57:23 +02:00
|
|
|
config_scatter <- function(range_x, range_y, datetime = FALSE) {
|
2019-03-13 09:21:03 +01:00
|
|
|
config <- list(
|
2020-02-23 16:56:35 +01:00
|
|
|
dataLabels = list(enabled = FALSE),
|
2019-03-13 09:21:03 +01:00
|
|
|
xaxis = list(
|
2020-01-27 18:20:54 +01:00
|
|
|
type = "numeric",
|
2020-05-27 11:42:42 +02:00
|
|
|
min = range_x[1],
|
|
|
|
max = range_x[2],
|
2020-04-17 08:57:23 +02:00
|
|
|
crosshairs = list(
|
|
|
|
show = TRUE,
|
|
|
|
stroke = list(dashArray = 0)
|
|
|
|
)
|
2019-03-13 09:21:03 +01:00
|
|
|
),
|
|
|
|
yaxis = list(
|
2020-05-27 11:42:42 +02:00
|
|
|
min = range_y[1],
|
|
|
|
max = range_y[2],
|
2020-04-17 08:57:23 +02:00
|
|
|
decimalsInFloat = 3,
|
|
|
|
tooltip = list(
|
|
|
|
enabled = TRUE
|
|
|
|
)
|
2020-03-04 21:51:40 +01:00
|
|
|
),
|
|
|
|
grid = list(
|
|
|
|
xaxis = list(
|
|
|
|
lines = list(
|
|
|
|
show = TRUE
|
|
|
|
)
|
|
|
|
)
|
2019-03-13 09:21:03 +01:00
|
|
|
)
|
|
|
|
)
|
2020-04-17 08:57:23 +02:00
|
|
|
if (isTRUE(datetime)) {
|
|
|
|
config$xaxis$type <- "datetime"
|
|
|
|
}
|
|
|
|
config
|
2019-03-13 09:21:03 +01:00
|
|
|
}
|
|
|
|
|
2020-02-12 16:37:47 +01:00
|
|
|
config_timeline <- function() {
|
|
|
|
list(
|
|
|
|
plotOptions = list(
|
|
|
|
bar = list(
|
|
|
|
horizontal = TRUE
|
|
|
|
)
|
|
|
|
),
|
|
|
|
xaxis = list(
|
|
|
|
type = "datetime"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2019-03-13 09:21:03 +01:00
|
|
|
|
2020-06-13 12:18:02 +02:00
|
|
|
config_candlestick <- function() {
|
|
|
|
list(
|
|
|
|
xaxis = list(
|
|
|
|
type = "datetime"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|