Skip to content

Commit b21b740

Browse files
authored
Merge pull request #1277 from ropensci/debounce
debounce the turnOn callback
2 parents 9e4e5cc + 0cf12e5 commit b21b740

File tree

7 files changed

+52
-12
lines changed

7 files changed

+52
-12
lines changed

NEWS.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
## NEW FEATURES & IMPROVEMENTS
44

5-
* Upgraded to plotly.js v1.38.1. A _huge_ amount of features and improvements have been made since v1.29.2 (i.e., the version included in the last CRAN release of the R package - v4.7.1). Highlights include a complete re-write of `scattergl` to make it nearly feature complete with `scatter`, localization of text rendering (i.e., international translations), and two new trace types (`violin` & `table`). Read more about the v1.32.0 release [here](https://codeburst.io/notes-from-the-latest-plotly-js-release-b035a5b43e21) and the complete list of changes [here](https://github.com/plotly/plotly.js/releases).
5+
* Upgraded to plotly.js v1.38.2. A _huge_ amount of features and improvements have been made since v1.29.2 (i.e., the version included in the last CRAN release of the R package - v4.7.1). Highlights include a complete re-write of `scattergl` to make it nearly feature complete with `scatter`, localization of text rendering (i.e., international translations), and two new trace types (`violin` & `table`). Read more about the v1.32.0 release [here](https://codeburst.io/notes-from-the-latest-plotly-js-release-b035a5b43e21) and the complete list of changes [here](https://github.com/plotly/plotly.js/releases).
66
* Support for **sf** (simple feature) data structures was added to `plot_ly()`, `plot_mapbox()`, and `plot_geo()` (via the new `add_sf()` function). See [this blog post](https://blog.cpsievert.me/2018/03/30/visualizing-geo-spatial-data-with-sf-and-plotly) for an overview.
77
* New "special arguments" `stroke`, `strokes`, `alpha_stroke`, `span`, and `spans` were added for easier control over the stroke (i.e., outline) appearance of various (filled) graphical marks. For an overview, see the **sf** blog post linked to in the bullet point above and the new package demos (list all demos with `demo(package = "plotly")`).
8-
* The selection (i.e., linked-brushing) mode can now switch from 'transient' to 'persistent' by holding the 'shift' key. It's still possible to _force_ persistent selection by setting `persistent = TRUE` in `highlight()`, but `persistent = FALSE` (the default) is now recommended since it allows one to switch between [persistent/transient selection](https://plotly-book.cpsievert.me/linking-views-without-shiny.html#transient-versus-persistent-selection) in the browser, rather than at the command line.
98
* The new `partial_bundle()` function makes it easy to leverage [partial bundles of plotly.js](https://github.com/plotly/plotly.js#partial-bundles) for reduced file sizes and faster render times.
109
* The `config()` function gains a `locale` argument for easily changing localization defaults (see #1270). This makes it possible localize date axes, and in some cases, modebar buttons (see #1270)
1110
* One may now inform `ggplotly()` about the relevant **shiny** output size via `session$clientData`. This ensures `ggplotly()` sizing is closer to **ggplot2** sizing, even on window resize. For an example, run `plotly_example("shiny", "ggplotly_sizing")`.
1211
* Instead of an error, `ggplotly(NULL, "message")` and `plotly_build(NULL, "message")` now returns `htmltools::div("message")`, making it easier to relay messages in shiny when data isn't yet ready to plot (see #1116)
12+
* The selection (i.e., linked-brushing) mode can now switch from 'transient' to 'persistent' by holding the 'shift' key. It's still possible to _force_ persistent selection by setting `persistent = TRUE` in `highlight()`, but `persistent = FALSE` (the default) is now recommended since it allows one to switch between [persistent/transient selection](https://plotly-book.cpsievert.me/linking-views-without-shiny.html#transient-versus-persistent-selection) in the browser, rather than at the command line.
13+
* The `highlight()` function gains a `debounce` argument for throttling the rate at which `on` events may be fired. This is mainly useful for improving user experience when `highlight(on = "plotly_hover")` and mousing over relevant markers at a rapid rate (see #1277)
1314
* The `animation_button()` function gains a `label` argument, making it easier to control the label of an animation button generated through the `frame` API (see #1205).
1415

1516
## CHANGES

R/highlight.R

+7-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
#' @param opacityDim a number between 0 and 1 used to reduce the
4444
#' opacity of non-selected traces (by multiplying with the existing opacity).
4545
#' @param selected attributes of the selection, see [attrs_selected()].
46+
#' @param debounce amount of time to wait before firing an event (in milliseconds).
47+
#' This is especially useful when `on = "plotly_hover"` to avoid firing too many events
48+
#' when users clickly move the mouse over relevant graphical marks.
4649
#' @param ... currently not supported.
4750
#' @export
4851
#' @author Carson Sievert
@@ -80,7 +83,8 @@ highlight <- function(p, on = "plotly_click", off,
8083
dynamic = FALSE, color = NULL,
8184
selectize = FALSE, defaultValues = NULL,
8285
opacityDim = getOption("opacityDim", 0.2),
83-
selected = attrs_selected(), ...) {
86+
selected = attrs_selected(), debounce = 1,
87+
...) {
8488

8589
# currently ... is not-supported and will catch
8690
# some arguments we supported at one point
@@ -154,7 +158,8 @@ highlight <- function(p, on = "plotly_click", off,
154158
selectize = selectize,
155159
defaultValues = defaultValues,
156160
opacityDim = opacityDim,
157-
selected = selected
161+
selected = selected,
162+
debounce = debounce
158163
)
159164

160165
p

R/plotly.R

+4-2
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,8 @@ typedArrayPolyfill <- function() {
424424
# and bundle size at print time.
425425
plotlyMainBundle <- function() {
426426
htmltools::htmlDependency(
427-
"plotly-main", "1.38.1",
427+
"plotly-main",
428+
version = "1.38.2",
428429
src = depPath("plotlyjs"),
429430
script = "plotly-latest.min.js",
430431
all_files = FALSE
@@ -433,7 +434,8 @@ plotlyMainBundle <- function() {
433434

434435
plotlyHtmlwidgetsCSS <- function() {
435436
htmltools::htmlDependency(
436-
"plotly-htmlwidgets-css", "1.38.1",
437+
"plotly-htmlwidgets-css",
438+
version = plotlyMainBundle()$version,
437439
src = depPath("plotlyjs"),
438440
stylesheet = "plotly-htmlwidgets.css",
439441
all_files = FALSE

inst/htmlwidgets/lib/plotlyjs/plotly-latest.min.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inst/htmlwidgets/plotly.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ HTMLWidgets.widget({
460460
selection.on("change", selectionChange);
461461

462462
// Set a crosstalk variable selection value, triggering an update
463-
graphDiv.on(x.highlight.on, function turnOn(e) {
463+
var turnOn = function(e) {
464464
if (e) {
465465
var selectedKeys = pointsToKeys(e.points);
466466
// Keys are group names, values are array of selected keys from group.
@@ -470,7 +470,9 @@ HTMLWidgets.widget({
470470
}
471471
}
472472
}
473-
});
473+
};
474+
475+
graphDiv.on(x.highlight.on, debounce(turnOn, x.highlight.debounce));
474476

475477
graphDiv.on(x.highlight.off, function turnOff(e) {
476478
// remove any visual clues
@@ -878,3 +880,25 @@ function removeBrush(el) {
878880
outlines[i].remove();
879881
}
880882
}
883+
884+
885+
// https://davidwalsh.name/javascript-debounce-function
886+
887+
// Returns a function, that, as long as it continues to be invoked, will not
888+
// be triggered. The function will be called after it stops being called for
889+
// N milliseconds. If `immediate` is passed, trigger the function on the
890+
// leading edge, instead of the trailing.
891+
function debounce(func, wait, immediate) {
892+
var timeout;
893+
return function() {
894+
var context = this, args = arguments;
895+
var later = function() {
896+
timeout = null;
897+
if (!immediate) func.apply(context, args);
898+
};
899+
var callNow = immediate && !timeout;
900+
clearTimeout(timeout);
901+
timeout = setTimeout(later, wait);
902+
if (callNow) func.apply(context, args);
903+
};
904+
};

man/highlight.Rd

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/plot_ly.Rd

+5-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)