You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R的Crosstalk、Plotly和DT实现表格过滤Plotly图表而非高亮

实现DT表格选中后过滤Plotly图表(隐藏未选中数据+适配坐标轴)

修改思路

原代码依赖Crosstalk默认的高亮机制,要实现过滤效果,核心是让Plotly仅渲染选中行对应的数据集,而非全部数据加高亮。由于无法使用Shiny,我们借助Crosstalk的客户端事件监听,结合Plotly的动态渲染能力实现:

  • 利用Crosstalk的SharedData同步DT与Plotly的选中状态
  • 通过JavaScript监听Crosstalk的过滤事件,触发Plotly用过滤后的数据集重新渲染,自动适配坐标轴范围

修改后的完整代码

library(dplyr)
library(tidyr)
library(crosstalk)
library(plotly)
library(DT)
library(htmlwidgets)

# Wide格式数据
df_test1 <- data.frame(
  id = c("id1", "id2"),
  item1 = c(0, 4),
  item2 = c(3, 2),
  item3 = c(1, 4),
  item4 = c(3, 4),
  item5 = c(1, NA)
)

# 转换为Long格式
df_test2 <- 
  df_test1 %>%
  tidyr::pivot_longer(cols = item1:item5, names_to = "item", values_to = "value") %>%
  dplyr::mutate(item = as.factor(item)) %>%
  dplyr::mutate(value = factor(as.character(value), levels = c("0", "1", "2", "3", "4")))

# 创建共享数据对象,确保group名称一致以同步状态
sd1 <- SharedData$new(df_test1, key = ~id, group = "groupdata")
sd2 <- SharedData$new(df_test2, key = ~id, group = "groupdata")

# 初始化Plotly图表
p <- plot_ly(sd2, x = ~value, y = ~item, color = ~value, 
             type = 'scatter', mode = 'markers+lines',
             line = list(group = ~id), marker = list(size = 3),
             tooltip = c("x", "y", "id")) %>%
  layout(xaxis = list(position = "top", categoryorder = "array", categoryarray = c("0", "1", "2", "3", "4")),
         yaxis = list(categoryorder = "array", categoryarray = paste0("item", 1:5)))

# 添加客户端交互:监听Crosstalk过滤事件,动态更新Plotly数据
p <- p %>% onRender("
function(el, x) {
  // 获取Crosstalk共享组
  const sdGroup = crosstalk.group('groupdata');
  
  // 监听过滤事件(DT选中行时触发)
  sdGroup.on('filter', function() {
    // 获取过滤后的数据集
    const filteredData = sdGroup.data();
    
    // 重新组织Plotly所需的数据结构
    const trace = {
      x: filteredData.map(d => d.value),
      y: filteredData.map(d => d.item),
      color: filteredData.map(d => d.value),
      type: 'scatter',
      mode: 'markers+lines',
      line: {group: filteredData.map(d => d.id)},
      marker: {size: 3},
      hovertemplate: 'x: %{x}<br>y: %{y}<br>id: %{customdata}<extra></extra>',
      customdata: filteredData.map(d => d.id)
    };
    
    // 重新渲染Plotly图表,自动适配坐标轴
    Plotly.react(el, [trace], x.layout);
  });
}
")

# 组合图表与表格
bscols(p, datatable(sd1, selection = "multiple"))

关键修改点说明

  1. 替换ggplotly为plot_ly:更灵活地控制数据渲染逻辑,便于后续动态更新
  2. 添加onRender客户端脚本:监听Crosstalk的filter事件(当DT选中行时触发),获取过滤后的数据集并重新渲染Plotly图表
  3. 坐标轴自动适配:由于每次渲染仅使用选中数据,Plotly会自动调整x/y轴的显示范围,匹配当前选中数据的取值
  4. 保留多选中支持:DT设置selection = "multiple",支持同时选中多行进行过滤

内容的提问来源于stack exchange,提问作者Anthony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:35:07