概述
分层布局弄好之后,每一层的节点上下的相对方位根本确定了,咱们最简略的方法,便是每一层平铺一切节点,节点宽度固定以及距离固定,每个节点的方位根本就确定了。咱们只需基于这些节点进行连线就能够了。
方案思路
直线方法
最简略的方法便是直线,咱们只需确定两个节点之间的相对详细坐标,然后两点之间画一条直线就能够了。作用如下
从上图能够看出,直线实现起来是比较简略的,可是节点很少的状况,仍是能够牵强能够接受的,如果节点太多,线条杂乱,根本没办法看了,作用不是很好。
曲线方法
曲线是比较常见的方法,这儿能够用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个点划线即可。
总结
以上是一种很简略的实现方法,遇到杂乱场景,仍是会有线条的堆叠,更准确的做法是要躲避一切妨碍,寻觅路径,这种杂乱的做法,后续会进一步测验。
本文由华为云发布。