private static <V, E> Point2D.Double getVertexOffsetFromCenterTopInLayoutSpace(
			VisualizationServer<V, E> viewer, V vertex) {

		//
		// We need an offset from the current vertex to the center top of the viewer
		//
		Rectangle vertexBoundsInViewSpace = getVertexBoundsInViewSpace(viewer, vertex);
		Point vertexLocationInViewSpace = vertexBoundsInViewSpace.getLocation();

		// Move our point a bit: we want x to be the center value, as we are getting an offset
		// 						 from the viewer's center x
		double centerX =
			vertexLocationInViewSpace.getX() + ((int) vertexBoundsInViewSpace.getWidth() >> 1);
		vertexLocationInViewSpace.setLocation(centerX, vertexLocationInViewSpace.getY());

		Point2D viewCenter = viewer.getCenter();
		int yWithPadding = 10;
		viewCenter.setLocation(viewCenter.getX(), yWithPadding); // move to the top of the view space

		Point vertexPointInLayoutSpace =
			translatePointFromViewSpaceToLayoutSpace(vertexLocationInViewSpace, viewer);
		Point layoutCenterInLayoutSpace =
			translatePointFromViewSpaceToLayoutSpace(viewCenter, viewer);

		double offsetX = layoutCenterInLayoutSpace.getX() - vertexPointInLayoutSpace.getX();
		double offsetY = layoutCenterInLayoutSpace.getY() - vertexPointInLayoutSpace.getY();
		return new Point2D.Double(offsetX, offsetY);
	}
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