AMCharts 5 仅为截断标签显示Tooltip问题求助
问题
我想实现类似AMCharts 5官方示例的效果,但仅让被截断的Y轴标签显示Tooltip。尝试用adapters实现后,发现Tooltip在鼠标离开时不会消失,请问问题出在哪里?
相关代码:
const yAxis = chart.yAxes.push( am5xy.CategoryAxis.new(root, { categoryField: 'category', renderer: am5xy.AxisRendererY.new(root, {}), }) ); const yRenderer = yAxis.get('renderer'); yRenderer.labels.template.setup = function (target) { target.set( 'background', am5.Rectangle.new(root, { fill: am5.color(0x000000), fillOpacity: 0, }) ); }; yRenderer.labels.template.setAll({ centerX: am5.p0, tooltipText: '{category}', oversizedBehavior: 'truncate', maxWidth: MAX_Y_LABEL_WIDTH, tooltipY: 1, }); yRenderer.labels.template.adapters.add('tooltip', (_, target) => { const width = target.width(); return am5.Tooltip.new(root, { pointerOrientation: 'vertical', forceHidden: width !== MAX_Y_LABEL_WIDTH, }); });
解决方法
你的问题出在每次调用adapter时都会创建新的Tooltip实例,旧的Tooltip没有被销毁或正确绑定到标签的交互逻辑上,导致鼠标离开时,新生成的Tooltip无法触发默认的隐藏行为,旧实例也可能残留。
正确的做法是给每个标签创建唯一的Tooltip实例,再动态控制它的显示/隐藏状态,而不是每次都生成新实例。以下是两种可行方案:
方案1:通过Adapter控制已有Tooltip的显示状态
先在标签初始化时创建Tooltip,再用Adapter修改其forceHidden属性:
const yAxis = chart.yAxes.push( am5xy.CategoryAxis.new(root, { categoryField: 'category', renderer: am5xy.AxisRendererY.new(root, {}), }) ); const yRenderer = yAxis.get('renderer'); yRenderer.labels.template.setup = function (target) { target.set( 'background', am5.Rectangle.new(root, { fill: am5.color(0x000000), fillOpacity: 0, }) ); // 初始化时为每个标签创建唯一的Tooltip target.set("tooltip", am5.Tooltip.new(root, { pointerOrientation: 'vertical', tooltipY: 1 })); }; yRenderer.labels.template.setAll({ centerX: am5.p0, tooltipText: '{category}', oversizedBehavior: 'truncate', maxWidth: MAX_Y_LABEL_WIDTH, }); // 通过Adapter控制Tooltip的显示状态,而非创建新实例 yRenderer.labels.template.adapters.add('tooltip', (tooltip, target) => { const width = target.width(); tooltip.set("forceHidden", width !== MAX_Y_LABEL_WIDTH); return tooltip; });
方案2:监听标签宽度变化控制Tooltip
直接监听标签的widthchanged事件,动态调整Tooltip的显示状态:
const yAxis = chart.yAxes.push( am5xy.CategoryAxis.new(root, { categoryField: 'category', renderer: am5xy.AxisRendererY.new(root, {}), }) ); const yRenderer = yAxis.get('renderer'); yRenderer.labels.template.setup = function (target) { target.set( 'background', am5.Rectangle.new(root, { fill: am5.color(0x000000), fillOpacity: 0, }) ); // 初始化Tooltip target.set("tooltip", am5.Tooltip.new(root, { pointerOrientation: 'vertical', tooltipY: 1, tooltipText: '{category}' })); // 监听宽度变化,控制Tooltip显示 target.events.on("widthchanged", (ev) => { const tooltip = ev.target.get("tooltip"); if (tooltip) { tooltip.set("forceHidden", ev.target.width() !== MAX_Y_LABEL_WIDTH); } }); }; yRenderer.labels.template.setAll({ centerX: am5.p0, oversizedBehavior: 'truncate', maxWidth: MAX_Y_LABEL_WIDTH, });
这两种方案都保证每个标签对应唯一的Tooltip实例,鼠标离开时能触发默认的隐藏逻辑,同时仅在标签被截断时显示Tooltip。
内容的提问来源于stack exchange,提问作者JoeClique
相关产品推荐
相关产品推荐

