public static <V extends VisualVertex, E extends VisualEdge<V>> 
		Rectangle getTotalGraphSizeInLayoutSpace(VisualizationServer<V, E> viewer) {
	//@formatter:on

		Layout<V, E> layout = viewer.getGraphLayout();
		Graph<V, E> theGraph = layout.getGraph();
		Collection<V> vertices = theGraph.getVertices();
		Collection<E> edges = theGraph.getEdges();

		Function<V, Rectangle> vertexToBounds = createVertexToBoundsTransformer(viewer);

		if (!layoutUsesEdgeArticulations(layout)) {
			Rectangle bounds = getBoundsForVerticesInLayoutSpace(vertices, vertexToBounds);
			return bounds;
		}

		Function<E, List<Point2D>> edgeToArticulations = e -> e.getArticulationPoints();
		return getTotalGraphSizeInLayoutSpace(vertices, edges, vertexToBounds, edgeToArticulations);
	}
Transforms the given edge loop shape to graph space, which includes updating
the size and location of the loop to be relative to the vertex.

@param edgeLoopShape The shape to transform
@param vertexShape The shape of the vertex for which the edge is being created
@param x The x coordinate of the vertex
@param y The y coordinate of the vertex
@return the transformed edge loop shape
Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/GraphViewerUtils.java