求组织架构图,自动布局算法?

目前项目中需要用到组织架构图,但是数据量都比较大,目前大概两三千条吧,用到了市面上一些组件,虽然方便了开发,但是数据量大的话就很快,几乎没法用了,想着自己弄个一下,我的思路如下:

1、固定每个节点的大小,然后找一个自动布局算法,确定每个节点的坐标位置;
2、通过连线组件,把所有有关系的几点连接起来;
3、丰富一些其他操作,显示、隐藏、拖拽等;

想请问下有没有好用的布局算法呢?

阅读 1.1k
1 个回答

什么组织架构有几千条数据的……不会是把人员信息都放进来了吧。

简单用 AntV-G6紧凑树示例,改了个3000条数据的 Demo 也没有卡啊。

import G6 from '@antv/g6';

fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/algorithm-category.json')
  .then((res) => res.json())
  .then((jdata) => {
    const data = { id: 'demo', children: Array.from({ length: 100 }).map(() => genUuidList(jdata))}
    console.log('data',data, 'count_i', count_i)
    const container = document.getElementById('container');
    const width = container.scrollWidth;
    const height = container.scrollHeight || 500;
    const graph = new G6.TreeGraph({
      container: 'container',
      width,
      height,
      linkCenter: true,
      modes: {
        default: [
          {
            type: 'collapse-expand',
            onChange: function onChange(item, collapsed) {
              const data = item.getModel();
              data.collapsed = collapsed;
              return true;
            },
          },
          'drag-canvas',
          'zoom-canvas',
        ],
      },
      defaultNode: {
        size: 26,
        anchorPoints: [
          [0, 0.5],
          [1, 0.5],
        ],
      },
      defaultEdge: {
        type: 'cubic-vertical',
      },
      layout: {
        type: 'compactBox',
        direction: 'TB',
        getId: function getId(d) {
          return d.id;
        },
        getHeight: function getHeight() {
          return 16;
        },
        getWidth: function getWidth() {
          return 16;
        },
        getVGap: function getVGap() {
          return 80;
        },
        getHGap: function getHGap() {
          return 20;
        },
      },
    });

    graph.node(function (node) {
      let position = 'right';
      let rotate = 0;
      if (!node.children) {
        position = 'bottom';
        rotate = Math.PI / 2;
      }
      return {
        label: node.id,
        labelCfg: {
          position,
          offset: 5,
          style: {
            rotate,
            textAlign: 'start',
          },
        },
      };
    });

    graph.data(data);
    graph.render();
    graph.fitView();

    if (typeof window !== 'undefined')
      window.onresize = () => {
        if (!graph || graph.get('destroyed')) return;
        if (!container || !container.scrollWidth || !container.scrollHeight) return;
        graph.changeSize(container.scrollWidth, container.scrollHeight);
      };
  });

let count_i = 0
const genUuidList = (obj) => {
  const newObj = { ...obj, id: crypto.randomUUID() };
  if (newObj.children) {
    newObj.children = newObj.children.map(genUuidList);
  }
  count_i ++ 
  return newObj;
};
推荐问题
宣传栏