You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:12:24