如何通过JavaScript切换Highcharts Sankey链接、节点及标签显隐
Highcharts桑基图节点/链接/标签显隐切换实现问题
需求
需要实现Sankey(桑基图)的链接、关联节点、标签的显隐切换功能,支持用户点击节点时逐步展开内容:图表完全展开后约有5个层级、10列,首次加载默认视图展示6列、4个层级。
目前梳理的三个实现方案
- 方案一:操作源数据将需要隐藏的链接权重设为0,可同时隐藏节点、链接、标签三类元素
- 方案二:给目标节点添加自定义className,通过设置CSS属性
display: none实现隐藏,暂未验证该方案是否能同时对三类元素生效 - 方案三:参考组织图节点显隐切换的同类问题解法,将逻辑适配到桑基图场景
各方案的现存问题
已经实测过方案一,确实可以同时隐藏三类元素,但该方案每次操作都需要查询数据库、调用API修改JSON数据并重载重绘图表,担心API调用过于频繁,希望找到更优的实现方式。
和方案三相比,方案二逻辑更清晰,对CSS的熟悉度高于highcharts.js,但本身也倾向尽量避免堆叠冗余样式。
方案三实现起来比较繁琐,需要深入了解对应库的运行逻辑,如果确认是最优方案也可以投入时间学习,但目前找到的参考示例运行效果并不理想。
选型要求
寻找最优解决方案,需要尽可能减少定制开发工作量,同时兼容原有功能,保证export.js导出、响应式设计等能力不受显隐逻辑影响。
目标效果对应的实现代码片段如下:
JavaScript代码
var nodes = [{ id: 'Col_1-Row_1', column: 1 }, ], data0 = [ // 默认状态下数据权重设为0,对应链接隐藏 ['Col_0-Row_0', 'Col_1-Row_0', 0], ['Col_0-Row_1', 'Col_1-Row_0', 0], // 默认展示的数据 ['Col_1-Row_0', 'Col_2-Row_0', 153], ['Col_1-Row_1', 'Col_2-Row_0', 91], ['Col_1-Row_1', 'Col_2-Row_0', 221], ['Col_1-Row_1', 'Col_2-Row_0', 200], // 循环链接 ['Col_2-Row_0', 'Col_1-Row_1', 10], ], data1 = [ ['Col_0-Row_0', 'Col_1-Row_0', 0.1], ['Col_0-Row_1', 'Col_1-Row_0', 152.9], ['Col_1-Row_0', 'Col_2-Row_0', 153], ['Col_1-Row_1', 'Col_2-Row_0', 91], ['Col_1-Row_1', 'Col_2-Row_0', 221], ['Col_1-Row_1', 'Col_2-Row_0', 200], ['Col_2-Row_0', 'Col_1-Row_1', 10], ] const chart = Highcharts.chart('container', { chart: { height: (9 / 16 * 80) + "%", marginBottom: 60, // 展示循环链接 marginRight: 60 // 展示循环链接 }, title: { text: '桑基图链接显隐切换' }, plotOptions: { series: { animation: false, minLinkWidth: 1, nodePadding: 50, colors: ['#0dcaf0'], clip: false, // 展示循环链接 dataLabels: { enabled: true, // 设置数据标签位置 align: "left", verticalAlign: "top", y: -20, x: -5, // 允许标签重叠展示 allowOverlap: true, padding: 0, // 允许标签超出绘图区域展示 overflow: "allow", crop: false, style: { fontSize: "12px", fontFamily: "Arial, sans-serif", color: "black", }, }, }, }, series: [{ data: data0, nodes: nodes, type: 'sankey', }, { data: data1, nodes: nodes, visible: false, type: 'sankey', }] });
CSS代码
#container { height: 90hw; margin: 1em auto; }
HTML代码
<script src="https://code.highcharts.com/highcharts.js"></script> <script src="https://code.highcharts.com/modules/sankey.src.js"></script> <script src="https://code.highcharts.com/modules/exporting.js"></script> <script src="https://code.highcharts.com/modules/accessibility.js"></script> <button id="btn_show" class="autocompare">展开</button> <button id="btn_hide" class="autocompare">收起</button> <div id="container"></div> <script> document.getElementById('btn_show').addEventListener('click', e => { seriesHide(); seriesShow(1); }); document.getElementById('btn_hide').addEventListener('click', e => { seriesHide(); seriesShow(0); }); function seriesHide() { chart.series.forEach(ser => ser.hide()) } function seriesShow(i) { var series = chart.series[i]; series.show(); } </script>
内容的提问来源于stack exchange,提问作者Vikero
相关产品推荐
相关产品推荐

