diff --git a/R/sanitize.R b/R/sanitize.R index 5d4aa811..0a1522e1 100644 --- a/R/sanitize.R +++ b/R/sanitize.R @@ -6,13 +6,18 @@ sanitize_ribbon.alpha = function(ribbon.alpha) { -sanitize_type = function(type, x, y, dots) { +sanitize_type = function(settings) { + settings_to_environment(settings, environment()) + if (inherits(type, "tinyplot_type")) { - return(type) + settings@type = type$name + settings@type_data = type$data + settings@type_draw = type$draw + return(settings) } known_types = c( - "p", "l", "o", "b", "c", "h", "j", "s", "S", "n", + "p", "l", "o", "b", "c", "h", "j", "s", "S", "n", "abline", "area", "bar", "barplot", @@ -57,57 +62,64 @@ sanitize_type = function(type, x, y, dots) { } } - if (is.character(type)) type = switch(type, - "abline" = type_abline, - "area" = type_area, - "bar" = type_barplot, - "barplot" = type_barplot, - "box" = type_boxplot, - "boxplot" = type_boxplot, - "density" = type_density, - "errorbar" = type_errorbar, - "function" = type_function, - "glm" = type_glm, - "hist" = type_histogram, - "histogram" = type_histogram, - "hline" = type_hline, - "j" = type_jitter, - "jitter" = type_jitter, - "lines" = type_lines, - "lm" = type_lm, - "loess" = type_loess, - "p" = type_points, - "pointrange" = type_pointrange, - "points" = type_points, - "polygon" = type_polygon, - "polypath" = type_polypath, - "qq" = type_qq, - "rect" = type_rect, - "ribbon" = type_ribbon, - "ridge" = type_ridge, - "rug" = type_rug, - "segments" = type_segments, - "spine" = type_spineplot, - "spineplot" = type_spineplot, - "spline" = type_spline, - "summary" = type_summary, - "text" = type_text, - "violin" = type_violin, - "vline" = type_vline, - type # default case - ) - + if (is.character(type)) { + type = switch(type, + "abline" = type_abline, + "area" = type_area, + "bar" = type_barplot, + "barplot" = type_barplot, + "box" = type_boxplot, + "boxplot" = type_boxplot, + "density" = type_density, + "errorbar" = type_errorbar, + "function" = type_function, + "glm" = type_glm, + "hist" = type_histogram, + "histogram" = type_histogram, + "hline" = type_hline, + "j" = type_jitter, + "jitter" = type_jitter, + "lines" = type_lines, + "lm" = type_lm, + "loess" = type_loess, + "p" = type_points, + "pointrange" = type_pointrange, + "points" = type_points, + "polygon" = type_polygon, + "polypath" = type_polypath, + "qq" = type_qq, + "rect" = type_rect, + "ribbon" = type_ribbon, + "ridge" = type_ridge, + "rug" = type_rug, + "segments" = type_segments, + "spine" = type_spineplot, + "spineplot" = type_spineplot, + "spline" = type_spline, + "summary" = type_summary, + "text" = type_text, + "violin" = type_violin, + "vline" = type_vline, + type # default case + ) + } + if (is.function(type)) { args = intersect(names(formals(type)), names(dots)) args = if (length(args) >= 1L) dots[args] else list() type = do.call(type, args) type$dots = dots[setdiff(names(dots), names(args))] } - - if (inherits(type, "tinyplot_type")) return(type) - out = list(draw = NULL, data = NULL, name = type) - return(out) + if (inherits(type, "tinyplot_type")) { + settings@type = type$name + settings@type_data = type$data + settings@type_draw = type$draw + settings@dots = dots + return(settings) + } + + return(settings) } diff --git a/R/settings.R b/R/settings.R new file mode 100644 index 00000000..41d3a8e5 --- /dev/null +++ b/R/settings.R @@ -0,0 +1,43 @@ +#' tinyplot_settings S4 class +#' @keywords internal +setClass("tinyplot_settings", + slots = list( + type = "ANY", + x = "ANY", + y = "ANY", + dots = "ANY", + type_data = "ANY", + type_draw = "ANY" + ) +) + + +#' Initialize settings object +#' @keywords internal +setMethod("initialize", "tinyplot_settings", function(.Object, ...) { + # Get all arguments passed to new() + args = list(...) + + # Set only the slots needed for sanitize_type() + .Object@type = args$type + .Object@x = args$x + .Object@y = args$y + .Object@dots = args$dots + + # Initialize output slots with default values + .Object@type_data = NULL + .Object@type_draw = NULL + + return(.Object) +}) + + +#' Assign settings slots to environment +#' @keywords internal +settings_to_environment = function(settings, environment) { + slot_names = slotNames(settings) + for (slot_name in slot_names) { + assign(slot_name, slot(settings, slot_name), envir = environment) + } + invisible(NULL) +} diff --git a/R/tinyplot.R b/R/tinyplot.R index 83a6dc31..e5627217 100644 --- a/R/tinyplot.R +++ b/R/tinyplot.R @@ -699,6 +699,14 @@ tinyplot.default = function( facet_dep = deparse1(substitute(facet)) + # + ## initialize settings object ----- + # + + settings = new("tinyplot_settings", + type = type, x = x, y = y, dots = list(...)) + + # ## sanitize arguments ----- # @@ -716,11 +724,11 @@ tinyplot.default = function( # type # sanitize_type: validates/converts type argument and returns list with name, data, and draw components - type = sanitize_type(type, x, y, dots) - if ("dots" %in% names(type)) dots = type$dots - type_data = type$data - type_draw = type$draw - type = type$name + settings = sanitize_type(settings) + + + # TODO: remove this when we can only operate on the settings object + settings_to_environment(settings, environment()) # area flag (mostly for legend) was_area_type = identical(type, "area")