private ImageIcon createImage(VertexShape vertexShape, String vertexName, Color vertexColor) {
		prepareLabel(vertexName, vertexColor);

		Shape unitShape = vertexShape.getShape();
		Rectangle bounds = unitShape.getBounds();

		// this variable attempts to keep the shape's height from being too out of proportion
		// from the width. 
		int maxWidthToHeightRatio = vertexShape.getMaxWidthToHeightRatio();
		double sizeFactor = vertexShape.getShapeToLabelRatio();

		int labelWidth = label.getWidth();
		int labelHeight = label.getHeight();

		// make height somewhat bigger if label width is really long to avoid really long thin
		// nodes
		labelHeight = Math.max(labelHeight, labelWidth / maxWidthToHeightRatio);

		// adjust for shape size factor (some shapes want to be somewhat bigger than the label)
		// for example, triangles need to be much bigger to get the text to fit inside the shape,
		// whereas, rectangles fit naturally.
		int shapeWidth = (int) (labelWidth * sizeFactor);
		int shapeHeight = (int) (labelHeight * sizeFactor);

		// compute the amount to scale the shape to fit around the label
		double scalex = shapeWidth / bounds.getWidth();
		double scaley = shapeHeight / bounds.getHeight();

		Shape scaledShape =
			AffineTransform.getScaleInstance(scalex, scaley).createTransformedShape(unitShape);

		// this determines the vertical positioning of text in the shape
		// a value of 0 will put the text at the top, 1 at the bottom, and .5 in the center
		double labelOffsetRatio = vertexShape.getLabelPosition();
		bounds = scaledShape.getBounds();
		int iconWidth = bounds.width + (2 * strokeThickness);
		int iconHeight = bounds.height + (2 * strokeThickness);

		BufferedImage bufferedImage =
			new BufferedImage(iconWidth, iconHeight, BufferedImage.TYPE_INT_ARGB);

		Graphics2D graphics = bufferedImage.createGraphics();
		graphics.setRenderingHints(renderingHints);
		AffineTransform graphicsTransform = graphics.getTransform();

		// shapes are centered at the origin, so translate the graphics to compensate
		graphics.translate(-bounds.x + strokeThickness, -bounds.y + strokeThickness);
		graphics.setPaint(Colors.BACKGROUND);
		graphics.fill(scaledShape);
		graphics.setPaint(vertexColor);
		graphics.setStroke(new BasicStroke(strokeThickness));
		graphics.draw(scaledShape);

		graphics.setTransform(graphicsTransform);

		// center the text horizontally
		// position the text vertically based on the shape.
		int xOffset = (iconWidth - label.getWidth()) / 2;
		int yOffset = (int) ((iconHeight - label.getHeight()) * labelOffsetRatio);

		graphics.translate(xOffset, yOffset);
		graphics.setPaint(Colors.FOREGROUND);
		label.paint(graphics);

		graphics.setTransform(graphicsTransform); // restore the original transform
		graphics.dispose();
		Image scaledImage = ImageUtils.createScaledImage(bufferedImage, iconWidth * ICON_ZOOM,
			iconHeight * ICON_ZOOM, Image.SCALE_FAST);
		ImageIcon imageIcon = new ImageIcon(scaledImage);
		return imageIcon;

	}
Handles the rendering of graphs for the {@link DefaultGraphDisplay}
Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphRenderer.java