Flexdashboard无Shiny用Crosstalk下拉加载本地PNG报错求助
解决方案
报错原因
- 首次报错是因为
readPNG仅支持接收字符串格式的图片路径,无法识别Crosstalk的SharedData对象,且该函数为R端静态执行函数,渲染完成后就不再响应前端交互,自然无法跟随下拉选择切换图片。 - 第二次报错是因为
knitr::include_graphics的第二个入参为dpi参数,你传入的列名公式参数位置匹配错误,且该函数同样是静态渲染函数,不支持响应Crosstalk的前端筛选逻辑。
可行实现方案
Crosstalk的交互逻辑完全在前端JS侧执行,因此需要搭配支持Crosstalk联动的前端组件实现图片切换,我们可以用reactable作为图片渲染载体,它原生支持Crosstalk筛选,无需Shiny支持即可生成纯静态HTML页面。
依赖安装
如果未安装对应依赖先执行安装:
install.packages(c("crosstalk", "tidyverse", "reactable", "htmltools"))
完整代码
library(crosstalk) library(tidyverse) library(reactable) library(htmltools) # 读取plots目录下所有png路径 df <- list.files("plots/", pattern = "\\.png$", full.names = TRUE) %>% as_tibble() %>% set_names("path") %>% # 提取不含后缀的文件名作为下拉选项的显示名称,可根据需求调整 mutate(show_name = str_remove(basename(path), "\\.png$")) # 初始化Crosstalk共享数据 shared_data <- SharedData$new(df, key = ~path) # 定义下拉选择组件 select_widget <- filter_select( id = "png_select", label = "选择图表", sharedData = shared_data, group = ~show_name, multiple = FALSE # 设为仅单选 ) # 定义图片展示组件,用reactable承接Crosstalk筛选结果,仅渲染图片 display_widget <- reactable( shared_data, columns = list( path = colDef( name = "", # 隐藏列头 # 把路径渲染为img标签 cell = function(path) tags$img(src = path, width = "100%", style = "max-height: 80vh; object-fit: contain;") ), show_name = colDef(show = FALSE) # 隐藏文件名列 ), # 隐藏所有不需要的表格UI元素 pagination = FALSE, searchable = FALSE, bordered = FALSE, striped = FALSE, highlight = FALSE, showSortIcon = FALSE, showPageInfo = FALSE ) # 组装布局 bscols( widths = c(3, 9), select_widget, display_widget )
注意事项
- 生成的HTML文件需要和
plots文件夹放在同一级目录下,相对路径才能正常读取图片,打开静态HTML即可直接使用,无需任何服务端支持。 - 如果需要调整图片大小,修改
tags$img里的width、height、max-height参数即可。
内容的提问来源于stack exchange,提问作者Forge
相关产品推荐
相关产品推荐

