vis.js Network hierarchical布局异常 设LR方向仍显示竖向单线
vis.js 分层布局渲染为单条竖直线问题
问题描述
实现vis.js hierarchical(分层)网络示例时,预期图形按从左到右方向展示,但实际整体渲染为单条竖直线,调整多种配置参数都无法得到正确效果。
复现代码如下:
// create an array with nodes var nodes = new vis.DataSet( [ { id: 1, value: 21, label: 'GR' }, { id: 12, value: 10, label: 'PL' }, { id: 18, value: 28, label: 'MM' }, { id: 22, value: 12, label: 'I_STORE_LOCATOR' }, { id: 23, value: 18, label: 'SL' }, { id: 29, value: 3, label: 'I_PRICEMATCH' }, { id: 30, value: 6, label: 'PM' } ] ); // create an array with edges var edges = new vis.DataSet( [ {id: 13, eLabel: 100, arrows: "to", from: 1, to: 12, }, {id: 26, eLabel: 100, arrows: "to", from: 1, to: 18, }, {id: 17, eLabel: 100, arrows: "to", from: 12, to: 1, }, {id: 32, eLabel: 60, arrows: "to", from: 18, to: 22, }, {id: 47, eLabel: 60, arrows: "to", from: 18, to: 23, }, {id: 53, eLabel: 30, arrows: "to", from: 18, to: 29, }, {id: 62, eLabel: 30, arrows: "to", from: 18, to: 30, }, {id: 34, eLabel: 120, arrows: "to", from: 22, to: 23, }, {id: 40, eLabel: 60, arrows: "to", from: 23, to: 22, }, {id: 43, eLabel: 120, arrows: "to", from: 23, to: 18, }, {id: 55, eLabel: 30, arrows: "to", from: 29, to: 30, }, {id: 58, eLabel: 60, arrows: "to", from: 30, to: 18, } ] ); // create a network var container = document.getElementById("mynetwork"); var treeData = { nodes: nodes, edges: edges, }; let options = { "layout": { "randomSeed": 2345, "improvedLayout":true, "clusterThreshold": 150, "hierarchical": { "enabled":true, "levelSeparation": 150, "nodeSpacing": 100, "treeSpacing": 200, "blockShifting": true, "edgeMinimization": true, "parentCentralization": true, "direction": 'LR', // UD, DU, LR, RL "sortMethod": 'directed', // hubsize, directed "shakeTowards": 'leaves' // roots, leaves } } }; var network = new vis.Network(container, treeData, options); network.on('click', function (properties) { var ids = properties.nodes; // ids is an array, loop through the items for (let i = 0; i < ids.length; i++){ treeData.nodes.update({id:ids[i],hidden:true}) } });
#mynetwork { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/9.1.2/standalone/umd/vis-network.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/vis-network/9.1.2/dist/dist/vis-network.min.css" rel="stylesheet"/> <div id="mynetwork"></div>
问题原因
配置本身无语法错误,核心问题是边数据存在多组双向循环引用,配合sortMethod: 'directed'配置时,vis分层布局算法无法正确判定节点层级归属,最终所有节点被判定到同一纵向层级,渲染为单条竖直线。
现有边中的循环引用包括:
- 节点1与节点12双向连接
- 节点18与节点23双向连接
- 节点22与节点23双向连接
- 节点18与节点30双向连接
这些循环会直接打断有向分层的层级计算逻辑。
解决方法
根据实际需求二选一即可:
方案1:保留有向分层逻辑,手动指定节点层级
如果需要使用directed排序的分层布局,手动给每个节点添加level属性明确所属层级,跳过算法自动判定环节即可,示例修改:
var nodes = new vis.DataSet( [ { id: 1, value: 21, label: 'GR', level: 0 }, { id: 12, value: 10, label: 'PL', level: 1 }, { id: 18, value: 28, label: 'MM', level: 1 }, { id: 22, value: 12, label: 'I_STORE_LOCATOR', level: 2 }, { id: 23, value: 18, label: 'SL', level: 2 }, { id: 29, value: 3, label: 'I_PRICEMATCH', level: 2 }, { id: 30, value: 6, label: 'PM', level: 2 } ] );
指定level后,direction: 'LR'配置会正常生效,图形按从左到右的层级排布。
方案2:无需严格有向分层,修改排序规则
如果不需要严格按照边方向判定层级,将sortMethod从directed改为hubsize,算法会根据节点连接数自动排布,不会出现单条直线问题:
"hierarchical": { "enabled":true, "levelSeparation": 150, "nodeSpacing": 100, "treeSpacing": 200, "blockShifting": true, "edgeMinimization": true, "parentCentralization": true, "direction": 'LR', "sortMethod": 'hubsize', // 修改为按节点连接数排序 "shakeTowards": 'leaves' }
内容的提问来源于stack exchange,提问作者user3617762
相关产品推荐
相关产品推荐

