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

如何让R Shiny应用点击多个饼图区块均可渲染对应关联数据表

实现方案

调整逻辑如下:

  • 利用Plotly点击事件返回的curveNumber字段区分点击来源:Plotly按输出渲染顺序给每个图表分配编号,先渲染的myPlot(V3维度饼图)编号为0,后渲染的myPlot2(V2维度饼图)编号为1,通过该字段即可判断用户点击的是哪个饼图。
  • 用reactiveValues存储不同维度的筛选条件,避免原代码中在观察器内嵌套渲染DT的低效写法,逻辑更清晰。
  • 可自由配置筛选逻辑:支持仅生效最新点击的条件,或叠加多个饼图的筛选条件同时生效,也可扩展支持单个饼图多选区块。
完整可运行代码
library(shiny)
library(plotly)
library(data.table)
library(DT)

df <- structure(list(V1 = c("PM00FQ01", "PM00GQ01", "PM00KQ02", "PM033Q01", "PM034Q01T", "PM155Q01", "PM155Q02D", "PM155Q03D", "PM155Q04T", "PM192Q01T", "PM273Q01T", "PM305Q01", "PM406Q01", "PM406Q02", "PM408Q01T", "PM411Q01", "PM411Q02", "PM420Q01T", "PM423Q01", "PM442Q02", "PM446Q01", "PM446Q02", "PM447Q01", "PM462Q01D", "PM464Q01T", "PM474Q01", "PM496Q01T", "PM496Q02", "PM559Q01", "PM564Q01", "PM564Q02", "PM571Q01", "PM603Q01T", "PM800Q01", "PM803Q01T", "PM828Q01", "PM828Q02", "PM828Q03", "PM903Q01", "PM903Q03", "PM905Q01T", "PM905Q02", "PM906Q01", "PM906Q02", "PM909Q01", "PM909Q02", "PM909Q03", "PM915Q01", "PM915Q02", "PM918Q01", "PM918Q02", "PM918Q05", "PM919Q01", "PM919Q02", "PM923Q01", "PM923Q03", "PM923Q04", "PM924Q02", "PM934Q01", "PM934Q02", "PM936Q01", "PM936Q02", "PM939Q01", "PM939Q02", "PM942Q01", "PM942Q02", "PM942Q03", "PM943Q01", "PM943Q02", "PM948Q01", "PM948Q02", "PM948Q03", "PM949Q01T", "PM949Q02T", "PM949Q03", "PM953Q02", "PM953Q03", "PM953Q04D", "PM954Q01", "PM954Q02", "PM954Q04", "PM955Q01", "PM955Q02", "PM955Q03", "PM957Q01", "PM957Q02", "PM957Q03", "PM961Q02", "PM961Q03", "PM961Q05", "PM967Q01", "PM967Q03T", "PM982Q01", "PM982Q02", "PM982Q03T", "PM982Q04", "PM985Q01", "PM985Q02", "PM985Q03", "PM991Q01", "PM991Q02D", "PM992Q01", "PM992Q02", "PM992Q03", "PM995Q01", "PM995Q02", "PM995Q03", "PM998Q02", "PM998Q04T"), V2 = c("space and shape", "space and shape", "space and shape", "space and shape", "space and shape", "change and relationships", "change and relationships", "change and relationships", "change and relationships", "change and relationships", "space and shape", "space and shape", "space and shape", "space and shape", "uncertainty and data", "quantity", "uncertainty and data", "uncertainty and data", "uncertainty and data", "quantity", "change and relationships", "change and relationships", "space and shape", "space and shape", "space and shape", "quantity", "quantity", "quantity", "quantity", "quantity", "uncertainty and data", "change and relationships", "quantity", "quantity", "uncertainty and data", "change and relationships", "uncertainty and data", "quantity", "change and relationships", "change and relationships", "quantity", "quantity", "quantity", "quantity", "quantity", "quantity", "change and relationships", "uncertainty and data", "change and relationships", "uncertainty and data", "uncertainty and data", "uncertainty and data", "quantity", "quantity", "quantity", "space and shape", "change and relationships", "quantity", "space and shape", "space and shape", "change and relationships", "change and relationships", "uncertainty and data", "uncertainty and data", "quantity", "change and relationships", "quantity", "change and relationships", "space and shape", "quantity", "quantity", "quantity", "space and shape", "space and shape", "space and shape", "uncertainty and data", "uncertainty and data", "uncertainty and data", "change and relationships", "change and relationships", "change and relationships", "uncertainty and data", "uncertainty and data", "uncertainty and data", "change and relationships", "change and relationships", "change and relationships", "change and relationships", "change and relationships", "uncertainty and data", "space and shape", "space and shape", "uncertainty and data", "uncertainty and data", "uncertainty and data", "uncertainty and data", "uncertainty and data", "quantity", "quantity", "space and shape", "space and shape", "space and shape", "space and shape", "change and relationships", "space and shape", "space and shape", "quantity", "change and relationships", "change and relationships"), V3 = c("Constructed Response Expert", "Constructed Response Manual", "Constructed Response Expert", "Simple Multiple Choice", "Constructed Response Auto-coded", "Constructed Response Expert", "Constructed Response Expert", "Constructed Response Expert", "Complex Multiple Choice", "Complex Multiple Choice", "Complex Multiple Choice", "Simple Multiple Choice", "Constructed Response Expert", "Constructed Response Expert", "Complex Multiple Choice", "Constructed Response Manual", "Simple Multiple Choice", "Complex Multiple Choice", "Simple Multiple Choice", "Constructed Response Manual", "Constructed Response Manual", "Constructed Response Expert", "Simple Multiple Choice", "Constructed Response Expert", "Constructed Response Auto-coded", "Constructed Response Manual", "Complex Multiple Choice", "Constructed Response Manual", "Simple Multiple Choice", "Simple Multiple Choice", "Simple Multiple Choice", "Simple Multiple Choice", "Complex Multiple Choice", "Simple Multiple Choice", "Constructed Response Auto-coded", "Constructed Response Expert", "Constructed Response Manual", "Constructed Response Manual", "Constructed Response Expert", "Constructed Response Manual", "Complex Multiple Choice", "Constructed Response Expert", "Simple Multiple Choice", "Constructed Response Expert", "Constructed Response Manual", "Simple Multiple Choice", "Constructed Response Expert", "Simple Multiple Choice", "Constructed Response Manual", "Simple Multiple Choice", "Simple Multiple Choice", "Simple Multiple Choice", "Constructed Response Manual", "Constructed Response Manual", "Simple Multiple Choice", "Simple Multiple Choice", "Constructed Response Expert", "Constructed Response Manual", "Constructed Response Manual", "Simple Multiple Choice", "Constructed Response Manual", "Constructed Response Expert", "Simple Multiple Choice", "Simple Multiple Choice", "Simple Multiple Choice", "Constructed Response Expert", "Constructed Response Manual", "Simple Multiple Choice", "Constructed Response Expert", "Simple Multiple Choice", "Constructed Response Manual", "Constructed Response Expert", "Complex Multiple Choice", "Complex Multiple Choice", "Constructed Response Expert", "Constructed Response Expert", "Constructed Response Manual", "Constructed Response Expert", "Constructed Response Manual", "Constructed Response Expert", "Constructed Response Expert", "Constructed Response Manual", "Constructed Response Expert", "Constructed Response Expert", "Simple Multiple Choice", "Simple Multiple Choice", "Constructed Response Manual", "Constructed Response Expert", "Simple Multiple Choice", "Constructed Response Expert", "Constructed Response Manual", "Complex Multiple Choice", "Constructed Response Manual", "Constructed Response Manual", "Complex Multiple Choice", "Simple Multiple Choice", "Simple Multiple Choice", "Simple Multiple Choice", "Constructed Response Manual", "Simple Multiple Choice", "Constructed Response Expert", "Constructed Response Manual", "Constructed Response Manual", "Constructed Response Expert", "Constructed Response Manual", "Constructed Response Expert", "Simple Multiple Choice", "Constructed Response Manual", "Complex Multiple Choice" ), V4 = c("Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male/Female voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice", "Male voice")), class = "data.frame", row.names = c(NA, -109L ))

setDT(df)
dtnum <- df[ , .N, by="V3"]
dtnum2 <- df[ , .N, by="V2"]
ui <- fluidPage(
  plotlyOutput("myPlot"),
  plotlyOutput("myPlot2"),
  DTOutput("mydt")
)

server <- function(input, output, session) {
  # 存储不同维度的筛选条件
  rv <- reactiveValues(filter_v2 = NULL, filter_v3 = NULL)
  
  # 监听所有饼图的点击事件
  observeEvent(event_data("plotly_click"), {
    d <- event_data("plotly_click")
    # 区分点击的饼图来源
    if (d$curveNumber == 0) {
      # 点击的是V3维度的饼图,如需每次点击清空其他维度筛选,可加 rv$filter_v2 <- NULL
      rv$filter_v3 <- d$customdata
    } else if (d$curveNumber == 1) {
      # 点击的是V2维度的饼图,如需每次点击清空其他维度筛选,可加 rv$filter_v3 <- NULL
      rv$filter_v2 <- d$customdata
    }
  })
  
  # 按选中条件过滤数据集
  filtered_df <- reactive({
    res <- df
    if (!is.null(rv$filter_v3)) {
      res <- res[V3 == rv$filter_v3]
    }
    if (!is.null(rv$filter_v2)) {
      res <- res[V2 == rv$filter_v2]
    }
    res
  })
  
  # 渲染数据表
  output$mydt <- renderDT({
    filtered_df()
  })
  
  # 渲染饼图逻辑和原有一致
  output$myPlot2 <- renderPlotly({
    plot_ly(dtnum2, labels = ~V2, values = ~N, type = 'pie', customdata = ~V2)
  }) 
  
  output$myPlot <- renderPlotly({
    plot_ly(dtnum, labels = ~V3, values = ~N, type = 'pie', customdata = ~V3)
  })
}

shinyApp(ui, server)
可选扩展:支持单个饼图多选区块

如果需要点击同一个饼图的多个区块、同时展示所有选中区块的对应数据,可修改筛选逻辑为存储向量,用%in%匹配:

# 修改observeEvent部分逻辑
observeEvent(event_data("plotly_click"), {
  d <- event_data("plotly_click")
  if (d$curveNumber == 0) {
    # 已选中则移除,未选中则添加
    if (d$customdata %in% rv$filter_v3) {
      rv$filter_v3 <- setdiff(rv$filter_v3, d$customdata)
    } else {
      rv$filter_v3 <- c(rv$filter_v3, d$customdata)
    }
  } else if (d$curveNumber == 1) {
    if (d$customdata %in% rv$filter_v2) {
      rv$filter_v2 <- setdiff(rv$filter_v2, d$customdata)
    } else {
      rv$filter_v2 <- c(rv$filter_v2, d$customdata)
    }
  }
})

# 修改过滤逻辑
filtered_df <- reactive({
  res <- df
  if (!is.null(rv$filter_v3) && length(rv$filter_v3) > 0) {
    res <- res[V3 %in% rv$filter_v3]
  }
  if (!is.null(rv$filter_v2) && length(rv$filter_v2) > 0) {
    res <- res[V2 %in% rv$filter_v2]
  }
  res
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 13:06:01