Skip to content

Commit 9c28ad6

Browse files
committed
Merge branch 'master' into v1.42.2
2 parents eaad8ca + 3908841 commit 9c28ad6

21 files changed

+279
-62
lines changed

NEWS.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@
1212
* The `style()` function now supports "partial updates" (i.e. modification of a particular property of an object, rather than the entire object). For example, notice how the first plot retains the original marker shape (a square): `p <- plot_ly(x = 1:10, y = 1:10, symbol = I(15)); subplot(style(p, marker.color = "red"), style(p, marker = list(color = "red")))` (#1342).
1313
* **plotly** objects can now be serialized and unserialized in different environments (i.e., you can now use `saveRDS()` to save an object as an rds file and restore it on another machine with `readRDS()`). Note this object is *dynamically* linked to JavaScript libraries, so one should take care to use consistent versions of **plotly** when serializing and unserializing (#1376).
1414
* The `plotly_example()` will now attempt to open the source file(s) used to run the example. Set `edit = FALSE` to prevent the source file(s) from opening.
15+
* The `event_data()` function now relays the (official plotly.js) `customdata` attribute in similar fashion to (unofficial) `key` attribute (#1423).
16+
1517

1618
## CHANGES
1719

1820
* The 'collaborate' button no longer appears in the modebar, and as a result, the `config()` function no longer has a `collaborate` argument.
1921

2022
## BUG FIXES
2123

22-
* `subplot()` now bumps annotation `xref`/`yref` anchors correctly (#1181).
23-
* `subplot()` now accumulates images, repositions paper coordinates, and reanchors axis references (#1332).
24+
* `subplot()` now works much better with annotations, images, and shapes:
25+
- When `xref`/`yref` references an x/y axis these references are bumped accordingly (#1181).
26+
- When `xref`/`yref` references paper coordinates, these coordinates are updated accordingly (#1332).
2427
* `event_data("plotly_selected")` is no longer too eager to clear. That is, it is no longer set to `NULL` when clicking on a plot *after* triggering the "plotly_selected" event (#1121) (#1122).
2528
* The colorscale generated via the `color` argument in `plot_ly()` now uses an evenly spaced grid of values instead of quantiles (#1308).
2629
* When using **shinytest** to test a **shiny** that contains **plotly** graph, false positive differences are no longer reported (rstudio/shinytest#174).
@@ -31,6 +34,7 @@
3134
* An articial marker no longer appears when clearing a crosstalk selection of a plot with a colorbar (#1406).
3235
* Clearing a highlight event via crosstalk no longer deletes all the traces added since initial draw (#1436).
3336
* Recursive attribute validation is now only performed on recursive objects (#1315).
37+
* The `text` attribute is no longer collapsed to a string when `hoveron='fills+points'` (#1448).
3438

3539
# 4.8.0
3640

R/layers2traces.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ geom2trace.GeomPath <- function(data, params, p) {
637637
y = data[["y"]],
638638
text = uniq(data[["hovertext"]]),
639639
key = data[["key"]],
640+
customdata = data[["customdata"]],
640641
frame = data[["frame"]],
641642
ids = data[["ids"]],
642643
type = "scatter",
@@ -667,6 +668,7 @@ geom2trace.GeomPoint <- function(data, params, p) {
667668
y = data[["y"]],
668669
text = if (isDotPlot) data[["key"]] else uniq(data[["hovertext"]]),
669670
key = data[["key"]],
671+
customdata = data[["customdata"]],
670672
frame = data[["frame"]],
671673
ids = data[["ids"]],
672674
type = "scatter",
@@ -720,6 +722,7 @@ geom2trace.GeomBar <- function(data, params, p) {
720722
y = y,
721723
text = uniq(data[["hovertext"]]),
722724
key = data[["key"]],
725+
customdata = data[["customdata"]],
723726
frame = data[["frame"]],
724727
ids = data[["ids"]],
725728
type = "bar",
@@ -747,6 +750,7 @@ geom2trace.GeomPolygon <- function(data, params, p) {
747750
y = data[["y"]],
748751
text = uniq(data[["hovertext"]]),
749752
key = data[["key"]],
753+
customdata = data[["customdata"]],
750754
frame = data[["frame"]],
751755
ids = data[["ids"]],
752756
type = "scatter",
@@ -778,6 +782,7 @@ geom2trace.GeomBoxplot <- function(data, params, p) {
778782
y = data[["y"]],
779783
hoverinfo = "y",
780784
key = data[["key"]],
785+
customdata = data[["customdata"]],
781786
frame = data[["frame"]],
782787
ids = data[["ids"]],
783788
type = "box",
@@ -812,6 +817,7 @@ geom2trace.GeomText <- function(data, params, p) {
812817
text = data[["label"]],
813818
hovertext = data[["hovertext"]],
814819
key = data[["key"]],
820+
customdata = data[["customdata"]],
815821
frame = data[["frame"]],
816822
ids = data[["ids"]],
817823
textfont = list(
@@ -850,6 +856,7 @@ geom2trace.GeomTile <- function(data, params, p) {
850856
z = matrix(g$fill_plotlyDomain, nrow = length(y), ncol = length(x), byrow = TRUE),
851857
text = matrix(g$hovertext, nrow = length(y), ncol = length(x), byrow = TRUE),
852858
key = data[["key"]],
859+
customdata = data[["customdata"]],
853860
frame = data[["frame"]],
854861
ids = data[["ids"]],
855862
colorscale = setNames(colScale, NULL),
@@ -945,6 +952,7 @@ make_error <- function(data, params, xy = "x") {
945952
y = data[["y"]],
946953
text = uniq(data[["hovertext"]]),
947954
key = data[["key"]],
955+
customdata = data[["customdata"]],
948956
frame = data[["frame"]],
949957
ids = data[["ids"]],
950958
type = "scatter",

R/plotly_build.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ plotly_build.plotly <- function(p, registerFrames = TRUE) {
190190
tr <- trace[names(trace) %in% allAttrs]
191191
# TODO: does it make sense to "train" matrices/2D-tables (e.g. z)?
192192
tr <- tr[vapply(tr, function(x) is.null(dim(x)) && is.atomic(x), logical(1))]
193+
# white-list customdata as this can be a non-atomic vector
194+
tr$customdata <- trace$customdata
193195
builtData <- tibble::as_tibble(tr)
194196
# avoid clobbering I() (i.e., variables that shouldn't be scaled)
195197
for (i in seq_along(tr)) {
@@ -266,7 +268,7 @@ plotly_build.plotly <- function(p, registerFrames = TRUE) {
266268

267269
# insert NAs to differentiate groups
268270
traces <- lapply(traces, function(x) {
269-
d <- data.frame(x[names(x) %in% x$.plotlyVariableMapping], stringsAsFactors = FALSE)
271+
d <- tibble::as_tibble(x[names(x) %in% x$.plotlyVariableMapping])
270272
d <- group2NA(
271273
d, if (has_group(x)) ".plotlyGroupIndex",
272274
ordered = if (inherits(x, "plotly_line")) "x",

R/subplots.R

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,30 +207,31 @@ subplot <- function(..., nrows = 1, widths = NULL, heights = NULL, margin = 0.02
207207
map <- xMap[xMap %in% sub("x", "xaxis", yAxes[[i]][[j]]$anchor %||% "x")]
208208
yAxes[[i]][[j]]$anchor <- sub("axis", "", names(map))
209209
}
210-
# map trace xaxis/yaxis/geo attributes
210+
211211
for (key in c("geo", "subplot", "xaxis", "yaxis")) {
212+
# bump trace axis references
212213
oldAnchors <- unlist(lapply(traces[[i]], "[[", key))
213214
if (!length(oldAnchors)) next
214215
axisMap <- if (key == "yaxis") yMap else xMap
215216
axisMap <- setNames(sub("axis", "", axisMap), sub("axis", "", names(axisMap)))
216217
newAnchors <- names(axisMap)[match(oldAnchors, axisMap)]
217218
traces[[i]] <- Map(function(tr, a) { tr[[key]] <- a; tr }, traces[[i]], newAnchors)
218-
# also map annotation and image xaxis/yaxis references
219-
# TODO: do this for shapes as well?
219+
220+
# bump annotation, image, shape xref/yref
221+
# (none of these layout components have geo/subplot support)
220222
ref <- list(xaxis = "xref", yaxis = "yref")[[key]]
221223
if (is.null(ref)) next
222-
if (length(annotations[[i]])) {
223-
annotations[[i]] <- Map(function(x, y) {
224-
if (!identical(x[[ref]], "paper")) x[[ref]] <- y
225-
x
226-
}, annotations[[i]], newAnchors)
227-
}
228-
if (length(images[[i]])) {
229-
images[[i]] <- Map(function(x, y) {
230-
if (!identical(x[[ref]], "paper")) x[[ref]] <- y
231-
x
232-
}, images[[i]], newAnchors)
224+
bump_axis_ref <- function(obj, ref_default = sub("ref", "", ref)) {
225+
# TODO: throw error/warning if ref_default doesn't match axisMap?
226+
obj[[ref]] <- obj[[ref]] %||% ref_default
227+
if (identical(obj[[ref]], "paper")) return(obj)
228+
refIdx <- match(obj[[ref]], axisMap)
229+
if (!is.na(refIdx)) obj[[ref]] <- names(axisMap)[refIdx][1]
230+
obj
233231
}
232+
annotations[[i]] <- lapply(annotations[[i]], bump_axis_ref)
233+
shapes[[i]] <- lapply(shapes[[i]], bump_axis_ref)
234+
images[[i]] <- lapply(images[[i]], bump_axis_ref, "paper")
234235
}
235236

236237

R/utils.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,9 @@ verify_attr <- function(proposed, schema) {
476476
proposed[[attr]] <- retain(proposed[[attr]], uniq)
477477
}
478478

479-
# plotly.js should really handle this logic
480-
if (isTRUE(grepl("fill", proposed[["hoveron"]]))) {
479+
# If we deliberately only want hover on fills, send a string to
480+
# plotly.js so it does something sensible
481+
if (identical(proposed[["hoveron"]], "fills")) {
481482
proposed[["text"]] <- paste(uniq(proposed[["text"]]), collapse = "\n")
482483
}
483484

demo/ternary.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ plot_ly(
5151

5252
plot_ly(
5353
df, a = ~clay, b = ~sand, c = ~silt, color = ~id, type = "scatterternary",
54-
fill = "toself", mode = "lines",
54+
fill = "toself", mode = "lines"
5555
) %>%
5656
layout(
5757
annotations = label("Ternary Contour"), ternary = ternaryAxes

inst/examples/shiny/event_data/app.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ server <- function(input, output, session) {
1515

1616
output$plot <- renderPlotly({
1717
if (identical(input$plotType, "ggplotly")) {
18-
p <- ggplot(mtcars, aes(x = mpg, y = wt, key = nms)) + geom_point()
18+
p <- ggplot(mtcars, aes(x = mpg, y = wt, customdata = nms)) + geom_point()
1919
ggplotly(p) %>% layout(dragmode = "select")
2020
} else {
21-
plot_ly(mtcars, x = ~mpg, y = ~wt, key = nms) %>%
21+
plot_ly(mtcars, x = ~mpg, y = ~wt, customdata = nms) %>%
2222
layout(dragmode = "select")
2323
}
2424
})

inst/htmlwidgets/plotly.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ HTMLWidgets.widget({
236236
obj.z = pt.z;
237237
}
238238

239+
if (pt.hasOwnProperty("customdata")) {
240+
obj.customdata = pt.customdata;
241+
}
242+
239243
/*
240244
TL;DR: (I think) we have to select the graph div (again) to attach keys...
241245

tests/figs/subplot/plotly-subplot-ggmatrix.svg

Lines changed: 1 addition & 1 deletion
Loading

tests/figs/subplot/subplot-bump-axis-annotation-shared.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)