
Plotly Sankey 图不支持直接为 node.hovertemplate 传入字符串数组,但可通过 customdata + 单一 hovertemplate 模板实现每个节点独立的悬停内容。本文详解该兼容方案,并提供可运行示例与关键注意事项。
plotly sankey 图不支持直接为 `node.hovertemplate` 传入字符串数组,但可通过 `customdata` + 单一 `hovertemplate` 模板实现每个节点独立的悬停内容。本文详解该兼容方案,并提供可运行示例与关键注意事项。
在 Plotly 的 Sankey 图中,开发者常希望为不同节点(如“A1”“B2”等)配置差异化的悬停提示信息(例如显示特定 ID、描述或指标)。直觉上,将 hovertemplate 设为字符串数组(如 ["a", "b", "c", ...])看似合理——毕竟 label 和 color 均支持此类数组输入。但实际中,此写法会导致悬停信息完全消失,这是 Plotly 当前(截至 2023 年及后续多个版本)对 Sankey 节点/链接的已知限制:hovertemplate 不支持数组形式,即使官方文档未明确标注该限制。
✅ 正确解法是结合 customdata 与动态模板变量:
- 将各节点的自定义文本存入 node.customdata 数组(类型:string[] 或 number[]);
- 在 node.hovertemplate 中统一使用 '%{customdata}' 引用对应值;
- Plotly 会自动按索引匹配 customdata[i] 到第 i 个节点,实现逐节点定制。
以下是修正后的完整可运行代码示例:
var data = {
type: "sankey",
orientation: "h",
node: {
pad: 15,
thickness: 30,
line: {
color: "black",
width: 0.5,
},
label: ["A1", "A2", "B1", "B2", "C1", "C2"],
color: ["#4e79a7", "#f28e2c", "#e15759", "#76b7b2", "#59a14f", "#edc948"],
customdata: ["Node A1: Input Source", "Node A2: Backup Source",
"Node B1: Processor Alpha", "Node B2: Processor Beta",
"Node C1: Output Channel X", "Node C2: Output Channel Y"],
hovertemplate: '<b>%{label}</b><br>%{customdata}<extra></extra>'
},
link: {
source: [0, 1, 0, 2, 3, 3],
target: [2, 3, 3, 4, 4, 5],
value: [8, 4, 2, 8, 4, 2],
}
};
Plotly.react("myDiv", [data], {
title: "Sankey with Per-Node Custom Hover",
font: { size: 12 },
margin: { t: 40, b: 20 }
});
? 关键细节与最佳实践:
-
必须显式添加:否则 Plotly 默认会在悬停框底部追加 trace 名称和坐标信息,干扰自定义内容; -
支持富文本格式:hovertemplate 中可嵌入 HTML 标签(如 、
),提升可读性; - customdata 同样适用于 links:若需为连接线定制悬停(如显示流量百分比),可在 link.customdata 中传入数组,并在 link.hovertemplate 中引用 '%{customdata}';
- 类型一致性:customdata 元素支持字符串、数字甚至对象(需配合 JSON.stringify() 在模板中处理),但建议优先使用字符串以确保渲染稳定;
- 调试技巧:若悬停仍不显示,请检查浏览器控制台是否有 Plotly: Invalid hovertemplate 报错,并确认 customdata 长度与 label 严格一致。
该方案不仅规避了 hovertemplate 数组的兼容性缺陷,还保持了代码清晰性与扩展性,是当前 Plotly Sankey 图实现精细化交互体验的推荐实践。










