@@ -269,8 +269,6 @@ verify_attr_names <- function(p) {
269
269
c(names(attrSpec ), " key" , " set" , " frame" , " _isNestedKey" , " _isSimpleKey" ),
270
270
thisTrace $ type
271
271
)
272
- # if it makes sense, reduce a single-valued vector to a constant
273
- p $ x $ data [[tr ]] <- attrs_simplify(thisTrace , attrSpec )
274
272
}
275
273
invisible (p )
276
274
}
@@ -287,21 +285,11 @@ attrs_name_check <- function(proposedAttrs, validAttrs, type = "scatter") {
287
285
invisible (proposedAttrs )
288
286
}
289
287
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 ) {
302
290
if (! is.null(p $ x $ layout )) {
303
291
layoutNames <- names(p $ x $ layout )
304
- layoutNew <- verify_box (
292
+ layoutNew <- verify_attr (
305
293
setNames(p $ x $ layout , sub(" [0-9]+$" , " " , layoutNames )),
306
294
Schema $ layout $ layoutAttributes
307
295
)
@@ -310,41 +298,47 @@ verify_boxed <- function(p) {
310
298
for (tr in seq_along(p $ x $ data )) {
311
299
thisTrace <- p $ x $ data [[tr ]]
312
300
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 )
314
302
# prevent these objects from sending null keys
315
303
p $ x $ data [[tr ]][[" xaxis" ]] <- p $ x $ data [[tr ]][[" xaxis" ]] %|| % NULL
316
304
p $ x $ data [[tr ]][[" yaxis" ]] <- p $ x $ data [[tr ]][[" yaxis" ]] %|| % NULL
317
305
}
318
- p $ x $ layout $ updatemenus
319
306
320
307
p
321
308
}
322
309
323
- verify_box <- function (proposed , schema ) {
310
+ verify_attr <- function (proposed , schema ) {
324
311
for (attr in names(proposed )) {
325
- attrVal <- proposed [[attr ]]
326
312
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 ]])
337
318
}
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
+ )
347
340
}
341
+ # we don't have to go more than two-levels, right?
348
342
}
349
343
}
350
344
}
0 commit comments