【发布时间】:2017-02-16 17:01:57
【问题描述】:
我有一个闪亮的应用程序,在一个页面上使用相同的日期范围包含多个 plot_ly 图表。出于复杂的原因,我希望将每个图表放在一个单独的模块中,并对plot_ly 缩放做出反应。
我做这个预模块的方法是捕获plotly_relayout 并让它调用updateDateRangeInput 将整个页面设置为该范围,然后通过我的其他plot_ly 图表级联。现在我们正在模块化这些图表,我无法拥有相同的行为。我捕获了重绘事件,但在父日期范围内调用 updateDateRangeInput 似乎没有效果。
我尝试过使用命名空间的会话以及传递父会话并使用它调用。
非常简化的代码:
app.R:
library(shiny)
source("mod.R", local = TRUE)
ui <- shinyUI(fluidPage(
chartTimeseriesUI("myseries")
, dateRangeInput("dateRange", "Select Date Range:"
, start = Sys.Date() - 600
, end = Sys.Date()
, min = Sys.Date() - 1200
, max = Sys.Date()
)
))
server <- shinyServer(function(input, output, session) {
callModule(chartTimeseries, id = "myseries", reactive(input$dateRange), session)
})
shinyApp(ui = ui, server = server)
mod.R:
chartTimeseriesUI <- function(id) {
ns <- NS(id)
plotlyOutput(outputId = ns("timeseries"))
}
chartTimeseries <- function(input, output, session, dateRange, psession) {
regionRedraw <- reactive({
print("I'm in redraw")
d <- event_data("plotly_relayout", source = "timeseries")
if(is.null(d)) { # double click
startdate <- Sys.Date() - 600
enddate <- Sys.Date()
} else {
xstart <- d$`xaxis.range[0]`
xend <- d$`xaxis.range[1]`
if (is.null(xstart)) {
startdate <- Sys.Date() - 600
enddate <- Sys.Date()
} else {
# Take our X time and convert it out of milliseconds
startdate <- as.POSIXlt(xstart/1000, origin="1970-01-01", tz="America/New_York")
enddate <- as.POSIXlt(xend/1000, origin="1970-01-01", tz="America/New_York")
}
}
absmindate <- Sys.Date() - 1200
absmaxdate <- Sys.Date()
updateDateRangeInput(psession, dateRange, label="Now for a new range:", start=startdate, end=enddate, min=absmindate, max=absmaxdate)
})
observe({
print("date range changed!")
d <- regionRedraw()
})
output$timeseries <- renderPlotly({
rangestart <- dateRange()[1]
rangeend <- dateRange()[2]
diff_in_days = as.numeric(difftime(rangeend, rangestart, units = "days"))
tm <- seq(0, diff_in_days, by = 10)
x <- rangeend - tm
y <- rnorm(length(x))
p <- plot_ly(x = ~x
, y = ~y
, type = "scatter"
, mode = "markers"
, text = paste(tm, "days from today")
, source = "timeseries")
})
}
输出
[1] "date range changed!"
[1] "I'm in redraw"
然后当我选择一个区域时,我得到:
[1] "date range changed!"
[1] "I'm in redraw"
并且绘图放大,日期范围不会更改为新选择,dateRangeInput 标签也不会更改。
感谢您的帮助!
【问题讨论】:
-
您的
dateRangeInput在您的模块之外,因此您无法从模块内部直接与其交互。我相信做你想做的事情的正确方法是使用 return 从模块外部更新输入或将 Date 输入放入模块中。