diff --git a/.Rbuildignore b/.Rbuildignore index a0e3635f..94927477 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -17,5 +17,3 @@ ^app*$ ^page$ ^demo$ -^\.positai$ -^\.claude$ diff --git a/.gitignore b/.gitignore index 25eb7609..ce227491 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,3 @@ app page demo visuals -.positai diff --git a/R/generate_colors.R b/R/generate_colors.R index 9daec605..d7a7cc82 100644 --- a/R/generate_colors.R +++ b/R/generate_colors.R @@ -56,25 +56,38 @@ #' #' @export generate_colors <- function(n, palette = "viridis", ...) { - - # --- Input validation ------------------------------------------------------- - if (!is.numeric(n) || length(n) != 1 || n < 1 || n %% 1 != 0) { + if (!is.numeric(n) || + length(n) != 1 || n < 1 || n != as.integer(n)) { stop("`n` must be a single positive integer.") } - if (!is.function(palette) && (!is.character(palette) || length(palette) != 1)) { - stop("`palette` must be a single character string or a function.") - } - # --- Function passthrough --------------------------------------------------- + # Function passthrough — call directly with n and ... if (is.function(palette)) { return(palette(n, ...)) } - # --- Named palette dispatch ------------------------------------------------- + if (!is.character(palette) || length(palette) != 1) { + stop("`palette` must be a single character string or a function.") + } + + if (!is.numeric(n) || + length(n) != 1 || n < 1 || n != as.integer(n)) { + stop("`n` must be a single positive integer.") + } + if (!is.character(palette) || length(palette) != 1) { + stop("`palette` must be a single character string.") + } + palette_lower <- tolower(palette) - viridis_palettes <- c("viridis", "magma", "plasma", "inferno", - "cividis", "mako", "rocket", "turbo") + viridis_palettes <- c("viridis", + "magma", + "plasma", + "inferno", + "cividis", + "mako", + "rocket", + "turbo") if (palette_lower %in% viridis_palettes) { viridisLite::viridis(n = n, option = palette_lower, ...) @@ -94,42 +107,35 @@ generate_colors <- function(n, palette = "viridis", ...) { } else if (palette_lower == "topo") { grDevices::topo.colors(n = n, ...) + } else if (palette %in% rownames(RColorBrewer::brewer.pal.info)) { + max_n <- RColorBrewer::brewer.pal.info[palette, "maxcolors"] + fetch_n <- max(min(n, max_n), 3L) # clamp to [3, max_n] for brewer.pal() + base_colors <- RColorBrewer::brewer.pal(n = fetch_n, name = palette) + grDevices::colorRampPalette(base_colors)(n) + + } else if (palette %in% grDevices::palette.pals()) { + grDevices::colorRampPalette(palette.colors(palette = palette))(n) + + } else if (palette %in% grDevices::hcl.pals()) { + grDevices::hcl.colors(n = n, palette = palette, ...) + } else { - # Case-insensitive RColorBrewer lookup - brewer_names <- rownames(RColorBrewer::brewer.pal.info) - brewer_match <- brewer_names[match(palette_lower, tolower(brewer_names))] - - if (!is.na(brewer_match)) { - max_n <- RColorBrewer::brewer.pal.info[brewer_match, "maxcolors"] - fetch_n <- max(min(n, max_n), 3L) - base_colors <- RColorBrewer::brewer.pal(n = fetch_n, name = brewer_match) - grDevices::colorRampPalette(base_colors)(n) - - } else { - # Case-insensitive grDevices palette.pals() lookup - pal_names <- grDevices::palette.pals() - pal_match <- pal_names[match(palette_lower, tolower(pal_names))] - - if (!is.na(pal_match)) { - grDevices::colorRampPalette(grDevices::palette.colors(palette = pal_match))(n) - - } else if (palette %in% grDevices::hcl.pals()) { - # Named HCL palettes (e.g. "Rocket", "Plasma") — distinct from viridisLite - grDevices::hcl.colors(n = n, palette = palette, ...) - - } else { - warning( - "Unknown palette: '", palette, "'. Falling back to viridis.\n", - "Available options:\n", - " viridisLite : viridis, magma, plasma, inferno, cividis, mako, rocket, turbo\n", - " grDevices : hcl, rainbow, heat, terrain, topo\n", - " grDevices HCL: use grDevices::hcl.pals() to see all options\n", - " grDevices : use grDevices::palette.pals() to see all options\n", - " RColorBrewer : use RColorBrewer::brewer.pal.info to see all options" - ) - viridisLite::viridis(n = n, option = "viridis") - } - } + message( + paste0( + "Unknown palette: '", + palette, + "'. ", + "Falling back to default R colors.\n", + "Available options:\n", + " viridisLite : viridis, magma, plasma, inferno, cividis, mako, rocket, turbo\n", + " grDevices : hcl, rainbow, heat, terrain, topo\n", + " grDevices HCL: use grDevices::hcl.pals() to see all options\n", + " grDevices : use grDevices::palette.pals() to see all options\n", + " RColorBrewer : use RColorBrewer::brewer.pal.info to see all options" + ) + ) + viridisLite::viridis(n = n, option = "viridis") + # grDevices::hcl.colors(n = n) } }