Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8f5be40

Browse filesBrowse files
authored
Allow highlight() selectize to contain selectize.js options (#2217)
* Close #2216: allow highlight() selectize to contain selectize.js options * Update shinytest screenshots * Update shinytest baseline * Close #2218: properly construct mapping between crosstalk sets and keys when constructing selectize payload * document the new feature * update news * Fix tests * Revert "Update shinytest baseline" This reverts commit fa5a1d5.
1 parent 3a33b1a commit 8f5be40
Copy full SHA for 8f5be40

File tree

Expand file treeCollapse file tree

11 files changed

+125
-45
lines changed
Filter options
Expand file treeCollapse file tree

11 files changed

+125
-45
lines changed

‎DESCRIPTION

Copy file name to clipboardExpand all lines: DESCRIPTION
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ Suggests:
7979
reticulate,
8080
rsvg
8181
LazyData: true
82-
RoxygenNote: 7.2.1
82+
RoxygenNote: 7.2.3
8383
Encoding: UTF-8
8484
Roxygen: list(markdown = TRUE)

‎NEWS.md

Copy file name to clipboardExpand all lines: NEWS.md
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# 4.10.1.9000
22

3+
## New features
4+
5+
* Closed #2216: Additional selectize.js options can now be passed along to `highlight()`'s `selectize` argument. (#2217)
6+
37
## Bug fixes
48

5-
* `ggplotly()` no longer errors given a `geom_area()` with 1 or less data points (error introduced by new behavior in ggplot2 v3.4.0). (#2209)
9+
* Closed #2218: `highlight(selectize = TRUE)` no longer yields an incorrect selectize.js result when there is a combination of crosstalk and non-crosstalk traces. (#2217)
10+
* Closed #2208: `ggplotly()` no longer errors given a `geom_area()` with 1 or less data points (error introduced by new behavior in ggplot2 v3.4.0). (#2209)
611

712

813
# 4.10.1

‎R/highlight.R

Copy file name to clipboardExpand all lines: R/highlight.R
+5-3Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
#' highlighting selections. See [toRGB()] for valid color
3737
#' specifications. If `NULL` (the default), the color of selected marks
3838
#' are not altered.
39-
#' @param selectize provide a selectize.js widget for selecting keys? Note that
40-
#' the label used for this widget derives from the groupName of the SharedData object.
39+
#' @param selectize whether or not to render a selectize.js widget for selecting
40+
#' [highlight_key()] values. A list of additional selectize.js options may
41+
#' also be provided. The label used for this widget should be set via the
42+
#' `groupName` argument of [highlight_key()].
4143
#' @param defaultValues a vector of values for setting a "default selection".
4244
#' These values should match the key attribute.
4345
#' @param opacityDim a number between 0 and 1 used to reduce the
@@ -115,7 +117,7 @@ highlight <- function(p, on = "plotly_click", off,
115117

116118
# attach HTML dependencies (these libraries are used in the HTMLwidgets.renderValue() method)
117119
# TODO: only attach these when keys are present!
118-
if (selectize) {
120+
if (!identical(selectize, FALSE)) {
119121
p$dependencies <- c(p$dependencies, list(selectizeLib()))
120122
}
121123
if (dynamic) {

‎R/utils.R

Copy file name to clipboardExpand all lines: R/utils.R
+55-30Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -366,31 +366,32 @@ supply_highlight_attrs <- function(p) {
366366
# set "global" options via crosstalk variable
367367
p$x$highlight <- p$x$highlight %||% highlight_defaults()
368368

369-
# defaults are now populated, allowing us to populate some other
370-
# attributes such as the selectize widget definition
371-
sets <- unlist(lapply(p$x$data, "[[", "set"))
372-
keys <- setNames(lapply(p$x$data, "[[", "key"), sets)
373-
p$x$highlight$ctGroups <- i(unique(sets))
369+
# Grab the special "crosstalk set" (i.e., group) for each trace
370+
sets <- lapply(p$x$data, "[[", "set")
371+
noSet <- vapply(sets, is.null, logical(1))
372+
373+
# If no sets are present, there's nothing more to do
374+
if (all(noSet)) {
375+
return(p)
376+
}
377+
378+
# Store the unique set of crosstalk sets (which gets looped over client-side)
379+
p$x$highlight$ctGroups <- i(unique(unlist(sets)))
380+
381+
# Build a set -> key mapping for each relevant trace, which we'll use
382+
# to set default values and/or build the selectize.js payload (if relevant)
383+
setDat <- p$x$data[!noSet]
384+
keys <- setNames(lapply(setDat, "[[", "key"), sets[!noSet])
374385

375-
# TODO: throw warning if we don't detect valid keys?
376-
hasKeys <- FALSE
377386
for (i in p$x$highlight$ctGroups) {
387+
388+
# Get all the keys for this crosstalk group
378389
k <- unique(unlist(keys[names(keys) %in% i], use.names = FALSE))
379-
if (is.null(k)) next
380390
k <- k[!is.null(k)]
381-
hasKeys <- TRUE
382-
383-
# include one selectize dropdown per "valid" SharedData layer
384-
if (isTRUE(p$x$highlight$selectize)) {
385-
# Hash i (the crosstalk group id) so that it can be used
386-
# as an HTML id client-side (i.e., key shouldn't contain spaces)
387-
p$x$selectize[[rlang::hash(i)]] <- list(
388-
items = data.frame(value = k, label = k), group = i
389-
)
390-
}
391+
if (length(k) == 0) next
391392

392393
# set default values via crosstalk api
393-
vals <- p$x$highlight$defaultValues[p$x$highlight$defaultValues %in% k]
394+
vals <- intersect(p$x$highlight$defaultValues, k)
394395
if (length(vals)) {
395396
p <- htmlwidgets::onRender(
396397
p, sprintf(
@@ -399,20 +400,44 @@ supply_highlight_attrs <- function(p) {
399400
)
400401
)
401402
}
403+
404+
# include one selectize dropdown per "valid" SharedData layer
405+
selectize <- p$x$highlight$selectize %||% FALSE
406+
if (!identical(selectize, FALSE)) {
407+
options <- list(items = data.frame(value = k, label = k), group = i)
408+
if (!is.logical(selectize)) {
409+
options <- modify_list(options, selectize)
410+
}
411+
# Hash i (the crosstalk group id) so that it can be used
412+
# as an HTML id client-side (i.e., key shouldn't contain spaces)
413+
groupId <- rlang::hash(i)
414+
415+
# If the selectize payload has already been built, use that already built payload
416+
# (since it may have been modified at this point), unless there are new keys to consider
417+
oldSelectize <- p$x$selectize[[groupId]]
418+
if (length(oldSelectize) > 0) {
419+
missingKeys <- setdiff(k, oldSelectize$items$value)
420+
if (length(missingKeys) > 0) {
421+
warning("Overwriting the existing selectize payload for group '", i, "'. If you've previously modified this payload in some way, consider modifying it again.")
422+
} else {
423+
options <- oldSelectize
424+
}
425+
}
426+
427+
p$x$selectize[[groupId]] <- options
428+
}
402429
}
403430

404-
# add HTML dependencies, set a sensible dragmode default, & throw messages
405-
if (hasKeys) {
406-
p$x$layout$dragmode <- p$x$layout$dragmode %|D|%
407-
default(switch(p$x$highlight$on %||% "", plotly_selected = "select", plotly_selecting = "select") %||% "zoom")
408-
if (is.default(p$x$highlight$off)) {
409-
message(
410-
sprintf(
411-
"Setting the `off` event (i.e., '%s') to match the `on` event (i.e., '%s'). You can change this default via the `highlight()` function.",
412-
p$x$highlight$off, p$x$highlight$on
413-
)
431+
# set a sensible dragmode default, & throw messages
432+
p$x$layout$dragmode <- p$x$layout$dragmode %|D|%
433+
default(switch(p$x$highlight$on %||% "", plotly_selected = "select", plotly_selecting = "select") %||% "zoom")
434+
if (is.default(p$x$highlight$off)) {
435+
message(
436+
sprintf(
437+
"Setting the `off` event (i.e., '%s') to match the `on` event (i.e., '%s'). You can change this default via the `highlight()` function.",
438+
p$x$highlight$off, p$x$highlight$on
414439
)
415-
}
440+
)
416441
}
417442

418443
p
Loading
Loading
Loading
Loading

‎inst/htmlwidgets/plotly.js

Copy file name to clipboardExpand all lines: inst/htmlwidgets/plotly.js
+10-8Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -521,15 +521,17 @@ HTMLWidgets.widget({
521521
// communication between the widget and direct manipulation events
522522
if (x.selectize) {
523523
var selectizeID = Object.keys(x.selectize)[i];
524-
var items = x.selectize[selectizeID].items;
524+
var options = x.selectize[selectizeID];
525525
var first = [{value: "", label: "(All)"}];
526-
var opts = {
527-
options: first.concat(items),
528-
searchField: "label",
529-
valueField: "value",
530-
labelField: "label",
531-
maxItems: 50
532-
};
526+
var opts = $.extend({
527+
options: first.concat(options.items),
528+
searchField: "label",
529+
valueField: "value",
530+
labelField: "label",
531+
maxItems: 50
532+
},
533+
options
534+
);
533535
var select = $("#" + selectizeID).find("select")[0];
534536
var selectize = $(select).selectize(opts)[0].selectize;
535537
// NOTE: this callback is triggered when *directly* altering

‎man/highlight.Rd

Copy file name to clipboardExpand all lines: man/highlight.Rd
+4-2Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎tests/testthat/test-animate-highlight.R

Copy file name to clipboardExpand all lines: tests/testthat/test-animate-highlight.R
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,50 @@ test_that("group_by.plotly() retains crosstalk set", {
8181
expect_true(all(b$x$data[[1]]$key == row.names(mtcars)))
8282
})
8383

84+
test_that("highlight(selectize) produces a sensible payload", {
85+
p <- plot_ly() %>%
86+
add_lines(data = mtcars, x = ~wt, y = ~mpg) %>%
87+
add_markers(
88+
data = highlight_key(mtcars, ~cyl, "Choose cylinder"),
89+
x = ~wt, y = ~mpg
90+
)
91+
92+
# Builds basic payload when selectize=TRUE
93+
b <- p %>%
94+
highlight(selectize = TRUE) %>%
95+
plotly_build()
96+
97+
selectize <- list(
98+
items = data.frame(value = c(6, 4, 8), label = c(6, 4, 8)),
99+
group = "Choose cylinder"
100+
)
101+
102+
expect_length(b$x$selectize, 1)
103+
expect_equal(b$x$selectize[[1]], selectize)
104+
105+
# Copies over any list() options
106+
b2 <- p %>%
107+
highlight(selectize = list(plugins = list("remove_button"))) %>%
108+
plotly_build()
109+
110+
selectize$plugins <- list("remove_button")
111+
112+
expect_length(b2$x$selectize, 1)
113+
expect_equal(b2$x$selectize[[1]], selectize)
114+
115+
# Can also tack on options after building, and plotly_build() won't overwrite
116+
b2$x$selectize[[1]] <- modifyList(
117+
b2$x$selectize[[1]], list(foo = "bar")
118+
)
119+
120+
b2 <- plotly_build(b2)
121+
122+
selectize$foo <- "bar"
123+
124+
expect_equal(b2$x$selectize[[1]], selectize)
125+
126+
})
127+
84128

85129

86130
# Ignore for now https://github.com/ggobi/ggally/issues/264

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.