Skip to content

Hypergraphs

A regular graph connects elements in pairs — one edge, two endpoints. A hypergraph lifts that restriction: a single hyperedge can be incident to many vertices at once. That makes hypergraphs the natural model for set-like relationships — co-authorship, shared tags, group membership, any “these things belong together” relation that a pairwise edge can’t capture cleanly.

Nodus draws each hyperedge as a polygon region enclosing its member vertices, so overlapping sets read at a glance. This page is the conceptual overview; for the full options and runnable code see Hypergraph Visualization and the Hypergraph API.

The subsystem implements the scalable hypergraph visualization method of Oliver et al., “Scalable Hypergraph Visualization” (TVCG 2023, arXiv:2308.05043).

Vertices and hyperedges

A hypergraph has two ingredients:

  • Vertices — the points, optionally tied to a node in your graph.
  • Hyperedges — each names a set of vertices it’s incident to, and is drawn as a region around them.

The data shape mirrors that directly:

type HypergraphData = {
vertices: { id; nodeId?; data? }[];
hyperedges: { id; vertices: id[]; data? }[];
};

Where a node–link edge would be { source, target }, a hyperedge is { id, vertices: [...] } — a whole list of members.

The pipeline

The subsystem is a chainable pipeline. You feed it data, simplify the structure, lay it out, and render it:

setData → simplify → layout → render
nodus.hypergraph
.setData(data)
.simplify({ /* options */ });
await nodus.hypergraph.layout({ /* options */ });
nodus.hypergraph.render({ /* options */ });

You can also build a hypergraph from the graph you already have with fromNodesAndEdges({ groupBy }), where groupBy(node) returns the set ids a node belongs to.

Try it live — run the full setData → simplify → layout → render pipeline:

Hypergraph pipeline Open in new tab ↗

setData — provide the structure

setData(data) loads the vertices and hyperedges (or fromNodesAndEdges derives them from the current graph). This is the raw incidence structure, before any simplification or layout.

simplify — make it scalable

Real hypergraphs can be dense and tangled. The simplify stage is what makes the method scalable: it progressively reduces the structure through a series of operations, producing a hierarchy of scales you can navigate from detailed to coarse. It returns the scales and the operation stack it applied, and supports several stopping criteria (a linear target, removing problematic substructures, or hitting a target vertex/hyperedge count) — the concrete options live in the guide.

layout — position everything

The layout stage optimizes vertex positions and hyperedge regions to balance competing goals — keeping regions compact and regular, separating distinct sets, and minimising unwanted overlap. It runs an iterative solver (off the main thread by default), reports progress, and resolves with an energy summary describing the quality of the result.

render — draw the regions

The render stage draws the hyperedges as filled, stroked polygon regions (optionally with their vertices and incidence edges), with control over opacity, palette, interactivity and which view to show.

Views

The same hypergraph can be presented several ways, and you can switch between them:

  • Primal — the familiar view: vertices as points, hyperedges as polygon regions enclosing them.
  • Dual — flips the roles, so hyperedges become the points and shared vertices become the connections — useful for reasoning about how sets relate.
  • Both — primal and dual side by side.
  • 2.5D — a tilted, layered presentation that stacks structure in depth to show scale or level.

Switch the active view at runtime with setActiveView('primal' | 'dual' | 'both'), or request a view in the render options.

Quality metrics

Because the layout is an optimization, the subsystem can tell you how good the result is. getQualityMetrics() reports measures such as the number and area of region overlaps, the average regularity of the regions, and the count of problematic substructures remaining. These let you compare settings objectively rather than by eye, and decide whether to simplify further or re-run the layout.

Interactivity and lifecycle

The rendered hypergraph is interactive. You can query and drive selection and hover — selected and hovered hyperedges and vertices, toggling selection, and hit-testing a world-space point against the regions — and it emits a stream of lifecycle events (simplify, layout phases and iterations, render, view changes) plus pointer events for hyperedges and vertices. You can refresh(), hide(), show() and destroy() the visualization. The full method and event lists are in the API reference.

Where to go next