rstudio / dygraphs

R interface to dygraphs
http://rstudio.github.io/dygraphs
Other
365 stars 193 forks source link

Synchronization of Shiny's dateRangeInput() with dygraphs dyRangeSelector() #130

Open ero opened 8 years ago

ero commented 8 years ago

I have been searching for the solution of this for a long time now, but I'm not sure what I am doing wrong or its the problem with the dygraphs or shiny library.

I can't figure it out - how to sync/connect dateRangeInput widget and rendering of dygraphs dyRange selector variable (input$dygraph_dateWindow) in BOTH ways.

Basically what I want is, if I move dyRangeSelectors on the graph,I would like that shinyWidget dateRangeInput() (those two input calandars) gets the new dyRangeSelector date variable.

Please see the code example below.

library(shiny)
library(dygraphs)

ui <- shinyUI(fluidPage(

  titlePanel("Predicted Deaths from Lung Disease (UK)"),

  sidebarLayout(
    sidebarPanel(
      numericInput("months", label = "Months to Predict", 
                   value = 72, min = 12, max = 144, step = 12),
      selectInput("interval", label = "Prediction Interval",
                  choices = c("0.80", "0.90", "0.95", "0.99"),
                  selected = "0.95"),
      checkboxInput("showgrid", label = "Show Grid", value = TRUE),
      hr(),
      div(strong("From: "), textOutput("from", inline = TRUE)),
      div(strong("To: "), textOutput("to", inline = TRUE)),
      br(),
      helpText("Click and drag to zoom in (double click to zoom back out)."),
      dateRangeInput(inputId = "inDateRange",label = "Date"),
      br()

    ),
    mainPanel(
      dygraphOutput("dygraph")
    )
  )
))

library(dygraphs)
library(datasets)

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

  predicted <- reactive({
    hw <- HoltWinters(ldeaths)
    predict(hw, n.ahead = input$months, 
            prediction.interval = TRUE,
            level = as.numeric(input$interval))
  })

  output$dygraph <- renderDygraph({

    dygraph(predicted(), main = "Predicted Deaths/Month") %>%
      dySeries(c("lwr", "fit", "upr"), label = "Deaths") %>%
      dyRangeSelector(dateWindow = c(dyStartDate(),
                                     dyEndDate()),
        retainDateWindow = T)
  })
  output$from <- renderText({
    if (!is.null(input$dygraph_date_window))
      strftime(input$dygraph_date_window[[1]], "%d %b %Y")      
  })

  output$to <- renderText({
    if (!is.null(input$dygraph_date_window))
      strftime(input$dygraph_date_window[[2]], "%d %b %Y")
  })

  # how to use inDateRange calandar to change dyRange?
  observe({
    #connection/sync of dygraphs to daterange works...
    if (!is.null(input$dygraph_date_window)){

      updateDateRangeInput(session, "inDateRange",
                           start = strftime(input$dygraph_date_window[[1]]),
                           end = strftime(input$dygraph_date_window[[2]])
      )
    }
  })

  #... but not the other way around!
  dyStartDate <- reactive({

    if (!is.null(input$inDateRange[1])) {
      strftime(input$inDateRange[1])
    }
  })

  dyEndDate <- reactive({

    if (!is.null(input$inDateRange[2])) {
      strftime(input$inDateRange[2])
    }
  })

})

shinyApp(ui = ui, server = server)
fred777 commented 7 years ago

I'm, struggling with a similar situation.

You mast not use dateWindow and retainDateWindow=T simultaneously. The latter will prevent dateWindow to be set as desired. I worked around this with an if/else and that either calls with retainDateWindow=T or with dateWindow=... depending on whether dateWindow has to be overriden. But this still doesn't work as desired in all cases.

What's missing is an updateDygraph-Function that only sets the dateWindow but does not redraw. With this, things would be much easier...

VincentGuyader commented 6 years ago

Hi,

I put the same kind of quesiton on SO. https://stackoverflow.com/questions/49215000/synchronise-dygraph-and-daterangeinput-in-shiny

(maybe it can help ?)

Regards