A dependency drawing needs to answer a specific question: which component uses this one? Give Cytoscape.js explicit node IDs and directed edges, then show the selected component's incoming and outgoing links as text. A line on a canvas should not be the only way to read a dependency.
Consider a fictional documentation build. site uses search and theme; search uses index. In this example an arrow means “uses,” from the consumer to its dependency. Write that convention above the graph. Reversing the arrows would describe a different relationship.

Open the complete example · Download the full HTML source
Supply the relationships independently of the layout
The Cytoscape.js documentation separates element data, styles, and layout options. Start with a container that has an explicit height, then initialize the graph after that element exists:
const cy = cytoscape({
container: document.querySelector('#dependencies'),
elements: [
{ data: { id: 'site' } },
{ data: { id: 'search' } },
{ data: { id: 'theme' } },
{ data: { id: 'index' } },
{ data: { id: 'site-search', source: 'site', target: 'search' } },
{ data: { id: 'site-theme', source: 'site', target: 'theme' } },
{ data: { id: 'search-index', source: 'search', target: 'index' } }
],
style: [
{ selector: 'node', style: { label: 'data(id)' } },
{ selector: 'edge', style: {
'target-arrow-shape': 'triangle', 'curve-style': 'bezier'
} }
],
layout: { name: 'grid', rows: 2 }
});
Keep IDs unique and check that every edge endpoint exists before creating the graph. Do not silently invent a missing component because an edge happens to mention its name. Keep the source elements beside the HTML file so the drawing can be rebuilt.
Read a selection without guessing from distance
For the selected node, inspect its connected edges. An edge whose source is the selected ID is an outgoing “uses” relationship. An edge whose target is that ID is an incoming “used by” relationship. Sort the displayed names so repeated selections produce a stable reading order.
Selecting search should say “Uses: index” and “Used by: site.” Selecting theme should say “Uses: none” and “Used by: site.” Those answers come from the supplied relationships, not the node positions.
Offer a labeled component selector as well as graph taps. Both controls should call the same selection function and update the same text result. A keyboard user can then inspect a component without needing to hit a small drawn node.
In the embedded reading view, use that selector with a PNG rendered by Cytoscape from the current graph. Open the complete HTML download for the draggable canvas and node taps. The exported picture and relationship text update together when you select a component; the picture is not a separate hand-drawn diagram.
Moving a node changes the picture, not its dependencies. Use a Fit view control to restore the visible graph after exploration. Do not label that control Reset data unless it actually restores the elements as well.
Keep the question narrower than a graph analysis tool
This page inspects immediate incoming and outgoing dependencies. It does not calculate a deployment order, prove that a project is free of cycles, or measure an outage's full impact. Add those operations only with their own defined rules and readable results.
The existing network graph inspector addresses undirected paths and isolated nodes. Its hop counts should not be copied into this directed dependency example. Here, the arrow convention and the selected component's direct relationships are the useful output.
For a review in NOS, keep the arrow convention, original element list, and selection text with the drawing. Ask the reviewer whether the three supplied relationships are correct before changing colors or spacing. A clean layout can make a wrong edge easier to overlook.