@Override
	public void run(TaskMonitor monitor) throws CancelledException {
		this.graphScope = getGraphScopeAndGenerateGraphTitle();
		AttributedGraph graph = createGraph(graphTitle);
		monitor.setMessage("Generating Graph...");
		try {
			GraphDisplay display = graphProvider.getGraphDisplay(reuseGraph, monitor);
			GraphDisplayOptions graphOptions = new ProgramGraphDisplayOptions(graphType, tool);
			if (showCode) { // arrows need to be bigger as this generates larger vertices
				graphOptions.setArrowLength(30);
			}

			BlockModelGraphDisplayListener listener =
				new BlockModelGraphDisplayListener(tool, blockModel, display);
			addActions(display, v -> listener.getAddress(v));
			display.setGraphDisplayListener(listener);

			if (showCode) {
				graphOptions.setVertexLabelOverrideAttributeKey(CODE_ATTRIBUTE);
			}
			display.setGraph(graph, graphOptions, graphTitle, appendGraph, monitor);

			if (location != null) {
				// initialize the graph location, but don't have the graph send an event
				AttributedVertex vertex = listener.getVertex(location.getAddress());
				display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
			}
			if (selection != null && !selection.isEmpty()) {
				Set<AttributedVertex> selectedVertices = listener.getVertices(selection);
				if (selectedVertices != null) {
					// initialize the graph selection, but don't have the graph send an event
					display.selectVertices(selectedVertices, EventTrigger.INTERNAL_ONLY);
				}
			}
		}
		catch (GraphException e) {
			if (!monitor.isCancelled()) {
				Msg.showError(this, null, "Graphing Error", e.getMessage());
			}
		}
	}
<CODE>GraphTask</CODE> is a threaded task creating either a block or call graph.
Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java