如何为Plotly高亮/Selectize菜单添加自定义JavaScript调用?
解决方案:同步Plotly主图Selectize菜单/Highlight与副图、表格的筛选
一、捕获主图Selectize菜单的变更事件
主图顶部的Selectize菜单是Plotly自动生成的,需要定位其DOM元素并绑定变更事件,以此触发副图和表格的筛选同步。
实现步骤
- 给副图、表格的
filter_select设置唯一ID,方便后续JS定位:
# 副图的隐藏筛选器 sub_filter <- crosstalk::filter_select( id = "subplot-filter", label = "", sharedData = sub_shared, group = ~主键 ) # 表格的隐藏筛选器 table_filter <- crosstalk::filter_select( id = "table-filter", label = "", sharedData = table_shared, group = ~主键 )
- 编写JS代码监听主图Selectize菜单的
change事件,同步更新隐藏筛选器:
document.addEventListener('DOMContentLoaded', function() { // 定位主图的Selectize下拉框 const mainSelect = document.querySelector('.plotly-selectize select'); if (mainSelect) { mainSelect.addEventListener('change', function() { const selectedKey = this.value; // 同步副图筛选器 const subFilter = document.querySelector('#subplot-filter select'); if (subFilter) { subFilter.value = selectedKey; // 手动触发change事件让Crosstalk生效 subFilter.dispatchEvent(new Event('change')); } // 同步表格筛选器 const tableFilter = document.querySelector('#table-filter select'); if (tableFilter) { tableFilter.value = selectedKey; tableFilter.dispatchEvent(new Event('change')); } }); } });
二、捕获主图Highlight事件
Plotly的高亮操作触发的是plotly_selected事件(而非plotly_click),需监听该事件完成同步。
实现步骤
- 主图创建时,将主键存入
customdata字段,方便事件中获取:
main_plot <- plot_ly( main_shared, x = ~x, y = ~y, customdata = ~主键, type = "scatter", mode = "markers" ) %>% highlight_key(~主键) %>% highlight("plotly_selected", dynamic = TRUE)
- 编写JS代码监听
plotly_selected事件:
document.addEventListener('DOMContentLoaded', function() { const mainPlot = document.querySelector('.plotly'); if (mainPlot) { mainPlot.on('plotly_selected', function(eventData) { if (eventData.points.length > 0) { // 取第一个选中点的主键(多选场景可调整为批量处理) const selectedKey = eventData.points[0].customdata; // 复用之前的同步逻辑 const subFilter = document.querySelector('#subplot-filter select'); if (subFilter) { subFilter.value = selectedKey; subFilter.dispatchEvent(new Event('change')); } const tableFilter = document.querySelector('#table-filter select'); if (tableFilter) { tableFilter.value = selectedKey; tableFilter.dispatchEvent(new Event('change')); } } }); } });
三、整合与优化
- 将两段JS代码合并到同一个
htmltools::tags$script()标签中,确保DOM加载完成后执行。 - 若支持多选,需给
filter_select设置multiple = TRUE,并在JS中将多个选中主键用逗号分隔后赋值。 - 添加CSS隐藏副图和表格的筛选器:
htmltools::tags$style(HTML(" #subplot-filter, #table-filter { display: none; } "))
内容的提问来源于stack exchange,提问作者dkysh
相关产品推荐
相关产品推荐

