Plotly堆叠百分比图自定义悬停:按类别高亮同色分段
解决方案
要实现堆叠百分比条形图中悬停时高亮同group2类别的所有分段并显示对应百分比,需结合自定义悬停模板和JavaScript事件处理来实现,具体修改如下:
1. 修正悬停模板
先修正hovertemplate,确保正确展示分组信息与百分比数值。
2. 添加自定义高亮逻辑
借助htmlwidgets::onRender注入JavaScript代码,监听悬停事件,匹配同group2的所有条形分段并高亮显示。
完整代码
library(dplyr) library(plotly) library(htmlwidgets) dat <- data.frame(group1=(rep(letters[1:4], each=5)), group2=rep(LETTERS[1:5], times=4), pct = c(rep(.2, times=5), c(.1, .1, .1, .3, .4), c(.2, .2, .2, .3, .1), c(.3, .1, .2, .2, .2)) ) dat %>% plot_ly() %>% add_bars(x=~pct, y=~group1, color=~group2, customdata = ~group2, hovertemplate = paste0( "Group1: %{y}<br>", "Group2: %{customdata}<br>", "百分比: %{x:.2%}<extra></extra>" ), opacity = 1 # 初始透明度 ) %>% layout(yaxis = list(title = 'Group 1', autorange='reversed', categoryorder='trace'), xaxis = list(title = 'Percent', tickformat = ".0%"), barmode = 'stack', hovermode = 'closest', # 仅触发当前悬停的分段 legend = list(traceorder = "normal")) %>% config(displaylogo = FALSE) %>% # 注入JS实现同类别高亮 onRender(" function(el, x) { var traces = el.data; // 监听悬停事件 el.on('plotly_hover', function(data) { if(data.points.length === 0) return; var targetGroup = data.points[0].customdata; // 遍历所有trace设置透明度 traces.forEach(function(trace) { trace.opacity = trace.name === targetGroup ? 1 : 0.2; }); Plotly.update(el, {data: traces}, {}, [0,1,2,3,4]); }); // 监听离开事件,恢复初始透明度 el.on('plotly_unhover', function() { traces.forEach(function(trace) { trace.opacity = 1; }); Plotly.update(el, {data: traces}, {}, [0,1,2,3,4]); }); } ")
代码说明
hovermode = 'closest':确保仅触发当前鼠标悬停的单个条形分段,而非整个y轴分组。- 修正后的
hovertemplate:清晰展示当前分段的group1、group2分类及百分比数值。 - JavaScript部分:
- 监听
plotly_hover事件,获取当前悬停分段的group2类别,将同类别trace设为完全不透明,其他设为半透明实现高亮。 - 监听
plotly_unhover事件,鼠标离开时恢复所有trace的初始透明度。
- 监听
内容的提问来源于stack exchange,提问作者prizzlywizzly
相关产品推荐
相关产品推荐

