I have two reactive values input$code
and input$variants
and I want to redraw the plot once if any of the following conditions are true.
- code changes and variants changes
- code changes and variants does not change
- code does not change and variants changes
I can't call both input$code
and input$variants
in renderPlotly or else the plot will get redrawn twice for #1 above.
output$choose_test <- renderUI({ data_sets <- loadTest() selectizeInput( 'test', 'Test', choices = data_sets$test, selected = data_sets$test[1] ) }) output$choose_code <- renderUI({ validate( need(input$test, 'Please choose a test.') ) code <- loadCode(input$test) selectizeInput( 'code', 'Code', choices = code$code, selected = code$code[1] ) }) output$choose_variants <- renderUI({ validate( need(input$test, 'Please choose a test.'), need(input$code, 'Please choose a code.') ) dat <- loadVariants(input$test, input$code) default_select <- dat$variant[grep('v1|v2', dat$variant)] if (identical(default_select, factor(0))) { default_select <- dat$variant[1] } checkboxGroupInput("variants", "Variants", choices = dat$variant, selected = default_select) }) output$plot1 <- renderPlotly({ runLocations <- isolate(loadRunsBetweenDates(input$test, input$code, input$variants)) total_min_df <- runLocations %>% group_by(change_number, variant) %>% summarize(memory = min(memory)) total_min_df$change_number <- as.numeric(as.character(total_min_df$change_number)) p <- ggplot(total_min_df, aes(x=change_number, y=memory, group=variant, color=variant))+ geom_point()+ geom_smooth(se = FALSE)+ scale_x_continuous(labels = function(n){format(n, scientific = FALSE)})+ scale_y_continuous(labels = function(n){format(n, scientific = FALSE)})+ labs(x = "Change Number", y = "Megabytes") ggplotly(p) })
1 Answers
Answers 1
From what i see your input$test
, potentially triggers an update in input$code
. That results in the problem that a change in input$test
can trigger your described "double update".
What you can do is make a single trigger, that you store e.g. in a reactive value global$updatePlot
and make the update in the plot solely dependent on that variable (with isolate, see code).
Now, you also have to make sure that not only the trigger only fires once but also only fires if the potential update in input$code
is ready.
It could work as provided below, but as the others wrote without a reproducible example its hard to be sure ;)
# new code here observe({ validate( need(input$test, 'Please choose a test.'), need(input$variants, 'Please choose a variant.') ) input$variants global$code <- loadCode(input$test) # now global$code triggered potential new input$code and we can give trigger the plot update global$updatePlot <- rnorm(1) }) #changed code here output$choose_code <- renderUI({ code <- global$code selectizeInput( 'code', 'Code', choices = code$code, selected = code$code[1] ) }) # store the trigger for plot update if inputs changed global <- reactiveValues(updatePlot = TRUE) output$plot1 <- renderPlotly({ # update plot only with a single trigger. global$updatePlot isolate({ validate( need(input$test, 'Please choose a test.'), need(input$variants, 'Please choose a variant.'), need(input$code, 'Please choose a code.') ) runLocations <- isolate(loadRunsBetweenDates(input$test, input$code, input$variants)) total_min_df <- runLocations %>% group_by(change_number, variant) %>% summarize(memory = min(memory)) total_min_df$change_number <- as.numeric(as.character(total_min_df$change_number)) p <- ggplot(total_min_df, aes(x=change_number, y=memory, group=variant, color=variant))+ geom_point()+ geom_smooth(se = FALSE)+ scale_x_continuous(labels = function(n){format(n, scientific = FALSE)})+ scale_y_continuous(labels = function(n){format(n, scientific = FALSE)})+ labs(x = "Change Number", y = "Megabytes") ggplotly(p) }) })
0 comments:
Post a Comment