Skip to content

Commit 53cab09

Browse files
committed
debounce the turnOn callback
1 parent 9e4e5cc commit 53cab09

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

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

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+
};

0 commit comments

Comments
 (0)