Graph设置node的ranker

问题表现

最近在做一个流程图,绘图部分使用antd/x6,node的位置信息使用Graph生成,在完成基本功能开发后发现一个小问题,本来预期node是向上对齐的,但是Graph没有让本该处于同一ranker的node处于同一个ranker而是尽可能地提升node的ranker,造成了node向下对齐的效果, 问题如下图所示:4号node逻辑上应该处于ranker1,Graph却让它处于ranker2

 

 解决方案

Graph不支持直接设置node的ranker,但是可以设置edge的minlen,也就是设置一条边的起点和终点相差几个ranker;参考了这个链接后得到启发,通过设置node的输出边的minlen可以修改node的ranker。要让4号node处于ranker1就要设置4号node到终点的这条edge的minlen为2,  这样这个问题就可以得出这样一个解决方案:

计算出所有分支的路径,得出最长的路径的长度,然后给每条路径的最后一条edge设置相应的minlen就可以调整该路径上的所有node的ranker以实现node的向上对齐,minlen的设置规则为最长路径的长度-当前路径的长度+1

1.计算出所有分支的路径 

//传入edges和起点的id,返回的数据为一个二维数组,每一个item就是一条路径,按照上图的edges数据
//得到的结果为[[0,1,2,4],[0,3,4]]
export function findAllPath(edges, starting) {
  const endMap = {};
  edges.forEach(({ start, end }) => {
    if (endMap[start]) {
      endMap[start].push(end);
    } else {
      endMap[start] = [end];
    }
  });

  function generatePath(lastPaths) {
    const newPath = [];

    lastPaths.forEach((d) => {
      const id = d[d.length - 1];
      if (!endMap[id]) {
        newPath.push(d);
      } else {
        endMap[id].forEach((b) => {
          const temp = [...d, b];
          generatePath([temp]).forEach((a) => {
            newPath.push(a);
          });
        });
      }
    });

    return newPath;
  }

  return generatePath([[starting]]);
}

2.得到最长路径的长度

const allPath = findAllPath(edge, starting);
    let maxLength = 0;
    allPath.forEach((d) => {
      if (d.length > maxLength) {
        maxLength = d.length;
      }
    });

3.动态生成每一条路径最后一条edge的minlen,并把数据传入graph

edges.forEach((edge) => {
      const source = edge.getSource();
      const target = edge.getTarget();
      let minlen = 1;
//边的target是终点时才需要动态计算
      if (target.cell === terminal) {
        allPath.forEach((d) => {
          if (d.includes(source.cell)) {
            minlen = maxLength - d.length + 1;
          }
        });
      }
      g.setEdge(source.cell, target.cell, { minlen });
    });

4.经过上面的一番操作后完美解决了这个问题,一家人就该齐齐整整

 结论

Graph虽然无法单独设置单个node的ranker,但是可以通过设置它的输出边的minlen为一个比较大的数值来把它以及它上面的node顶上若干个ranker

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值