Cytoscape JS Examples

Cytoscape JS examples are node-link graphs, not bar charts. Here are four I actually paste: force, hierarchy, circle, and tap to highlight.

Cytoscape Examples Networks
← All posts
Cytoscape JS Examples

Search Cytoscape JS examples and you get biology papers mixed with a three-node hello-world. Cytoscape.js is a graph theory library. Nodes, edges, a layout name. It will not draw a bar chart. If that's what you wanted, I wrote bar charts explained.

Below are four graphs I actually paste: a cose force layout, a breadthfirst pipeline, a circle, and tap-to-highlight neighbors. The Cytoscape.js page has a tighter force / circle / grid demo. For D3's version of a network, see D3 graph examples.

What these Cytoscape JS examples are

Every example is the same object: a container, an elements list, a stylesheet, a layout. Change the layout name and the picture changes. That's the API.

  • cose. Force-directed. The default when you don't know the shape yet.
  • breadthfirst. A tree or a pipeline. Needs directed edges.
  • circle. Small graphs where you want every node on the ring.
  • Tap. Not a layout. The interaction that makes a graph feel like a tool.

I pick Cytoscape when the product is the graph: pan, tap, filter, a few hundred nodes. I would not wrap D3 force just to ship that. vis.js is the other name I shortlist.

Force layout (cose)

Six services, some edges, cose spreads them out. Drag a node. This is the Cytoscape JS example I start from, then I swap in real ids. Animate is off so the page doesn't wriggle while it settles.

Preview

Code

const cy = cytoscape({
  container: document.getElementById("chart"),
  elements: [
    { data: { id: "App", label: "App" } },
    { data: { id: "API", label: "API" } },
    { data: { id: "DB", label: "DB" } },
    { data: { id: "e1", source: "App", target: "API" } },
    { data: { id: "e2", source: "API", target: "DB" } },
  ],
  style: [
    { selector: "node", style: { "background-color": "#e8b84a", label: "data(label)" } },
    { selector: "edge", style: { width: 2, "line-color": "#5b9fd4" } },
  ],
  layout: { name: "cose", animate: false, padding: 28 },
});

Breadthfirst

A deploy pipeline. Directed edges, directed: true, and breadthfirst puts Git at the top and Prod at the bottom. Use this when the graph has a root and a direction. Force would just make a blob.

Preview

Code

cy.layout({
  name: "breadthfirst",
  directed: true,
  padding: 28,
  spacingFactor: 1.25,
  animate: false,
}).run();

// edges need a direction for this to mean anything
// { data: { id: "e1", source: "Git", target: "Build" } }

Circle

Eight nodes on a ring, a couple of chords so it isn't just a cycle. Circle is honest when the graph is small and you don't want cose to hide a node behind another one. Past ~20 nodes I stop using it.

Preview

Tap to highlight neighbors

Tap a person. Their neighborhood stays, everyone else fades. Tap the background to reset. closedNeighborhood() is the node plus its edges plus its neighbors. That's the selection I want 90% of the time.

Preview

Tap a node. Tap the empty space to clear.

Code

cy.on("tap", "node", (event) => {
  const node = event.target;
  cy.elements().removeClass("highlighted faded");
  node.addClass("highlighted");
  node.neighborhood().addClass("highlighted");
  cy.elements().difference(node.closedNeighborhood()).addClass("faded");
});

cy.on("tap", (event) => {
  if (event.target === cy) cy.elements().removeClass("highlighted faded");
});

Gotchas

  • Height. The container needs a pixel height. A div with width: 100% and no height is an empty box. That's always the first bug.
  • Edge ids. Give edges their own id. If you skip it, adding a second edge between the same pair gets weird.
  • Layout vs style. Layout places. Style paints. You don't color a node by putting fill on the layout object.
  • Zoom vs scroll. I turn userZoomingEnabled off on a blog page so the wheel still scrolls the article. Turn it back on in an app.

Grid layout is on the library page if you just need a table of nodes. Compound nodes (parents that wrap children) are the next step when a flat graph isn't enough. And if the “graph” is really a flow of amounts, that's a sankey, not Cytoscape.

Questions I get

What are Cytoscape JS examples usually showing?

Node-link graphs. Nodes are things, edges are relationships. Layouts like cose, circle, and breadthfirst place them. This is not a bar chart library. If you wanted that, search for Chart.js.

How do I start a Cytoscape.js graph?

Give it a container with a real height, an elements array of nodes and edges, a style, and a layout name. cytoscape({ container, elements, style, layout: { name: 'cose' } }) is the whole hello-world.

Why is my Cytoscape graph blank?

The container has no height. Cytoscape will not invent one. Set height in CSS or inline. The second most common bug is running the script before the div exists.

Should I use Cytoscape.js or D3 for a network?

Cytoscape if the product is a graph you pan, tap, and filter. D3 if you already live in SVG and the network is a one-off drawing. I would not wrap D3 force just to ship a graph UI.

Do I need cytoscape-cose-bilkent?

Not for these examples. cose ships in the core build. cose-bilkent is a separate extension for larger, messier graphs. Start with cose. Add the extension when the layout looks like a knot.

Latest posts

All posts

Bar Charts Explained

A bar is a number you can compare at a glance. Here's when to use one, the four layouts I actually ship, and the mistakes that make a bar chart lie.

Charts Examples JavaScript
Read post