Skip to content

Commit 0806f6e

Browse files
committed
array -> constant simplication should apply to attribute objects (e.g., line.width) as well
1 parent d62d8ea commit 0806f6e

File tree

3 files changed

+34
-40
lines changed

3 files changed

+34
-40
lines changed

R/plotly_build.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ plotly_build.plotly <- function(p, registerFrames = TRUE) {
354354
# verify plot attributes are legal according to the plotly.js spec
355355
p <- verify_attr_names(p)
356356
# box up 'data_array' attributes where appropriate
357-
p <- verify_boxed(p)
357+
p <- verify_attr_spec(p)
358358

359359
# make sure plots don't get sent out of the network (for enterprise)
360360
p$x$base_url <- get_domain()

R/process.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ process.plotly_figure <- function(resp) {
3131
fig$url <- sub("apigetfile/", "~", resp$url)
3232
# make sure that we always return a HTTPS link
3333
con$url <- sub("^http[s]?:", "https:", con$url)
34-
fig <- verify_boxed(fig)
34+
fig <- verify_attr_spec(fig)
3535
as_widget(fig)
3636
}
3737

R/utils.R

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,6 @@ verify_attr_names <- function(p) {
269269
c(names(attrSpec), "key", "set", "frame", "_isNestedKey", "_isSimpleKey"),
270270
thisTrace$type
271271
)
272-
# if it makes sense, reduce a single-valued vector to a constant
273-
p$x$data[[tr]] <- attrs_simplify(thisTrace, attrSpec)
274272
}
275273
invisible(p)
276274
}
@@ -287,21 +285,11 @@ attrs_name_check <- function(proposedAttrs, validAttrs, type = "scatter") {
287285
invisible(proposedAttrs)
288286
}
289287

290-
attrs_simplify <- function(trace, spec) {
291-
for (attr in names(trace)) {
292-
type <- tryCatch(spec[[attr]]$valType, error = function(e) NULL)
293-
if (isTRUE(type %in% c("any", "data_array"))) next
294-
trace[[attr]] <- uniq(trace[[attr]])
295-
}
296-
trace
297-
}
298-
299-
# ensure both the layout and trace attributes are sent to plotly.js
300-
# as data_arrays
301-
verify_boxed <- function(p) {
288+
# ensure both the layout and trace attributes adhere to the plot schema
289+
verify_attr_spec <- function(p) {
302290
if (!is.null(p$x$layout)) {
303291
layoutNames <- names(p$x$layout)
304-
layoutNew <- verify_box(
292+
layoutNew <- verify_attr(
305293
setNames(p$x$layout, sub("[0-9]+$", "", layoutNames)),
306294
Schema$layout$layoutAttributes
307295
)
@@ -310,41 +298,47 @@ verify_boxed <- function(p) {
310298
for (tr in seq_along(p$x$data)) {
311299
thisTrace <- p$x$data[[tr]]
312300
validAttrs <- Schema$traces[[thisTrace$type %||% "scatter"]]$attributes
313-
p$x$data[[tr]] <- verify_box(thisTrace, validAttrs)
301+
p$x$data[[tr]] <- verify_attr(thisTrace, validAttrs)
314302
# prevent these objects from sending null keys
315303
p$x$data[[tr]][["xaxis"]] <- p$x$data[[tr]][["xaxis"]] %||% NULL
316304
p$x$data[[tr]][["yaxis"]] <- p$x$data[[tr]][["yaxis"]] %||% NULL
317305
}
318-
p$x$layout$updatemenus
319306

320307
p
321308
}
322309

323-
verify_box <- function(proposed, schema) {
310+
verify_attr <- function(proposed, schema) {
324311
for (attr in names(proposed)) {
325-
attrVal <- proposed[[attr]]
326312
attrSchema <- schema[[attr]]
327-
isArray <- tryCatch(
328-
identical(attrSchema[["valType"]], "data_array"),
329-
error = function(e) FALSE
330-
)
331-
isObject <- tryCatch(
332-
identical(attrSchema[["role"]], "object"),
333-
error = function(e) FALSE
334-
)
335-
if (isArray) {
336-
proposed[[attr]] <- i(attrVal)
313+
valType <- tryNULL(attrSchema[["valType"]]) %||% ""
314+
role <- tryNULL(attrSchema[["role"]]) %||% ""
315+
# ensure data_arrays of length 1 are boxed up by to_JSON()
316+
if (identical(valType, "data_array")) {
317+
proposed[[attr]] <- i(proposed[[attr]])
337318
}
338-
# we don't have to go more than two-levels, right?
339-
if (isObject) {
340-
for (attr2 in names(attrVal)) {
341-
isArray2 <- tryCatch(
342-
identical(attrSchema[[attr2]][["valType"]], "data_array"),
343-
error = function(e) FALSE
344-
)
345-
if (isArray2) {
346-
proposed[[attr]][[attr2]] <- i(attrVal[[attr2]])
319+
# where applicable, reduce single valued vectors to a constant
320+
# (while preserving any 'special' attribute class)
321+
if (!valType %in% c("data_array", "any") && !identical(role, "object")) {
322+
proposed[[attr]] <- structure(
323+
uniq(proposed[[attr]]), class = oldClass(proposed[[attr]])
324+
)
325+
}
326+
# do the same for "sub-attributes"
327+
if (identical(role, "object")) {
328+
for (attr2 in names(proposed[[attr]])) {
329+
valType2 <- tryNULL(attrSchema[[attr2]][["valType"]]) %||% ""
330+
role2 <- tryNULL(attrSchema[[attr2]][["role"]]) %||% ""
331+
# ensure data_arrays of length 1 are boxed up by to_JSON()
332+
if (identical(valType2, "data_array")) {
333+
proposed[[attr]][[attr2]] <- i(proposed[[attr]][[attr2]])
334+
}
335+
# where applicable, reduce single valued vectors to a constant
336+
if (!valType2 %in% c("data_array", "any", "color") && !identical(role2, "object")) {
337+
proposed[[attr]][[attr2]] <- structure(
338+
uniq(proposed[[attr]][[attr2]]), class = oldClass(proposed[[attr]][[attr2]])
339+
)
347340
}
341+
# we don't have to go more than two-levels, right?
348342
}
349343
}
350344
}

0 commit comments

Comments
 (0)