private void treeify(VisualGraph<FGVertex, FGEdge> g, FGVertex source,
				Map<FGVertex, Node> nodesByVertices) {

			Collection<FGEdge> outEdges = g.getOutEdges(source);
			Iterator<FGEdge> it = outEdges.iterator();
			Node parent = nodesByVertices.get(source);
			if (parent.processed) {
				return;
			}

			parent.processed = true;
			int n = outEdges.size();
			switch (n) {
				case 0:
					// sink
					break;
				case 1:
					FGEdge e = it.next();
					FGVertex end = e.getEnd();
					Node node = nodesByVertices.get(end);
					parent.left = node;

					treeify(g, end, nodesByVertices);
					break;
				case 2:

					FGEdge e1 = it.next();
					FGEdge e2 = it.next();
					FGVertex end1 = e1.getEnd();
					FGVertex end2 = e2.getEnd();
					Node n1 = nodesByVertices.get(end1);
					Node n2 = nodesByVertices.get(end2);

					FGVertex left;
					FGVertex right;

					// largest row is left; put further away addresses at the bottom
					int comp = n1.row - n2.row;
					if (comp < 0) {
						parent.right = n1;
						parent.left = n2;
						left = end2;
						right = end1;
					}
					else {
						parent.left = n1;
						parent.right = n2;
						left = end1;
						right = end2;
					}

					treeify(g, right, nodesByVertices);
					treeify(g, left, nodesByVertices);
					break;
				default:
					if (!(parent.v instanceof GroupedFunctionGraphVertex)) {
						// this can happen if a test adds another edge to a test vertex
						Msg.debug(this, "\n\n\tMore than 2 edges?: " + parent);
					}

			}
		}
A simple layout that is used during testing
Ghidra/Features/FunctionGraph/src/test.slow/java/ghidra/app/plugin/core/functiongraph/graph/layout/TestFGLayoutProvider.java