简体   繁体   中英

How to prevent JS code to run multiple times in R Shiny?

I try to use a workaround for the highcharter package to update the chart and not to rerender it which looks much smoother. So far, my functions works fine as long as I run the code in a seperate JS file. But to make it more flexible I want to write with function with R. When I click the input$data button, the code seems to run as many times as the value input$data has got (see the print statement). Why is this happening and what can I do to prevent this issue?

library(highcharter)
library(shiny)
library(shinyjs)

df <- data.frame(
    a = floor(runif(10, min = 1, max = 10)),
    b = floor(runif(10, min = 1, max = 10))
)


updaterfunction <- function() {

    jscode <- 
        '$("#data").on("click",function() {

        console.log("code was run")

    Shiny.addCustomMessageHandler("handler1", function(message1){
        var chart1 = $("#plot").highcharts()

        var newArray1 = new Array(message1.length)
        var newArray2 = new Array(message1.length)

        for(var i in message1) {
            newArray1[i] = message1[i].a
            newArray2[i] = message1[i].b
        }

        chart1.series[0].update({
            // type: "line",
            data: newArray1
        }, false)

        chart1.series[1].update({
        //   type: "line",
          data: newArray2
      }, false)

      chart1.redraw();
    })

    });'

    runjs(jscode)
}




# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Old Faithful Geyser Data"),
    #includeScript("www/script.js"),
    useShinyjs(),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30),
            actionButton("data2", "Generate Data"),
            actionButton("data", "Generate Data")
        ),

        # Show a plot of the generated distribution
        mainPanel(
           highchartOutput("plot"),
           highchartOutput("plot2")
        )
    )
)


server <- function(input, output, session) {


    observeEvent(input$data, {

    print(input$data)

        df <- data.frame(
            a = floor(runif(10, min = 1, max = 10)),
            b = floor(runif(10, min = 1, max = 10))
        )

        message1 = jsonlite::toJSON(df)
        session$sendCustomMessage("handler1", message1)

        updaterfunction()

    })


    reactivedata <- eventReactive(input$data2, {

        df <- data.frame(
            a = floor(runif(10, min = 1, max = 10)),
            b = floor(runif(10, min = 1, max = 10))
        )
    })

    output$plot <- renderHighchart({

        highchart() %>%

            hc_add_series(type = "bar", data = df$a) %>%
            hc_add_series(type = "bar", data = df$b)

    })


    output$plot2 <- renderHighchart({

        highchart() %>%

            hc_add_series(type = "bar", data = reactivedata()$a) %>%
            hc_add_series(type = "bar", data = reactivedata()$b)
    })


}

# Run the application 
shinyApp(ui = ui, server = server)

That's because each time you run the JS code, it attaches a new click event to the button. You can use off("click") to remove the previous event handler:

  jscode <- 
    '$("#data").off("click").on("click",function() {

But I'm not sure this produces the expected behaviour. Is it ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM