如何基于echarts4r的e_datazoom实现Shiny表格联动筛选?
问题描述
原本在Shiny应用中通过ggplot的input$brush实现刷选图表点后展示对应详情表格,功能正常。现在将图表切换为echarts4r,需要保留相同功能——基于e_datazoom的筛选结果生成对应表格,但未找到实现方法。
原ggplot表格代码:
output$plot_brushed_points <- render_gt({ dat<-dft()%>% select(c(4,8:16,18:19,21:38)) dat<-dat %>% mutate(across(where(is.numeric) & !(c("ODDS1","ODDS2","ODDS3")), ~ round(.x, 3))) res<- brushedPoints(dat,input$brush) gt(res) %>% opt_interactive() %>% tab_header(md("**In-depth parameter details**")) %>% tab_options(table.width = pct(100), container.width = pct(150)) })
原echarts4r图表代码:
output$plotui1<- renderEcharts4r({ g1<- dft() %>% select(x=xvar(),y=yvar(),sz=sz(),FSCORE, HOME,AWAY) %>% group_by(FSCORE) %>% mutate(game=paste(HOME,AWAY,sep="-")) %>% e_charts(x) %>% e_scatter(y,sz,bind = game,symbol_size = 2) %>% e_tooltip(formatter=htmlwidgets::JS(" function(params){ var vals = params.name.split('-') return('<strong>' + vals[0] + '-'+ vals[1] + '</strong><br />xvar(): ' + params.value[0] + '<br />yvar(): ' + params.value[1] + '<br />sz():' +params.value[2]) }")) %>% e_datazoom() %>% e_zoom( dataZoomIndex = 1 ) %>% e_legend(bottom = 0) g1 })
实现方法
步骤1:给echarts4r图表添加datazoom事件监听
修改echarts4r代码,添加e_on监听datazoom事件,将筛选的x轴范围发送到Shiny的输入对象:
output$plotui1<- renderEcharts4r({ g1<- dft() %>% select(x=xvar(),y=yvar(),sz=sz(),FSCORE, HOME,AWAY) %>% group_by(FSCORE) %>% mutate(game=paste(HOME,AWAY,sep="-")) %>% e_charts(x) %>% e_scatter(y,sz,bind = game,symbol_size = 2) %>% e_tooltip(formatter=htmlwidgets::JS(" function(params){ var vals = params.name.split('-') return('<strong>' + vals[0] + '-'+ vals[1] + '</strong><br />xvar(): ' + params.value[0] + '<br />yvar(): ' + params.value[1] + '<br />sz():' +params.value[2]) }")) %>% e_datazoom() %>% e_zoom( dataZoomIndex = 1 ) %>% e_legend(bottom = 0) %>% # 添加datazoom事件监听 e_on("datazoom", htmlwidgets::JS(" function(params) { // 获取datazoom的百分比范围 var startPct = params.batch[0].start; var endPct = params.batch[0].end; // 获取x轴的所有数据点 var xData = this.getOption().xAxis[0].data; // 计算对应位置的x值 var xStart = xData[Math.floor(startPct / 100 * xData.length)]; var xEnd = xData[Math.ceil(endPct / 100 * xData.length) - 1]; // 将范围发送到Shiny输入 Shiny.setInputValue('echarts_zoom_range', {x_min: xStart, x_max: xEnd}); } ")) g1 })
步骤2:修改表格渲染逻辑,基于zoom范围筛选数据
替换原brushedPoints逻辑,改用input$echarts_zoom_range中的范围筛选数据:
output$plot_brushed_points <- render_gt({ # 确保zoom范围输入存在 req(input$echarts_zoom_range) dat <- dft() %>% select(c(4,8:16,18:19,21:38)) %>% mutate(across(where(is.numeric) & !(c("ODDS1","ODDS2","ODDS3")), ~ round(.x, 3))) # 获取图表使用的x轴变量名 x_col <- xvar() # 根据zoom范围筛选数据 res <- dat %>% filter(!!sym(x_col) >= input$echarts_zoom_range$x_min, !!sym(x_col) <= input$echarts_zoom_range$x_max) gt(res) %>% opt_interactive() %>% tab_header(md("**In-depth parameter details**")) %>% tab_options(table.width = pct(100), container.width = pct(150)) })
注意事项
- 如果需要基于y轴datazoom筛选,只需修改事件监听中的代码,改为获取y轴数据并计算范围,同时调整表格筛选逻辑中的列名。
- 确保
xvar()返回的变量名与dat数据框中的列名完全一致,否则筛选会失效。 req(input$echarts_zoom_range)用于避免初始状态下因无输入导致的报错。
内容的提问来源于stack exchange,提问作者M.O
相关产品推荐
相关产品推荐

