My goal is to create a script where initially a blank plotly graph is displayed. If the user clicks on a Shiny actionButton saying "Add points", then points will be added to the plotly graph via the onRender() function of htmlWidgets. This would be efficient because the background blank plotly graph would not need to be replotted when the user selects the Shiny actionButton.
However, in order for me to achieve this, I would need to figure out a way to indicate the change in the Shiny actionButton directly into the onRender() function so that the blank plotly graph (in the code below called "pP") would not be altered at all. I put two commented lines as an if statement in the onRender() code below to show what I am aiming for.
I know there is a function called Shiny.onInputChange('variable', variable) that can be called inside the onRender() function to save a variable that was created inside onRender() so that it can be used like a Shiny input outside of the onRender() function. So, I guess I am looking for something that does the reverse (transfers a shiny input value directly into the onRender() function).
ui <- shinyUI(fluidPage(
uiOutput("add"),
plotlyOutput("myPlot", height = 700)
))
server <- shinyServer(function(input, output) {
output$add <- renderUI({
actionButton("addButton", "Add points")
})
output$myPlot <- renderPlotly({
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_blank()
pP <- ggplotly(p)
pP %>% onRender("
function(el, x, data) {
//if (input$addButton selected){
var Traces = [];
var trace = {
x: data.x,
y: data.y,
mode: 'markers',
marker: {
color: 'green',
size: 6
},
hoverinfo: 'none'
};
Traces.push(trace);
Plotly.addTraces(el.id, Traces);
//}
}", data = list(x = mtcars$wt, y = mtcars$mpg))
})
})
shinyApp(ui, server)
Note: This is similar to a question I asked earlier (Using Shiny actionButton() function in onRender() function of htmlWidgets). However, I simplified the question and am hoping to determine if there is a simple answer that might be available.
You can try using some jQuery directly in order to respond to the user clicking on the button. The onRender
would be:
function(el, x, data) {
$('#addButton').on('click',function() {
var Traces = [];
var trace = {
x: data.x,
y: data.y,
mode: 'markers',
marker: {
color: 'green',
size: 6
},
hoverinfo: 'none'
};
Traces.push(trace);
Plotly.addTraces(el.id, Traces);
})
}
For this to work the button needs to be created first, so I changed your ui.R
to:
ui <- shinyUI(fluidPage(
actionButton("addButton", "Add points"),
plotlyOutput("myPlot", height = 700)
))
Edit: If you want to keep the renderUI
, you can use event-delegation to bind your function buttons in the #add
div:
function(el, x, data) {
$('#add').on('click','button',function() {
var Traces = [];
var trace = {
x: data.x,
y: data.y,
mode: 'markers',
marker: {
color: 'green',
size: 6
},
hoverinfo: 'none'
};
Traces.push(trace);
Plotly.addTraces(el.id, Traces);
})
}