关于程序员:从零开始画自己的DAG作业依赖图三节点连线简单版

46次阅读

共计 1510 个字符,预计需要花费 4 分钟才能阅读完成。

概述

分层布局弄好之后,每一层的节点高低的绝对地位根本确定了,咱们最简略的形式,就是每一层平铺所有节点,节点宽度固定以及间距固定,每个节点的地位根本就确定了。咱们只有基于这些节点进行连线就能够了。

计划思路

直线形式

最简略的形式就是直线,咱们只有确定两个节点之间的绝对具体坐标,而后两点之间画一条直线就能够了。成果如下

从上图能够看出,直线实现起来是比较简单的,然而节点很少的状况,还是能够勉强能够承受的,如果节点太多,线条简单,根本没方法看了,成果不是很好。

曲线形式

曲线是比拟常见的形式,这里能够用 3 次贝塞尔曲线或者 2 次贝塞尔曲线,算好相应的控制点即可。然而这些控制点不是很好算,并且通用的一些控制点,在一些简单状况下,展现的成果也不是很好,这里也没打算应用这个。

折线形式

就是通过折线,曼哈顿的形式,在空白的中央进行拐点,进行连线,这种形式能够很好利用空间,并且能够躲避节点,不会呈现 线和节点的互相遮蔽,这里我就采纳了这种形式。因为咱们的业务场景,节点比拟多,并且层级不是很多,这里我投机采纳了一种比较简单的形式来画这个折线。首先看下成果

在上述情况,咱们思考最简略的场景,就是最多用 4 个点来画这条折线,这种画法应该是最简略的。因为图是从上往下画的,咱们只有思考 两头节点 Y 坐标即可。然而要思考尽可能的不要让线条重叠。咱们能够把每层节点依照 x 坐标排序,而后划线的时候,依照 x 轴,从左到右的顺次划线,并且保障每条线没有重叠的局部。

具体实现

节点排序

function divideNodesIntoLayer(nodeList){
            // 清空缓存的线段联合
            nodeLines = {};
            var lineNodes = {};
            for(var layer = 1; layer <= maxGraphLayer; layer++){lineNodes[layer] = [];
                for(var j = 0; j < nodeList.length; j++){if(nodeList[j].layer === layer){lineNodes[layer].push(nodeList[j]);
                    }
                }
                lineNodes[layer].sort(function(a, b){return a.x - b.x;})
            }
            return lineNodes;
}

从间隔上层节点 40px 的中央,往上遍历,每次减少一个步长,判断是否用重叠,直到找到一个不重叠的 Y 值为止。

function calcMidY(){
    var midY = endY - 40;
    while (true) {
        var flag = false;
        if (nodeLines[layer]) {for (var i = 0; i < nodeLines[layer].length; i++) {var line = nodeLines[layer][i];
                if (line.startY === midY) {
                    //  判断是否重叠
                    if (checkCross(startX, endX, line.startX, line.endX)) {flag = true;}
                }
                if (flag) break;
            }
        } else {nodeLines[layer] = [];}
        if (!flag) break;
        midY -= lineDis;
    }
    if (startX !== endX) {
                //  缓存曾经画的线段
        nodeLines[layer].push({
            startX: startX,
            startY: midY,
            endX: endX,
            endY: midY
        })
    }

}

找到了拐点的 Y 值,整条折线的坐标都清晰了,依据 4 个点划线即可。

总结

以上是一种很简略的实现形式,遇到简单场景,还是会有线条的重叠,更精确的做法是要躲避所有阻碍,寻找门路,这种简单的做法,后续会进一步尝试。

本文由华为云公布

正文完
 0