如何判断Highcharts打包气泡图中是否点击/悬浮自定义中心图例?
解决Packed Bubble图中心标签的事件冲突问题
当前自定义的中心系列标签在点击或悬浮时,会触发下方子气泡的tooltip和点击事件,可通过以下方式实现中心标签的独立交互:
核心思路
- 给中心标签添加事件监听,阻止事件冒泡,避免触发下方气泡的交互逻辑
- 自定义tooltip内容,hover中心标签时展示系列专属信息
- 给中心标签绑定独立的点击事件,执行自定义操作
修改后的完整代码
(function(H) { H.addEvent(H.Series, 'afterDrawDataLabels', function(e) { const series = this; const chart = series.chart; if (!series.parentNode.plotX || chart.options.chart.type !== 'packedbubble') { return; } if (!series.customLabel) { series.customLabel = series.chart.renderer.label( series.name, null, 'rect' ) .attr({ align: 'center', fill: 'rgba(255, 255, 255, 0.7)', zIndex: 3, shape: 'rect', cursor: 'pointer' // 鼠标悬浮显示手型,提示可交互 }) .css({ color: 'black', fontSize: '12px', fontWeight: 'bold', whiteSpace: 'nowrap', padding: '5px', borderRadius: '5px', textOverflow: 'ellipsis', width: series.parentNode.graphic.width }) // 添加鼠标事件监听 .on('mouseover', function(e) { e.stopPropagation(); // 计算系列总排放量 const totalValue = series.data.reduce((sum, point) => sum + point.value, 0); // 刷新tooltip显示系列信息 chart.tooltip.refresh({ name: series.name, value: totalValue, // 自定义tooltip格式,和点的tooltip区分开 tooltipFormatter: () => `<b>${series.name}:</b> ${totalValue}m CO<sub>2</sub>` }); }) .on('mouseout', function() { chart.tooltip.hide(); }) .on('click', function(e) { e.stopPropagation(); const totalValue = series.data.reduce((sum, point) => sum + point.value, 0); alert(`点击了${series.name}\n总排放量:${totalValue}m CO2`); }) .add(); } series.customLabel.attr({ x: series.parentNode.plotX + chart.plotLeft, y: series.parentNode.plotY + chart.plotTop - 10 }); }); }(Highcharts)); Highcharts.chart('container', { chart: { type: 'packedbubble', height: '100%' }, title: { text: 'Carbon emissions around the world (2014)', align: 'left' }, tooltip: { useHTML: true, // 动态判断tooltip内容 formatter: function() { if (this.point.tooltipFormatter) { return this.point.tooltipFormatter(); } return `<b>${this.point.name}:</b> ${this.point.value}m CO<sub>2</sub>`; } }, plotOptions: { packedbubble: { minSize: '20%', events: { click: () => alert("hello"), }, maxSize: '100%', zMin: 0, zMax: 1000, layoutAlgorithm: { gravitationalConstant: 0.05, splitSeries: true, seriesInteraction: false, dragBetweenSeries: true, parentNodeLimit: true }, dataLabels: { enabled: true, format: '{point.name}', filter: { property: 'y', operator: '>', value: 250 }, style: { color: 'black', textOutline: 'none', fontWeight: 'normal' } } } }, series: [{ name: 'Europe 1234432222 1234432222 1234432222 1234432222 1234432222', data: [{ name: 'Germany', value: 767.1 }, { name: 'Croatia', value: 20.7 }, { name: 'Belgium', value: 97.2 }, { name: 'Czech Republic', value: 111.7 }, { name: 'Netherlands', value: 158.1 }, { name: 'Spain', value: 241.6 }, { name: 'Ukraine', value: 249.1 }, { name: 'Poland', value: 298.1 }, { name: 'France', value: 323.7 }, { name: 'Romania', value: 78.3 }, { name: 'United Kingdom', value: 415.4 }, { name: 'Turkey', value: 353.2 }, { name: 'Italy', value: 337.6 }, { name: 'Greece', value: 71.1 }, { name: 'Austria', value: 69.8 }, { name: 'Belarus', value: 67.7 }, { name: 'Serbia', value: 59.3 }, { name: 'Finland', value: 54.8 }, { name: 'Bulgaria', value: 51.2 }, { name: 'Portugal', value: 48.3 }, { name: 'Norway', value: 44.4 }, { name: 'Sweden', value: 44.3 }, { name: 'Hungary', value: 43.7 }, { name: 'Switzerland', value: 40.2 }, { name: 'Denmark', value: 40 }, { name: 'Slovakia', value: 34.7 }, { name: 'Ireland', value: 34.6 }, { name: 'Croatia', value: 20.7 }, { name: 'Estonia', value: 19.4 }, { name: 'Slovenia', value: 16.7 }, { name: 'Lithuania', value: 12.3 }, { name: 'Luxembourg', value: 10.4 }, { name: 'Macedonia', value: 9.5 }, { name: 'Moldova', value: 7.8 }, { name: 'Latvia', value: 7.5 }, { name: 'Cyprus', value: 7.2 } ] }, { name: 'Long word 1234432222 1234432222 1234432222 1234432222 1234432222', data: [{ name: 'Senegal', value: 8.2 }, { name: 'Cameroon', value: 9.2 }, { name: 'Zimbabwe', value: 13.1 }, { name: 'Ghana', value: 14.1 }, { name: 'Kenya', value: 14.1 }, { name: 'Sudan', value: 17.3 }, { name: 'Tunisia', value: 24.3 }, { name: 'Angola', value: 25 }, { name: 'Libya', value: 50.6 }, { name: 'Ivory Coast', value: 7.3 }, { name: 'Morocco', value: 60.7 }, { name: 'Ethiopia', value: 8.9 }, { name: 'United Republic of Tanzania', value: 9.1 }, { name: 'Nigeria', value: 93.9 }, { name: 'South Africa', value: 392.7 }, { name: 'Egypt', value: 225.1 }, { name: 'Algeria', value: 141.5 } ] }] });
.highcharts-figure, .highcharts-data-table table { min-width: 320px; max-width: 800px; margin: 1em auto; } .highcharts-data-table table { font-family: Verdana, sans-serif; border-collapse: collapse; border: 1px solid #ebebeb; margin: 10px auto; text-align: center; width: 100%; max-width: 500px; } .highcharts-data-table caption { padding: 1em 0; font-size: 1.2em; color: #555; } .highcharts-data-table th { font-weight: 600; padding: 0.5em; } .highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption { padding: 0.5em; } .highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) { background: #f8f8f8; } .highcharts-data-table tr:hover { background: #f1f7ff; }
<script src="https://code.highcharts.com/highcharts.js"></script> <script src="https://code.highcharts.com/highcharts-more.js"></script> <script src="https://code.highcharts.com/modules/series-label.js"></script> <div id="container"></div>
关键代码说明
- 阻止事件冒泡:在
mouseover和click事件中调用e.stopPropagation(),确保点击/悬浮中心标签时,事件不会传递到下方的子气泡元素,避免触发子气泡的tooltip和点击事件。 - 自定义tooltip:在
mouseover时,计算系列的总排放量,通过chart.tooltip.refresh()显示自定义的tooltip内容;同时修改全局tooltip的formatter方法,区分系列标签和子气泡的tooltip格式。 - 中心标签交互优化:给标签添加
cursor: pointer样式,提示用户该元素可交互;绑定独立的点击事件,展示系列的汇总信息。
内容的提问来源于stack exchange,提问作者Ant's
相关产品推荐
相关产品推荐

