partial_bundle causes a Shiny app to fail when used in a module with only plotly outputs
未关闭
还没有人认领这个 Issue。
- 主要语言
- R
- 星标
- 2.7k
- 派生
- 641
- PR 合并指标
- 30 天内没有已合并 PR
描述
The app below fails to render any of its outputs when I try to run it; the error message in my web browser's console says Uncaught ReferenceError: Plotly is not defined. I believe this is due to partial_bundle() being used when a plotly object is first rendered in a shiny module with renderPlotly().
When I was creating this example, I noticed that this bug did not appear if either of the following conditions were met:
- The plotly object that is rendered inside the shiny module for the first time didn't use
partial_bundle(), for example, if the initial render of the plot didn't usepartial_bundle()due to conditional logic - The app has a non-plotly output visible, inside or outside the module, when the app is first rendered
library(plotly) # 4.10.0
library(shiny) # 1.7.1
# Create dummy data
dummy_data = data.frame(
x = Sys.Date() + 1:nrow(iris),
y = iris$Sepal.Length,
Species = iris$Species
)
testUI <- function(id, scatter_name, bar_name) {
# Define the namespace for this module
ns = NS(id)
# Return the UI elements for this module
tagList(
plotlyOutput(ns(scatter_name)),
plotlyOutput(ns(bar_name))
)
}
testServer <- function(id, scatter_name, bar_name) {
moduleServer(
id,
function(input, output, session) {
output[[scatter_name]] = renderPlotly({
# req(selected_bars()) # This causes the entire app to fail to load if it is included
if(length(selected_bars()) == 0) {
iris %>%
plot_ly(
type = 'scatter',
mode = 'markers',
x = ~Sepal.Length,
y = ~Sepal.Width
) %>%
# Causes an error
partial_bundle(type = 'cartesian')
} else {
iris %>%
filter(Species %in% selected_bars()) %>%
plot_ly(
type = 'scatter',
mode = 'markers',
x = ~Sepal.Length,
y = ~Sepal.Width,
color = ~Species
) %>%
layout(showlegend = TRUE) %>%
# Does not cause an error
partial_bundle(type = 'cartesian')
}
})
output[[bar_name]] = renderPlotly({
dummy_data %>%
group_by(Species) %>%
summarise(
bar_val = mean(y)
) %>%
arrange(Species) %>% # This is required to mitigate issue #1657
plot_ly(
type = 'bar',
source = bar_name,
x = ~factor(Species, levels = Species[order(-bar_val)]),
y = ~bar_val,
opacity = ifelse(
.$Species %in% selected_bars() | length(selected_bars()) == 0,
1,
.2
),
split = ~Species,
showlegend = FALSE
)
})
# Track what bar(s) the user has selected via click
selected_bars = reactiveVal(value = character(), label = 'selected_bars')
mod_issue_bar_click = reactive({
event_data(event = 'plotly_click', source = bar_name, priority = 'event')$x
})
observeEvent(mod_issue_bar_click(), {
if(! mod_issue_bar_click() %in% selected_bars()) {
selected_bars(
c(
selected_bars(),
mod_issue_bar_click()
)
)
} else {
selected_bars(
selected_bars()[selected_bars() != mod_issue_bar_click()]
)
}
})
}
)
}
shinyApp(
ui = fluidPage(
testUI(
'test',
scatter_name = 'test_line',
bar_name = 'test_bar'
),
hr(), # Visually separates outputs from the module and those not from the module
plotlyOutput('dummy_plot')
# ,
# plotOutput('dummy_plot2')
),
server = function(input, output, session) {
testServer(
'test',
scatter_name = 'test_line',
bar_name = 'test_bar'
)
output$dummy_plot = renderPlotly({
iris %>%
plot_ly(
type = 'scatter',
mode = 'markers',
x = ~Sepal.Length,
y = ~Sepal.Width
)
})
# output$dummy_plot2 = renderPlot({
# plot(
# x = iris$Sepal.Length,
# y = iris$Sepal.Width,
# type = 'b'
# )
# })
}
)
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
首先运行提供的 Shiny 复现,并通过 renderPlotly() 和 partial_bundle(type = 'cartesian') 跟踪第一个模块输出。当应用能够渲染两个模块图表,且不会因 Plotly 产生 Uncaught ReferenceError 时,修复就完成了;即使第一个图表使用 partial_bundle(),并且最初没有显示其他输出,也必须如此。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- javascript, plotly, r
- 领域
- data-visualization, frontend
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100