An overview of the

After the hierarchical layout is completed, the relative position of nodes on each layer is basically determined. The simplest way is to tile all nodes on each layer with fixed width and spacing, so the position of each node is basically determined. All we have to do is wire up based on these nodes.

Solution ideas

A straight line

The simplest way is a straight line, we just need to determine the relative specific coordinates between two nodes, and then draw a straight line between two points. Results the following

As can be seen from the figure above, the straight line is relatively simple to implement, but it is barely acceptable when there are few nodes. If there are too many nodes and the lines are complicated, it is almost impossible to see, and the effect is not very good.

Curve way

Curve is the more common way, here can be used 3 times Bezier curve or 2 times Bezier curve, calculate the corresponding control points. But these control points are not easy to calculate, and some control points in general, in some complicated cases, don’t show up very well, and I’m not going to use them here.

Line way

It’s a polyline, Manhattan way, where you have inflection points in blank Spaces, and you connect them, and it makes good use of space, and it avoids nodes, and there’s no line and node covering each other, and that’s what I did here. Because of our business scenario, there are many nodes and not many levels, I have speculated on a simpler way to draw this polyline. Let’s look at the effect first

In this case, let’s consider the simplest scenario, which is to draw the polyline with a maximum of four points, which should be the simplest. And since we’re drawing it from the top down, we just have to worry about the Y coordinate of the middle node. But think about not having lines overlap as much as possible. We can order the nodes of each layer according to the x coordinate, and then when drawing lines, draw lines from left to right according to the X axis, and ensure that there is no overlap between each line.

The specific implementation

The node ordering

Function divideNodesIntoLayer(nodeList){// Empty the cached line segment combination 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; }Copy the code

Start at 40px away from the bottom node and move up, one step at a time, until you find a non-overlapping Y value.

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 (checkCross(startX, endX, line.startx, line.endx)) {flag = true; } } if (flag) break; } } else { nodeLines[layer] = []; } if (! flag) break; midY -= lineDis; } if (startX ! NodeLines [layer]. Push ({startX: startX, startY: midY, endX: endX, endY: midY})}}Copy the code

Find the Y value of the inflection point, the coordinates of the whole broken line are clear, according to the 4 dot line can be.

conclusion

The above is a very simple way of implementation. In complex scenes, there will still be overlapping lines. It is more accurate to avoid all obstacles and find paths.

This document is published by Huawei Cloud.