Shiny actionButton() output in onRender() function of htmlWidgets

纵然是瞬间 提交于 2019-12-25 16:53:16

问题


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.


回答1:


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


来源:https://stackoverflow.com/questions/43700201/shiny-actionbutton-output-in-onrender-function-of-htmlwidgets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!