Как сбросить один sliderInput при смене секунды, не вызывая реактив в Shiny - PullRequest
0 голосов
/ 03 февраля 2019

Я прошу прощения, если на этот вопрос есть тривиальный ответ, и мое ограниченное знание Shiny привело меня по неверному пути во время моего обширного поиска ответа.

Я пытаюсь решить следующую проблему.У меня есть выход, который зависит от двух sliderInputs для создания графика.Ползунки, в свою очередь, зависят друг от друга в том смысле, что состояние второго ползунка следует сбрасывать при каждом изменении значения для первого ползунка.Моя текущая попытка реализации этого выглядит следующим образом:

library(shiny)
library(plotly)
library(ggplot2)    

ui <- fluidPage(

  titlePanel("Test"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("slider1", "Slider1:", min = 0, max = 100, value = 0, step= 0.1),
      sliderInput("slider2", "Slider2:", min = 0, max = 100, value = 0, step= 0.1)
    ),
    mainPanel(
      plotlyOutput('plot', height = 600)
    )
  )
)


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

  #temporary state storage.
  slider1.state <- reactiveVal(-1)
  counter <- reactiveVal(0)

  output$plot <- renderPlotly({

    print(paste("Function Call Number ", isolate(counter()) )) 
    counter(isolate(counter())+1)

    #Only reset Slider2 if Slider1 has been changed
    if (isolate(slider1.state()) != input$slider1) {

      #this triggers a redraw
      updateSliderInput(session, "slider2", value=0 )

    }
    ylim_max = input$slider2

    #set the new values of the sliders
    slider1.state(input$slider1)

    ggplot(data.frame()) + geom_point() + xlim(0, input$slider1) + ylim(0, ylim_max)

  })

}

shinyApp(ui, server)

Я использую реактивные значения для сохранения состояния slider1 и сбрасываю slider2, используя updateSliderInput, только когда slider1 изменилось.Однако проблема, с которой я сталкиваюсь, заключается в том, что вызов updateSliderInput вызывает функцию renderPlotly во второй раз, следовательно, излишне вычисляет и перерисовывает график во второй раз.

Я попытался найти решение, которое позволило бы мне каким-то образом обновить sliderInput, не вызывая событие, но безрезультатно.Есть ли элегантный способ получить такое поведение?В идеале я ищу решение, которое можно было бы применить к произвольным входам.

Любая помощь в этом вопросе будет принята с благодарностью.Спасибо!

1 Ответ

0 голосов
/ 04 февраля 2019

Вы можете использовать debounce(), чтобы избежать ненужных обновлений:

library(shiny)
library(plotly)
library(ggplot2)    

ui <- fluidPage(

  titlePanel("Test"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("slider1", "Slider1:", min = 0, max = 100, value = 0, step= 0.1),
      sliderInput("slider2", "Slider2:", min = 0, max = 100, value = 0, step= 0.1)
    ),
    mainPanel(
      plotlyOutput('plot', height = 600)
    )
  )
)


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

  observeEvent(input$slider1, {
    updateSliderInput(session, "slider2", value=0 )
  })

  plot_limits <- reactive({
    list(xlim_max = input$slider1, ylim_max = input$slider2)
  })

  plot_limits_d <- plot_limits %>% debounce(500)

  counter <- reactiveVal(0)

  output$plot <- renderPlotly({
    print(paste("Function Call Number ", isolate(counter()) )) 
    counter(isolate(counter())+1)
    ggplot(data.frame()) + geom_point() + xlim(0, plot_limits_d()$xlim_max) + ylim(0, plot_limits_d()$ylim_max)
  })

}

shinyApp(ui, server)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...