Skip to content

Commit f23838f

Browse files
committed
Allow shiny input priority to be configurable at the plot-level, closes #1043
1 parent 5a54e41 commit f23838f

File tree

4 files changed

+63
-18
lines changed

4 files changed

+63
-18
lines changed

R/layout.R

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ rangeslider <- function(p, start = NULL, end = NULL, ...) {
101101
#' (see [here](https://github.com/ropensci/plotly/blob/master/inst/examples/rmd/MathJax/index.Rmd)
102102
#' for an **rmarkdown** example and
103103
#' [here](https://github.com/ropensci/plotly/blob/master/inst/examples/rmd/MathJax/index.Rmd) for a **shiny** example).
104+
#' @param priority the priority of shiny input events. If `NULL` (the default), then
105+
#' [event_data()] becomes invalidated only when the input value changes. If `"event"`,
106+
#' then the event will always fire, regardless of whether the value has changed.
104107
#' @author Carson Sievert
105108
#' @export
106109
#' @examples
@@ -131,7 +134,7 @@ rangeslider <- function(p, start = NULL, end = NULL, ...) {
131134
#' config(p, locale = "zh-CN")
132135
#'
133136

134-
config <- function(p, ..., collaborate = TRUE, cloud = FALSE, locale = NULL, mathjax = NULL) {
137+
config <- function(p, ..., collaborate = TRUE, cloud = FALSE, locale = NULL, mathjax = NULL, priority = NULL) {
135138

136139
if (!is.null(locale)) {
137140
p$dependencies <- c(
@@ -170,6 +173,7 @@ config <- function(p, ..., collaborate = TRUE, cloud = FALSE, locale = NULL, mat
170173
}
171174

172175
p$x$config$cloud <- cloud
176+
p$x$config$priority <- priority
173177

174178
p
175179
}

R/proxy.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ plotlyjs_methods <- function() {
101101
c(
102102
"restyle", "relayout", "update", "addTraces", "deleteTraces", "moveTraces",
103103
"extendTraces", "prependTraces", "purge", "toImage", "downloadImage", "animate",
104-
"newPlot", "react", "validate", "makeTemplate", "validateTemplate", "addFrames"
104+
"newPlot", "react", "validate", "makeTemplate", "validateTemplate", "addFrames",
105+
"reconfig"
105106
)
106107
}
107108

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
library(plotly)
2+
library(shiny)
3+
4+
ui <- fluidPage(
5+
checkboxInput("priority", "Shiny event priority", FALSE),
6+
plotlyOutput("p")
7+
)
8+
9+
server <- function(input, output, session) {
10+
11+
output$p <- renderPlotly({
12+
title <- if (input$priority) {
13+
"Clicking on the same point repeatedly will keep triggering console output"
14+
} else {
15+
"Clicking on the same point won't trigger more output"
16+
}
17+
18+
plot_ly(mtcars, x = ~wt, y = ~mpg) %>%
19+
layout(title = title) %>%
20+
config(priority = if (input$priority) "event")
21+
})
22+
23+
observeEvent(event_data("plotly_click"), {
24+
print("clicked!")
25+
})
26+
27+
}
28+
29+
shinyApp(ui, server)

inst/htmlwidgets/plotly.js

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -272,29 +272,35 @@ HTMLWidgets.widget({
272272

273273
// send user input event data to shiny
274274
if (HTMLWidgets.shinyMode) {
275+
var priority = x.config.priority ? {priority: x.config.priority} : undefined;
276+
275277
// https://plot.ly/javascript/zoom-events/
276278
graphDiv.on('plotly_relayout', function(d) {
277279
Shiny.setInputValue(
278280
".clientValue-plotly_relayout-" + x.source,
279-
JSON.stringify(d)
281+
JSON.stringify(d),
282+
priority
280283
);
281284
});
282285
graphDiv.on('plotly_restyle', function(d) {
283286
Shiny.setInputValue(
284287
".clientValue-plotly_restyle-" + x.source,
285-
JSON.stringify(d)
288+
JSON.stringify(d),
289+
priority
286290
);
287291
});
288292
graphDiv.on('plotly_hover', function(d) {
289293
Shiny.setInputValue(
290294
".clientValue-plotly_hover-" + x.source,
291-
JSON.stringify(eventDataWithKey(d))
295+
JSON.stringify(eventDataWithKey(d)),
296+
priority
292297
);
293298
});
294299
graphDiv.on('plotly_click', function(d) {
295300
Shiny.setInputValue(
296301
".clientValue-plotly_click-" + x.source,
297-
JSON.stringify(eventDataWithKey(d))
302+
JSON.stringify(eventDataWithKey(d)),
303+
priority
298304
);
299305
});
300306
graphDiv.on('plotly_selected', function(d) {
@@ -307,47 +313,52 @@ HTMLWidgets.widget({
307313
if (d) {
308314
Shiny.setInputValue(
309315
".clientValue-plotly_selected-" + x.source,
310-
JSON.stringify(eventDataWithKey(d))
316+
JSON.stringify(eventDataWithKey(d)),
317+
priority
311318
);
312319
var limits = d.range ? d.range : d.lassoPoints;
313320
Shiny.setInputValue(
314321
".clientValue-plotly_brush-" + x.source,
315-
JSON.stringify(limits)
322+
JSON.stringify(limits),
323+
priority
316324
);
317325
}
318326
});
319327
graphDiv.on('plotly_selecting', function(d) {
320328
if (d) {
321329
Shiny.setInputValue(
322330
".clientValue-plotly_selecting-" + x.source,
323-
JSON.stringify(eventDataWithKey(d))
331+
JSON.stringify(eventDataWithKey(d)),
332+
priority
324333
);
325334
var limits = d.range ? d.range : d.lassoPoints;
326335
Shiny.setInputValue(
327336
".clientValue-plotly_brushing-" + x.source,
328-
JSON.stringify(limits)
337+
JSON.stringify(limits),
338+
priority
329339
);
330340
}
331341
});
332342
graphDiv.on('plotly_unhover', function(eventData) {
333-
Shiny.setInputValue(".clientValue-plotly_hover-" + x.source, null);
343+
Shiny.setInputValue(".clientValue-plotly_hover-" + x.source, null, priority);
334344
});
335345
graphDiv.on('plotly_doubleclick', function(eventData) {
336-
Shiny.setInputValue(".clientValue-plotly_click-" + x.source, null);
346+
Shiny.setInputValue(".clientValue-plotly_click-" + x.source, null, priority);
337347
});
338348
// 'plotly_deselect' is code for doubleclick when in select mode
339349
graphDiv.on('plotly_deselect', function(eventData) {
340-
Shiny.setInputValue(".clientValue-plotly_selected-" + x.source, null);
341-
Shiny.setInputValue(".clientValue-plotly_selecting-" + x.source, null);
342-
Shiny.setInputValue(".clientValue-plotly_brush-" + x.source, null);
343-
Shiny.setInputValue(".clientValue-plotly_brushing-" + x.source, null);
344-
Shiny.setInputValue(".clientValue-plotly_click-" + x.source, null);
350+
Shiny.setInputValue(".clientValue-plotly_selected-" + x.source, null, priority);
351+
Shiny.setInputValue(".clientValue-plotly_selecting-" + x.source, null, priority);
352+
Shiny.setInputValue(".clientValue-plotly_brush-" + x.source, null, priority);
353+
Shiny.setInputValue(".clientValue-plotly_brushing-" + x.source, null, priority);
354+
Shiny.setInputValue(".clientValue-plotly_click-" + x.source, null, priority);
345355
});
346356

347357
graphDiv.on('plotly_clickannotation', function(d) {
348-
Shiny.setInputValue(".clientValue-plotly_clickannotation-" + x.source, JSON.stringify(d.fullAnnotation));
358+
Shiny.setInputValue(".clientValue-plotly_clickannotation-" + x.source, JSON.stringify(d.fullAnnotation), priority);
349359
});
350360

361+
// This is a 'true' event -- always give it priority
351362
graphDiv.on('plotly_afterplot', function() {
352363
Shiny.setInputValue(".clientValue-plotly_afterplot-" + x.source, "afterplot", {priority: "event"});
353364
});

0 commit comments

Comments
 (0)