|
37 | 37 | #' # similar to plotly.js, you can update a particular attribute like so
|
38 | 38 | #' # https://github.com/plotly/plotly.js/issues/1866#issuecomment-314115744
|
39 | 39 | #' style(p, marker.line.color = "blue")
|
| 40 | +#' # this clobbers the previously supplied marker.line.color |
| 41 | +#' style(p, marker.line = list(width = 2.5), marker.size = 10) |
40 | 42 | #'
|
41 | 43 | style <- function(p, ..., traces = NULL) {
|
42 | 44 | p <- plotly_build(p)
|
43 |
| - nTraces <- length(p$x$data) |
44 |
| - traces <- traces %||% seq_len(nTraces) |
45 |
| - idx <- traces > nTraces |
46 |
| - traces <- traces[!idx] |
47 |
| - if (any(idx)) warning("You've referenced non-existent traces", call. = FALSE) |
48 |
| - argz <- list(...) |
49 |
| - |
50 |
| - # argument names that contain a '.' signify a "partial update" |
51 |
| - isPartialUpdate <- grepl("\\.", names(argz)) |
52 |
| - # expand these special arguments to a suitable list object, |
53 |
| - # `list(marker.color = "red")`, to `list(marker = list(color = "red"))` |
54 |
| - nms <- strsplit(names(argz), "\\.") |
55 |
| - for (i in seq_along(nms)) { |
56 |
| - nm <- nms[[i]] |
57 |
| - if (length(nm) == 1) next |
58 |
| - val <- argz[[i]] |
59 |
| - for (j in seq(length(nm), 2)) { |
60 |
| - val <- setNames(list(val), nm[j]) |
61 |
| - } |
62 |
| - argz[[i]] <- val |
| 45 | + n_traces <- length(p$x$data) |
| 46 | + trace_idx <- traces %||% seq_len(n_traces) |
| 47 | + if (any(trace_idx > n_traces)) { |
| 48 | + warning("You've referenced non-existent traces", call. = FALSE) |
63 | 49 | }
|
64 |
| - argz <- setNames(argz, unlist(lapply(nms, `[[`, 1))) |
65 | 50 |
|
66 |
| - # perform the replacement |
67 |
| - for (i in traces) { |
68 |
| - for (j in seq_along(argz)) { |
69 |
| - attr <- names(argz)[j] |
70 |
| - p$x$data[[i]][[attr]] <- if (isPartialUpdate[j]) modify_list(p$x$data[[i]][[attr]], argz[[attr]]) else argz[[attr]] |
| 51 | + values <- list(...) |
| 52 | + paths <- strsplit(names(values), "\\.") |
| 53 | + |
| 54 | + p$x$data[trace_idx] <- lapply(p$x$data[trace_idx], function(trace) { |
| 55 | + for (i in seq_along(paths)) { |
| 56 | + trace <- trace_replace(trace, paths[[i]], values[[i]]) |
71 | 57 | }
|
72 |
| - } |
| 58 | + trace |
| 59 | + }) |
73 | 60 |
|
74 | 61 | p
|
75 | 62 | }
|
| 63 | + |
| 64 | +#' @param path character vector of path elements: c("marker", "line", "size") |
| 65 | + if (length(path) == 0) return(trace) |
| 66 | + if (length(path == 1)) { |
| 67 | + trace[[path]] <- value |
| 68 | + return(trace) |
| 69 | + } |
| 70 | + trace_replace(trace[[path[1]]], path[-1], value) |
| 71 | +} |
0 commit comments