cytoscape.js v4 HEAD · 47a5c66d · built 2026-09-16 14:48Z

API reference

Preview. Generated from the JSDoc on src/ by scripts/docs-generate.mjs — the same model round 46 will build the real documentation site from. This page exists so the authoring surface can be read as a consumer reads it, not as a replacement for that site.

332 documented members.

The cytoscape factory

Entry point The cytoscape factory

cytoscape

Create a GPU-prototype cytoscape instance (issue #3486, pass 1): a columnar CPU-canonical model with a WebGPU render pipeline.

With a container, WebGPU is required — this throws synchronously when navigator.gpu is unavailable. Without a container the instance is headless (Node-friendly, never throws for a missing GPU). Adapter acquisition is asynchronous and reported separately: cy.ready rejects when no adapter can be had, which this function cannot know yet.

Beyond the constructor's work, the factory ingests options.elements through the bulk path (no per-element handles, no add events — nothing can be listening yet), runs options.layout, and attaches the renderer and pointer handler when a container is given.

Unknown options are ignored, deliberately (decided 2026-08-04, fifth design sitting): unlike an unknown sheet key, style property or query key, a misspelled option does not throw, because strictness here resolves at the type layer — TypeScript's excess-property check rejects { motionBlur: true } against CytoscapeOptions, and v4 does not replicate at runtime what the build already checks.

options

the instance options; every field is optional, and an omitted container is what selects headless mode

Returns

the new core, usable synchronously — reads and writes do not wait on the device, and a rendered instance additionally resolves cy.ready

Throws

when container is given and navigator.gpu is missing

cytoscape.toColumnarElements

Convert classic v3-style elements JSON into the columnar bulk-load form: typed-array columns with edge endpoints as node indices.

This is the compatibility path for callers holding definition-form JSON; the columnar form is what the loader ingests fastest, since contiguous slot runs become memcpys and no per-element objects or per-edge id lookups are needed. Exposed publicly as cytoscape.toColumnarElements.

The columnar form has no column for locked, grabbable or pannable, so a def setting one of those converts without it. The factory's own definition-form load does not go through this function for that reason — it uses the internal buildColumnar, which reports the deviations so it can write them after the ingest.

defs

one element, an array, or { nodes, edges }

Returns

the equivalent self-contained columnar payload

Throws

if an edge names a source or target that is not a node in the same payload — columnar payloads must be self-contained

cytoscape.serializeElements

Serialize elements (definition form or columnar form) into one transferable/fetchable ArrayBuffer. deserializeElements (or passing the buffer straight to options.elements/cy.add()) reverses it.

elements

the elements to serialize, in either accepted form; a definition-form payload is converted to columnar first. A columnar payload's optional graph-level data rides along (round 39.2); the definition form has nowhere to put it, so it carries none

Returns

one little-endian ArrayBuffer holding the whole payload — fixed header, columns, and ids as a UTF-8 blob with prefix offsets

Throws

if the platform is big-endian, or if a definition-form payload names an edge endpoint that is not a node in the same payload

cytoscape.deserializeElements

Deserialize a serializeElements buffer (or a view over one) back into the columnar elements form. Numeric columns are zero-copy views into the given buffer; a misaligned view is copied once to realign.

input

a serializeElements buffer, or a view over one

Returns

the columnar form, whose numeric columns are views into the input rather than copies — so the buffer must outlive the result, and writing into either is visible through the other. Graph-level data is the exception in two ways: it is decoded from JSON rather than viewed, and cy.add() deliberately ignores it (see ColumnarElements.data)

Throws

if the platform is big-endian, or the buffer is too short, truncated or of an unsupported format version

Core

Lifecycle Core

cy.ready

resolves once the render pipeline is usable (immediately when headless)

Style Core

cy.style

Get the style engine, or set the stylesheet and return it.

v4's sheet is a plain { nodes, edges, parents, core } object of prop objects — there are no selector blocks and no style functions. All per-element variation is declarative: mapper objects ({ data, scale, … }) and case conditionals, which is what keeps every value analyzable, serializable and GPU-evaluable.

Inside a batch the sheet is compiled and validated immediately (so errors still throw at the call site) but applied once at the outermost endBatch().

sheet

the stylesheet to install; omit to read the engine

Returns

the style engine (also reachable as the return value when setting, so calls chain)

Throws

if the sheet references an unknown property or an invalid value

Batching Core

cy.compact

Slot-moving compaction, explicit form (round 19.5): move live elements down to a dense slot prefix so highWater, column capacity and pass-iteration widths shrink to the current graph instead of its peak. A monotone remap keeps draw order — compaction is a visual no-op — and held refs/handles/listeners repair through forwarding (19.3). The automatic dead-slot-ratio trigger covers the common shrink/churn profiles; this call is for deterministic timing (e.g. right after a bulk filter, before an animation). Throws mid-batch; defers with a warning while a GPU force layout runs.

Also spelled cy.gc.

cy.startBatch

Open a batch: defer style application until the matching endBatch(). Pairs nest — only the outermost endBatch() flushes. Prefer batch( fn ), which cannot leak a depth on an exception.

Returns

this core, for chaining

cy.endBatch

Close a batch. At the outermost close the deferred work flushes as one bulk pass — filtered to elements still live, so adding and removing within the same batch costs nothing — and the automatic slot-compaction trigger gets its boundary check. A sheet change during the batch subsumes the per-element work: one applyAll() covers every live element.

Unbalanced calls are a no-op rather than an error, matching v3.

Returns

this core, for chaining

cy.batch

Run fn inside a startBatch()/endBatch() pair. The batch closes even if fn throws, so this is the form to prefer.

fn

the mutations to batch; its return value is discarded

Returns

this core, for chaining

Layout Core

cy.layout

Make a layout over the whole graph. The layout does not run until you call .run() on it.

Built-ins: grid, preset, circle, concentric, breadthfirst, random and force (the GPU-capable spring–electric layout, round 18). An external layout is passed directly rather than registered — v4 has no cytoscape.use and no string registry — by giving impl: a class or object implementing { run( ctx ), stop?() } (see layout/contract.mts for the LayoutContext it receives).

Lifecycle events (layoutstart/layoutready/layoutstop) fire on the core, once per run; layout instances are not emitters.

options

{ name } for a built-in or { impl } for an extension, plus that layout's own options and the shared layoutPositions plumbing (animate, spacingFactor, transform, fit, padding, …)

Also spelled cy.makeLayout, cy.createLayout.

Returns

the layout instance, unstarted

Throws

if neither a known name nor an impl is given

See

Collection#layout to lay out a subset

Graph manipulation Core

cy.add

Add elements to the graph and return them as a collection.

Takes all three input forms: the classic v3 definition form (one object, an array, or { nodes, edges }), the columnar bulk form (typed-array columns with edge endpoints as node indices), and the binary wire buffer produced by serializeElements/cy.serialize(). Nodes are added before edges, so an edge may reference a node added in the same call.

Fires add per element. Inside a batch the first style application of the new elements defers to the outermost endBatch(), so style-derived reads (width(), label()) may be stale until then.

Graph-level data() in a wire buffer is ignored here (round 39.2), where options.elements applies it: adding elements to a populated graph must not overwrite that graph's own data(). Apply it explicitly with cy.data( deserializeElements( buf ).data ) if that is what you want.

input

elements in definition, columnar or wire form

Returns

a collection of the added elements

cy.remove

Remove elements from the graph. Removing a node removes its connected edges, and removing a compound parent removes its descendants. Equivalent to eles.remove().

eles

the elements to remove

Returns

the removed elements

Collections Core

cy.collection

An empty collection bound to this core — the accumulator for union/add chains.

Takes no arguments, and throws if given any (round 64, closing ledger item 28): v3's collection( eles, opts ) also built from a string, an array or a collection, so the v3-shaped call used to return the empty collection silently — the one method boundary where a typo did nothing, against the unknown-key/unknown-prop throws everywhere else. Build a set with union() over this accumulator, or query with cy.$( query ) / cy.filter( query ).

Returns

a collection of zero elements

Throws

if called with any argument — v3's building forms are not ported; the message names the replacements

cy.getElementById

Look up one element by id through the O(1) id index.

id

the element id

Also spelled cy.$id, cy.byId.

Returns

a collection of one element, or an empty collection when no element has that id

cy.elements

All elements, optionally filtered — nodes (in insertion order) then edges.

v4 has no selector strings: pass a structured query object ({ group, selected, parent, data: { weight: { gt: 0.5 } } }), which compiles to per-group flag tests answered by one columnar scan, or a predicate function for anything richer. Unknown query keys throw, so a typo cannot silently match everything.

Called with no query, the result is memoized until the graph next gains or loses an element (round 34.2), so repeated calls are O(1) and two of them return the same collection object. A v4 collection is an immutable snapshot holding refs into the columns, so it still reads live values — a style, position or data write neither invalidates it nor goes unseen through it.

query

a query object or an ( ele ) => boolean predicate; omit for everything

Returns

the matching elements

cy.nodes

The graph's nodes, optionally filtered. Same query forms as elements(), restricted to the node group — and, with no query, the same memo (34.2).

query

a query object or an ( ele ) => boolean predicate

Returns

the matching nodes

cy.edges

The graph's edges, optionally filtered. Same query forms as elements(), restricted to the edge group — and, with no query, the same memo (34.2).

query

a query object or an ( ele ) => boolean predicate

Returns

the matching edges

cy.filter

Filter the whole graph. Identical to elements( query ), kept for symmetry with eles.filter().

query

a query object or an ( ele ) => boolean predicate

Also spelled cy.$.

Returns

the matching elements

cy.elementsInBox

Live, visible elements contained in the model-coordinate box (corners in any order): the box-selection query, answered by one columnar scan. Nodes count when their bounding box lies fully inside; edges when both endpoint node centers do (v3's default 'contain' semantics, with straight-edge endpoints taken at the node centers).

boxSelectionMode does not reach here (round 39.1): this stays the pure geometric containment query whatever the gesture is set to. For the overlap question, boxSelectionMode( 'overlap' ) and drag a box, or test intersection yourself against eles.boundingBox(). (boxSelectionIncludesLabels is the one interaction setting that does reach here: with it on, a node's label box must be contained too.)

x1

one corner's model x

y1

that corner's model y

x2

the opposite corner's model x

y2

that corner's model y

Returns

the contained elements

Events Core

cy.on

Listen for events on the core.

Delegation is predicate-based — there are no selector strings. With a trailing callback the middle argument is a predicate over the event target: cy.on( 'tap', ele => ele.isNode(), handler ).

Any name registers, and that is deliberate (decided 2026-08-04, fifth design sitting). Custom events are supported API — emit( 'foo' ) fires handlers bound to 'foo' — so event names cannot be validated against a list without breaking them. The consequence is worth stating plainly, because it is a silent one: a name v4 never emits registers cleanly and then never fires. That covers the round-17 drops — the vmouse* aliases and v3's raw mouse/touch re-emits (mousedown, click, touchstart, …), for which pointer* is the one modern spelling; mouseover/mouseout do still fire. A ported v3 handler does nothing at all rather than erroring, so port event names by the vocabulary in src/README.md rather than by trying them.

Namespaces are exactly that rule, not an exception to it (round 41.2). There is no namespace machinery: a type is matched whole, so 'tap.ns' is one literal name that emit( 'tap' ) does not reach and off( 'tap.ns' ) removes on its own. Until round 41 v4 imported v3's emitter and so inherited v3's namespace semantics in full, against its own design — measured in 37.4 and closed in 41.2.

events

one or more space-separated event names

predicateOrCb

the delegation predicate when callback is given, otherwise the handler itself

callback

the handler, when delegating

Listen with predicate delegation: the handler runs only for events whose target satisfies predicate.

events

one or more space-separated event names

predicate

( ele ) => boolean over the event target; only runs for element targets

callback

the handler

Also spelled cy.addListener.

Returns

this core, for chaining

See

Core#off — removing a delegated handler takes the same ( events, predicate, handler ) triple, since predicates compare by function identity

cy.one

Like on(), but the handler runs at most once and then removes itself.

events

one or more space-separated event names

predicateOrCb

the delegation predicate when callback is given, otherwise the handler itself

callback

the handler, when delegating

Like on() with delegation, but the handler runs at most once.

events

one or more space-separated event names

predicate

( ele ) => boolean over the event target

callback

the handler

Also spelled cy.once.

Returns

this core, for chaining

cy.off

Stop listening. Removing a delegated handler takes the same ( events, predicate, handler ) triple it was added with — predicates compare by function identity, so the predicate must be the same function object, not an equivalent one.

events

one or more space-separated event names

predicateOrCb

the delegation predicate when callback is given, otherwise the handler itself; omit both to remove every handler for events

callback

the handler, when delegating

Remove a delegated handler. The predicate must be the same function object it was registered with — predicates compare by identity, not by structure.

events

one or more space-separated event names

predicate

the predicate the handler was added with

callback

the handler to remove

Also spelled cy.removeListener.

Returns

this core, for chaining

cy.removeAllListeners

Remove every listener on the core, including element-bound and delegated ones.

Returns

this core, for chaining

cy.emit

Emit an event on the core.

Custom event names are supported API, which is why on() validates none: cy.emit( 'myevent' ) runs handlers registered for 'myevent', and the same holds on elements. Names v4 itself never emits are therefore legal to register and simply never fire — see on() for which those are, and PLAN.md's open-call record for why no denylist exists.

events

one or more space-separated event names, or an event props object

extraParams

extra arguments passed to each handler after the event object

Also spelled cy.trigger.

Returns

this core, for chaining

cy.promiseOn

Resolve once the next matching event fires — the promise form of one().

events

one or more space-separated event names

predicate

an optional delegation predicate over the target

Also spelled cy.pon.

Returns

a promise for the event object

Viewport Core

cy.zoom

Get the zoom level, or set it. Setting is a no-op while zoomingEnabled() is false, and the level is clamped to zoomRange().

zoom

the new level, or { level, position | renderedPosition } to zoom about a fixed point; omit to read

Returns

the current zoom when reading, this core when setting

cy.pan

Get the pan offset, or set it. Setting is a no-op while panningEnabled() is false.

pan

the new rendered-space offset; omit to read

Returns

the current pan when reading, this core when setting

cy.panBy

Shift the pan by a delta. A no-op while panningEnabled() is false.

delta

the rendered-space offset to add

Returns

this core, for chaining

cy.fit

Pan and zoom so the given elements fill the viewport.

Bounds include labels by default (round 16), so a fit never clips the text it was asked to show; edge-label terms are conservative, so a fit may slightly over-fit but never under-fits.

eles

the elements to fit; omit for the whole graph

padding

rendered-space padding around the box

Returns

this core, for chaining

cy.center

Pan so the given elements are centred, leaving the zoom alone. Bounds include labels, as in fit().

eles

the elements to centre on; omit for the whole graph

Also spelled cy.centre.

Returns

this core, for chaining

Animation (viewport) Core

cy.animate

Animate the viewport (pan/zoom) over duration ms. Element animation is on the collection (eles.animate). Tweens are CPU-canonical; a data write / manual pan mid-animation is not prevented but will be overwritten by the next tick.

opts

the viewport targets (pan, panBy, zoom, fit, center) plus duration, easing and complete; fit beats center beats panBy beats pan, and panBy with pan throws

Returns

this core, for chaining

cy.animation

Like animate, but returns a handle with play/stop/promise — the viewport counterpart of eles.animation.

opts

as animate; the animation does not start until play()

Returns

the handle

cy.animated

True while the viewport is animating.

Returns

whether a viewport animation (pan/zoom/fit/center) is running; element animations do not count here — those are eles.animated()

cy.stop

Stop every running viewport animation (round 21: no queue — the v3 clearQueue argument is gone).

jumpToEnd

apply each animation's final values instead of freezing the viewport where the tween reached

Returns

this core, for chaining

cy.extent

The model-space rectangle currently visible, as { x1, y1, x2, y2, w, h } — the inverse of the pan/zoom transform applied to the viewport box.

Returns

the visible extent in model coordinates

See

Core#renderedExtent for the same box in rendered coordinates

cy.renderedExtent

The rendered (on-screen) viewport rectangle.

Returns

the container's box in rendered px, anchored at the origin — the rendered-space counterpart of extent(), which is the same box projected into model coordinates

See

Core#extent for the model-coordinate form

cy.size

Rendered dimensions as { width, height }.

cy.minZoom

Get the minimum zoom, or set it. Setting re-clamps the current zoom.

zoom

the new minimum; omit to read

Returns

the current minimum when reading, this core when setting

cy.maxZoom

Get the maximum zoom, or set it. Setting re-clamps the current zoom.

zoom

the new maximum; omit to read

Returns

the current maximum when reading, this core when setting

cy.zoomRange

Set both zoom bounds; accepts (min, max) or { min, max }.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

min

the minimum zoom, or an object carrying both bounds

max

the maximum zoom, when min is a number

Returns

this core, for chaining

cy.viewport

Set zoom and/or pan together, emitting once.

opts

the zoom and/or pan to apply; omitted keys are left as they are

Returns

this core, for chaining

cy.reset

Reset the viewport to zoom 1, pan (0, 0).

cy.pick

Async GPU pick at a rendered (CSS px) position; resolves with the element under the point or null (always null when headless).

Exact: a hit is a point on the drawn element. The pointer gestures additionally apply v3's hit halos (8 rendered px around edges for a mouse, 24 for touch; 2/8 around nodes — round 57.9), so a press can land where this method answers null; the halo belongs to the gesture, not the API.

What wins when elements overlap, as contract (round 97.1): a non-parent node, then an edge, then a compound parent — the reverse of the order v4 draws them in (parents, edges, leaves), so the answer is always the topmost thing drawn at that point. Nesting depth does not change it: a parent inside another parent still draws under every edge, and among parents the deepest wins. v3 ordered these by z-index / z-compound-depth instead, which v4 does not have, so a deeply nested v3 parent could beat a shallower edge where v4's edge wins.

x

rendered (CSS px) x, relative to the container

y

rendered (CSS px) y

Returns

the element under the point, or null

Renderer Core

cy.stats

The renderer's frame statistics, or null when headless. The snapshot carries the frame timings, cache hit rates and pass counters — note that cpuFrameMs is encode/submit cost only (submission is fire-and-forget), so reconcile fps against gpuFrameMs.

Returns

a RendererStats snapshot, or null on a headless instance

cy.resize

Re-measure the container and redraw (no-op when headless).

Also spelled cy.invalidateSize.

Image export Core

cy.png

Export the rendered graph as a PNG. Async — the pixels live on the GPU (offscreen render + readback), unlike v3's synchronous base64 form; every output form resolves through the returned promise. Options as in v3: bg, full, scale or maxWidth/maxHeight, output ('base64uri' default | 'base64' | 'blob'; 'blob-promise' is an accepted alias of 'blob'). Headless instances reject — there is no renderer to export from.

options

the v3 export options named above

Returns

the encoded image in the requested output form

cy.jpg

Export as JPEG: as png, plus quality (0..1) and a white default bg (JPEG has no alpha channel).

options

as png, plus quality

Also spelled cy.jpeg.

Returns

the encoded image in the requested output form

Graph-level data & scratch (plain objects, not columns) Core

cy.data

Graph-level data — read all, read one key, or write. This is a plain object, not a columnar sidecar (which is ele.data()). It is carried by the wire format since round 39.2: serialize() writes it and options.elements applies it, while cy.add( buffer ) deliberately ignores it. Writing emits data.

args

() for the whole object, ( key ) to read one, ( key, value ) or ( patchObject ) to write

Also spelled cy.attr.

Returns

the data object or value when reading, this core when writing

cy.removeData

Delete graph-level data keys. Emits data when anything was removed.

names

space-separated key names; omit to clear everything

Also spelled cy.removeAttr.

Returns

this core, for chaining

cy.scratch

Graph-level scratchpad — like data(), but for transient state that is never exported and never emits. Namespace your keys (an extension convention: '_myExtension').

args

() for the whole object, ( key ) to read one, ( key, value ) or ( patchObject ) to write

Returns

the scratch object or value when reading, this core when writing

cy.removeScratch

Delete graph-level scratch keys.

names

space-separated key names; omit to clear everything

Returns

this core, for chaining

Interaction gating Core

cy.autolock

Get or set whether every node is locked (immovable) regardless of its own locked flag — the graph-wide override.

bool

the new setting; omit to read

Also spelled cy.autolockNodes.

Returns

the current setting when reading, this core when setting

cy.autoungrabify

Get or set whether every node is ungrabbable regardless of its own grabbable flag. Unlike autolock(), this blocks only user dragging; programmatic position writes still apply.

bool

the new setting; omit to read

Also spelled cy.autoungrabifyNodes.

Returns

the current setting when reading, this core when setting

cy.autounselectify

Get or set whether every element is unselectable regardless of its own selectable flag. Programmatic select() still applies.

bool

the new setting; omit to read

Returns

the current setting when reading, this core when setting

cy.panningEnabled

Get or set whether panning is allowed at all — programmatic pan() included. Use userPanningEnabled() to block only the gesture.

bool

the new setting; omit to read

Returns

the current setting when reading, this core when setting

cy.userPanningEnabled

Get or set whether the user may pan by dragging. Programmatic pan() is unaffected.

bool

the new setting; omit to read

Returns

the current setting when reading, this core when setting

cy.zoomingEnabled

Get or set whether zooming is allowed at all — programmatic zoom() included. Use userZoomingEnabled() to block only the gesture.

bool

the new setting; omit to read

Returns

the current setting when reading, this core when setting

cy.userZoomingEnabled

Get or set whether the user may zoom by wheel or pinch. Programmatic zoom() is unaffected.

bool

the new setting; omit to read

Returns

the current setting when reading, this core when setting

cy.boxSelectionIncludesLabels

Whether box selection considers label boxes as well as node bodies (round 16.5; v3's box-select-labels, reshaped as a core option — default off). Its sense follows boxSelectionMode: under 'contain' the label box must also be inside the band, under 'overlap' a label that merely crosses the band is enough.

bool

the setting to apply; omit to read it

Returns

the setting, or this when setting

cy.boxSelectionMode

What the box-selection gesture counts as caught: 'contain' (default, v3's) selects only elements wholly inside the band; 'overlap' selects anything the band touches — a node whose box intersects it, an edge any part of whose drawn path crosses it. Round 39.1.

Two notes on the boundary. This setting is read by the gesture only: cy.elementsInBox() stays the pure geometric containment query it has always been, so a programmatic caller's results do not change under this setting. And boxSelectionIncludesLabels reverses sense with the mode, because it can only mean one thing in each: under 'contain' the label box must also be inside, under 'overlap' a label that crosses the band is enough.

mode

the mode to set; omit to read the current one

Returns

the mode, or this when setting

Throws

if mode is neither 'contain' nor 'overlap'

cy.boxSelectionEnabled

Get or set whether the box-selection gesture is available.

bool

the new setting; omit to read

Returns

the current setting when reading, this core when setting

cy.pointerCursors

Get or set whether the canvas writes CSS cursors for the gesture affordances (round 89): grab over a draggable node and grabbing while it or the background is being dragged, pointer over any other interactive element, crosshair while box-selecting.

Three shapes. true (the default) takes the built-in map; false means the interaction layer never touches style.cursor at all — for an app that sets its own, which is what every v3 app did, since v3 set no cursors and left the affordance to userland. An object overrides individual entries ({ pan: 'move' }) and falls back to the defaults for the rest, where '' means inherit.

Idle over background is '' rather than default for that same reason: v4's canvas fills its container, so an inline cursor would override the app's own, and a v4 instance with nothing to say says nothing. A touch pointer never gets a cursor either way.

cursors

the setting to apply; omit to read the current one

Returns

the setting, or this core when setting

cy.selectionType

How user selection composes: 'single' (a tap or box replaces the selection) or 'additive' (taps toggle and boxes add, as if a multiple-select key were always held).

type

the mode to set; omit to read the current one

Returns

the mode, or this when setting

Throws

if type is neither 'single' nor 'additive'

cy.multiClickDebounceTime

The dbltap/onetap debounce window in ms (v3 parity; default 250).

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

ms

the window to set; omit to read it

Returns

the window, or this when setting

Throws

if ms is not a finite non-negative number

cy.wheelSensitivity

Wheel-zoom sensitivity: a multiplier on the zoom-per-wheel-tick exponent (v3 parity; default 1). Non-default values warn once per instance, as v3 does — a custom sensitivity tuned on one mouse/OS zooms unnaturally on others.

mult

the multiplier to set; omit to read it

Returns

the multiplier, or this when setting

Throws

if mult is not a finite positive number (0 would freeze the zoom, so the bound is strict where the threshold setters allow 0)

cy.desktopTapThreshold

Css px a mouse/pen press may move and still count as a tap (v3 parity; default 4).

px

the threshold to set; omit to read it

Returns

the threshold, or this when setting

Throws

if px is not a finite non-negative number

cy.touchTapThreshold

Css px a touch press may move and still count as a tap (v3 parity; default 8).

px

the threshold to set; omit to read it

Returns

the threshold, or this when setting

Throws

if px is not a finite non-negative number

cy.tapholdDuration

Unmoved-press duration before 'taphold' fires, ms (default 500 — v3's constant, configurable in v4).

ms

the duration to set; omit to read it

Returns

the duration, or this when setting

Throws

if ms is not a finite non-negative number

Environment Core

cy.isReady

Whether the render pipeline is usable yet. Always true on a headless instance; on a rendered one this flips when cy.ready resolves.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

true once rendering can proceed

cy.headless

Whether this instance has no container and therefore no GPU — the Node-testable mode, in which every model API works and the render, pick and image-export paths are no-ops or reject.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

true when running headless

cy.styleEnabled

Always true: v4 has no style-disabled mode, since the columnar model derives geometry from stored style channels rather than treating style as an optional layer. Kept so v3 code that checks it works.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

true

cy.hasCompoundNodes

Whether any node currently has a parent. Worth checking because the compound tier changes paint evaluation and draw order; the renderer pays nothing for compounds while this is false.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

true when the graph has at least one parent/child relation

cy.hasElementWithId

Whether an element with this id exists, via the O(1) id index — cheaper than getElementById( id ).nonempty() because no handle is materialized.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

id

the element id

Returns

true when the graph holds that element

cy.window

The window this instance renders into, or null when there is no DOM (Node). v3 parity, for extensions that need the hosting realm.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

the global window, or null outside a browser

cy.options

The options the instance was constructed with.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

the caller's own options object, held by reference — not a copy and not a defaults-resolved view, so an option the caller omitted reads back absent rather than as the default in force

cy.serialize

Export the live graph as the binary wire format (the buffer options.elements/add() accept directly): the columnar counterpart of json(). Carries ids, positions, selection state, the data() sidecar and — since round 39.2 — graph-level data(); style, viewport and scratch are not part of the wire.

Note the asymmetry in loading that graph data back: options. elements applies it, cy.add( buffer ) ignores it. Adding elements to a populated graph must not overwrite that graph's own data(), and there is no third answer that is right in both places.

Returns

a fresh little-endian buffer, self-contained (every edge endpoint indexes a node in the same payload) and directly loadable — derived geometry is flushed first, so parent boxes are the current ones rather than whatever was last materialized

cy.json

Export the graph as a plain object — elements, stylesheet, viewport, gating flags and graph-level data.

Export-only: the v3 import/restore form (json( obj )) is not supported, because rebuilding from a snapshot needs the stored element definitions that the columnar model deliberately does not keep. Use serialize() for the compact binary counterpart, which can be fed back in.

flat

when true, elements export as one flat array instead of { nodes, edges } (v3's option)

Returns

the exported graph

Throws

if given anything but a boolean — the guard that catches an attempted json( obj ) import

cy.unmount

Detach the renderer: the instance becomes headless (the model is CPU-canonical, so nothing is lost). No-op when already headless.

cy.mount

(Re)attach a renderer to a container. Re-mounting to a different container unmounts first; the fresh renderer re-uploads every column from the CPU-canonical model and rebuilds all glyph runs.

container

the element to render into

Returns

this

Throws

if no container is given, if the instance was built directly rather than through the cytoscape factory (there is no renderer to attach), or if WebGPU is unavailable — mounting is the one way a headless instance can demand a GPU after construction

cy.container

The DOM element this instance renders into, or null when headless or unmounted.

Returns

the container element, or null

cy.width

The rendered width in CSS px. Headless instances report the configured headlessWidth (default 800), so viewport maths works without a DOM.

Returns

the viewport width in CSS px

cy.height

The rendered height in CSS px. Headless instances report the configured headlessHeight (default 600).

Returns

the viewport height in CSS px

cy.destroy

Tear the instance down: emit destroy, drop every listener, and release the pointer handler and the renderer (with its GPU resources). Idempotent. The store is left intact but the instance must not be used afterwards.

Returns

this core

cy.destroyed

Whether destroy() has run.

Returns

true once destroyed

Collection

Basics Collection

eles.length

How many elements this collection holds.

Core reference & identity Collection

eles.cy

The core this collection belongs to.

Returns

the instance that owns these elements — a collection cannot span two cores, so this is also the identity a set operation against a foreign collection would violate

eles.collection

An empty collection in the same core.

Takes no arguments, and throws if given any — the same round-64 guard as cy.collection(), since this delegate shared the same silently-ignored-argument shape.

Returns

a fresh empty collection bound to this core — the seed for building a set up by union

Throws

if called with any argument (v3's building forms are not ported; the message names the replacements)

eles.hasElementWithId

Whether this collection contains an element with the given id.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

id

the element id

Returns

true when a member has that id

eles.indexOf

Index of an element within this collection.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

ele

the element to find; only its first element is used

Returns

the index, or -1 when it is not in this collection

eles.indexOfId

Position of the element with this id within the collection.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

id

the element id

Returns

the index, or -1 when absent

Iteration Collection

eles.size

The number of elements — the method form of length.

Returns

the element count

eles.empty

Whether the collection holds no elements.

Returns

true when empty

eles.nonempty

Whether the collection holds at least one element.

Returns

true when non-empty

eles.forEach

Call fn for each element. Returning false from the callback stops the iteration early, as in v3.

With no thisArg the callback is plain-called, so this is undefined inside it — v3's semantics, and deliberate: rebinding the receiver per element costs about 2x on large collections.

fn

( ele, i, eles ); return false to stop

thisArg

optional receiver for the callback

Also spelled eles.each.

Returns

this collection, for chaining

eles.toArray

The elements as a plain array of length-1 collections.

Returns

a new array of the members

eles.slice

A sub-range of the collection, with Array#slice semantics (negative indices count from the end).

start

first index, inclusive

end

last index, exclusive

Returns

the sub-range as a new collection

eles.sort

A copy sorted by a comparator. Note that sort order is a property of the collection, not of drawing: v4 draw order is structural and there is no z-index.

sortFn

( a, b ) comparator over length-1 collections; a non-function is ignored and returns this collection unchanged

Returns

a new, sorted collection

eles.eq

The element at an index, as a length-1 collection.

i

the index

Returns

that element, or an empty collection when out of range

eles.first

The first element, as a length-1 collection.

Returns

the first element, or an empty collection

eles.last

The last element, as a length-1 collection.

Returns

the last element, or an empty collection

eles.map

Map each element through fn into a plain array.

fn

( ele, i, eles )

thisArg

optional receiver for the callback

Returns

an array of the results

eles.some

Whether any element satisfies the predicate. Short-circuits.

fn

( ele, i, eles ) => boolean

thisArg

optional receiver for the callback

Returns

true when at least one element matches

eles.every

Whether every element satisfies the predicate. Short-circuits, and is vacuously true for an empty collection.

fn

( ele, i, eles ) => boolean

thisArg

optional receiver for the callback

Returns

true when all elements match

Identity Collection

eles.id

The first element's id. Cached on the handle, so it stays readable after the element is removed.

Returns

the id, or undefined when the collection is empty

eles.group

The first element's group. Cached on the handle, so it stays readable after removal.

Returns

'nodes' or 'edges', or undefined when empty

eles.json

Plain-object form of the first element (undefined when empty).

Returns

the definition-form object for the first element, or undefined when the collection is empty; it round-trips through cy.add(), which is the supported restore path since cy.json()'s import form is not in v4

eles.jsons

Plain-object form of every element.

Returns

one object per element, in collection order — the plural of json(), not a graph-level export

eles.isNode

Whether the first element is a node.

Returns

true for a node

eles.isEdge

Whether the first element is an edge.

Returns

true for an edge

eles.isLoop

Whether the first element is a self-loop — an edge whose source and target are the same node.

Returns

true for a loop edge; false for nodes and removed elements

eles.isSimple

Whether the first element is a non-loop edge.

Returns

true for an edge between two distinct nodes

eles.removed

Whether the first element has been removed from the graph. A removed element's handle stays usable — reads are no-ops or undefined, and the cached id()/group() remain readable.

Returns

true when the element is no longer in the graph

eles.inside

Whether the first element is still in the graph — the complement of removed().

Returns

true when the element is live

Comparison Collection

eles.same

Whether both collections hold exactly the same elements, ignoring order.

other

the collection to compare against

Also spelled eles.equal, eles.equals.

Returns

true when the element sets are equal

eles.anySame

Whether the two collections share at least one element.

other

the collection to compare against

Returns

true when the sets intersect

eles.contains

Whether every element of other is also in this collection.

other

the candidate subset

Also spelled eles.has.

Returns

true when other is contained

eles.allAreNeighbors

Whether every element of other is in this collection's neighborhood.

other

the elements to test

Also spelled eles.allAreNeighbours.

Returns

true when all of them are neighbors

eles.allAre

Whether every element matches the criterion.

criterion

a query object or an ( ele ) => boolean predicate (there are no selector strings in v4)

Returns

true when all elements match

eles.is

Whether any element matches the criterion.

criterion

a query object or an ( ele ) => boolean predicate

Returns

true when at least one element matches

Building and filtering Collection

eles.union

The union of the two collections, deduped.

other

the collection to add

Also spelled eles.u, eles.or, eles.add, eles.merge.

Returns

a new collection holding both sets

eles.difference

This collection's elements that are not in other.

other

the collection to subtract

Also spelled eles.not, eles.subtract, eles.unmerge, eles.relativeComplement.

Returns

a new collection

eles.intersection

The elements present in both collections.

other

the collection to intersect with

Also spelled eles.intersect, eles.and.

Returns

a new collection

eles.symmetricDifference

The elements in exactly one of the two collections.

other

the other collection

Also spelled eles.symdiff, eles.xor.

Returns

a new collection

eles.filter

The subset matching the criterion.

A structured query object is answered directly off the flags column — no per-element handles and no closures — while a predicate function is called per element. v4 has no selector strings, so those two forms cover what v3 spelled with a selector.

criterion

a query object ({ selected: true }, { data: { weight: { gt: 0.5 } } }, …) or an ( ele, i, eles ) => boolean predicate

thisArg

optional receiver, for the predicate form

Returns

a new collection of the matching elements

Throws

if a query object carries an unknown key — a typo must not silently match everything

eles.nodes

The nodes in this collection, optionally filtered.

criterion

a query object or predicate; omit for all nodes

Returns

a new collection of nodes

eles.edges

The edges in this collection, optionally filtered.

criterion

a query object or predicate; omit for all edges

Returns

a new collection of edges

eles.getElementById

Find a member by id. This is a linear scan of the collection; use cy.$id( id ) for the O(1) whole-graph index.

id

the element id

Returns

a collection of one element, or an empty collection

eles.absoluteComplement

All elements of the graph not in this collection.

Also spelled eles.complement, eles.abscomp.

Returns

the complement against the whole graph, not against any enclosing collection — which is what the absolute in the name is distinguishing

eles.diff

Three-way set difference against another collection.

other

the collection to compare with

Returns

{ left: only in this, right: only in other, both: in both }

eles.reduce

Fold the collection into a single value.

fn

( accumulator, ele, i, eles )

initial

the starting accumulator (required, unlike Array#reduce)

Returns

the final accumulator

eles.max

The element maximizing valFn, with its value.

valFn

( ele, i, eles ) => number

thisArg

optional receiver for the callback

Returns

{ value, ele }, or { value: -Infinity, ele: undefined } when the collection is empty

eles.min

The element minimizing valFn, with its value.

valFn

( ele, i, eles ) => number

thisArg

optional receiver for the callback

Returns

{ value, ele }, or { value: Infinity, ele: undefined } when the collection is empty

Position and dimensions Collection

eles.position

Get or set the first element's model-space position (nodes only).

Reading a compound parent settles pending auto-bounds first, so the derived centre is current. Reading a node whose position is under a GPU-owned tween (an offloaded position animation or a live force layout) reports the stale mirror until the tween settles — the motion-staleness rule; geometry channels like width() do not behave this way.

dim

'x' or 'y' to read/write one axis, or a { x, y } object to write both; omit to read the pair

value

the new coordinate, with the 'x'/'y' form

Also spelled eles.modelPosition, eles.point.

Returns

the position or coordinate when reading (undefined for edges and removed elements), this collection when writing

eles.positions

Set every node's position, from a constant or per-element function.

pos

a { x, y } for all of them, or ( ele, i ) => ( { x, y } )

Also spelled eles.modelPositions, eles.points.

Returns

this collection, for chaining

Animation Collection

eles.animate

Animate these elements' style and/or position to explicit targets over duration ms, easing the normalized time.

There is no queue (round 21): the animation starts immediately, animations on disjoint channels run concurrently, and starting one that overlaps a running animation's channels stops the older one in place — its promise resolves, its values freeze, and the new animation captures from there. Sequence with await animation( … ).play() rather than by queueing.

Animatable: position; opacity (both groups); node background-color/border-color/border-width, edge line-color; and — since round 25 — the geometry numerics node width/height, edge width, compound padding and font-size. Colours interpolate in OKLab, matching the colour mappers, which deliberately differs from v3's per-channel sRGB tweening.

Easings are names, not functions: v3's full enum plus cubic-bezier( … ), CSS linear( … ) and spring( bounce ). A custom easing function is rejected — a closure cannot cross to the GPU, so accepting one would mean a curve that silently depended on whether the animation got offloaded.

opts

targets (position, style, plus the viewport forms on cy.animate), duration, easing, delay, complete

Returns

this collection, for chaining; use animation() when you want the handle

See

Collection#animation for the handle form with promise/pause/resume/reverse

eles.animation

Build an animation for these elements without starting it.

opts

the tween targets (position, style) plus duration, delay, easing and complete

Returns

the handle; nothing runs until play()

eles.delay

A no-op tween — a timed pause that touches no channels, so it composes with any running animation (round 21: use delayAnimation().play() + await to sequence).

duration

the pause in ms

complete

called when it elapses

Returns

this collection, for chaining

eles.delayAnimation

Like delay, but returns the handle instead of chaining.

duration

the pause in ms

complete

called when it elapses

Returns

the handle; nothing runs until play()

eles.animated

True when any of these elements has a running animation.

Returns

whether any element here is animating — not whether all are, and not whether the viewport is (that is cy.animated())

eles.stop

Stop every running animation on these elements (round 21: no queue — the v3 clearQueue argument is gone).

jumpToEnd

apply each animation's final values instead of freezing each channel where its tween reached

Returns

this collection, for chaining

eles.shift

Offset positions by a vector or along one axis.

dim

a { x, y } delta, or 'x' / 'y' with value

value

the offset, when dim names an axis

Returns

this collection, for chaining

eles.relativePosition

Compound-relative position: the model position minus the immediate parent's (derived) position — the model position for orphans and compound-free graphs (round 14.3, v3 semantics).

dim

omit to read the pair, 'x' / 'y' to read one axis, or pass a { x, y } (with no value) to write both

value

the relative coordinate to write, when dim names an axis

Also spelled eles.relativePoint.

Returns

the position or coordinate when reading, this when writing

eles.renderedPosition

Get or set the first element's position in rendered (CSS px) space — position() put through the current pan and zoom. Writing unprojects back to model space, so the element lands under the given screen point at the current viewport.

dim

'x'/'y', or a { x, y } object to write both; omit to read the pair

value

the new coordinate, with the 'x'/'y' form

Also spelled eles.renderedPoint.

Returns

the rendered position when reading, this collection when writing

eles.width

The first element's width — a node's model-space width, or an edge's stroke width.

For a compound parent this is the content width, with the padding subtracted from the stored drawn box (v3's autoWidth). Mid-tween this reads the exact current value: geometry tweens are CPU-canonical every tick and never leased to the GPU (round 25), so unlike a position tween there is no staleness window.

Returns

the width, or undefined when empty or removed

See

Collection#outerWidth to include the border

eles.height

The first element's height — a node's model-space height, or an edge's stroke width (as in v3, where an edge's height is its width).

For a compound parent this is the content height: the column stores the padded drawn box, so the padding is subtracted here (v3's autoHeight). Mid-tween this reads the exact current value: geometry tweens are CPU-canonical every tick and never leased to the GPU (round 25).

Returns

the height, or undefined when empty or removed

eles.data

data() over the sidecar columns. id (and source/target on edges) are first-class and immutable — reading them works, writing them throws. Setters apply to every element in the collection and emit data per element; a write refreshes data-mapped labels. The whole-object read returns a built snapshot, not the store's internals — and the same snapshot until a data write (or a reparent/re-point) invalidates it, so mutating it never corrupts the store but is visible to the mutator until the next write (v3 hands out its live internal object here, where mutation corrupts the actual store — v4's exposure is strictly narrower).

key

omit it (read the first element's whole object), a key (read it), or an object of keys to merge (write)

value

with a string key: the value to write; omitting it reads the key, and an explicit undefined clears it

Also spelled eles.attr.

Returns

the read value, or this collection when writing

eles.removeData

Remove sidecar data keys.

names

space-separated key names; omit to clear every key

Also spelled eles.removeAttr.

Returns

this collection, for chaining

eles.scratch

Per-element scratchpad (plain JS, not a column): scratch() reads the first element's whole object, scratch(ns) one namespace, scratch(ns, val) / scratch(obj) write to every element.

args

the form to take: nothing (read the whole object), a namespace (read it), a namespace and a value (write it to every element), or one object (merge its keys into every element)

Returns

the reader forms answer the first element — the whole scratch object under no argument, one namespace's value under scratch(ns), undefined when the collection is empty — while the writer forms return this collection for chaining

eles.removeScratch

Delete scratchpad keys from every element.

namespace

the key to remove; omit to clear each element's whole scratchpad

Returns

this collection, for chaining

Style (read-only) Collection

eles.style

Resolved style read off the stored channels — all of the first element's group props.

Resolved style read off the stored channels — one value. A bypassed prop reads its bypass value, since a bypass writes stored truth (round 63).

name

the property to read, dash-case or camelCase

Set a per-element style bypass on every element (round 63.4 — the v3 spelling, returned). Sugar over the stylesheet's bypasses section: the value must be a constant (mappers belong in the sheet's group blocks), the entry is keyed by the element's id and survives remove/re-add, it beats every sheet rule including the default sheet's selection color, and it exports from cy.json().

name

the property to bypass, dash-case or camelCase

value

the constant value to pin

Set several per-element style bypasses on every element (round 63.4). The object form of the setter: each key–value pair joins the element's bypass declaration.

props

prop → constant value, dash-case or camelCase keys

Also spelled eles.css.

Returns

the whole group's props (numbers for numeric props, rgb()/rgba() strings for colors, keywords otherwise), or undefined when the collection is empty

Throws
  • on a mapper value, a global font prop, a transition config prop, a wrong-group prop, or an invalid value

  • as the name/value form does, per prop

eles.removeStyle

Remove per-element style bypasses from every element (round 63.4 — v3's removeStyle). The sheet-resolved values return through the normal apply, transitions included.

name

the property to un-bypass, dash-case or camelCase; omit to clear each element's whole bypass declaration

Also spelled eles.removeCss.

Returns

this collection, for chaining

eles.renderedStyle

Like style(), but with length props (width, height, border-width, font-size) scaled into rendered (on-screen) px by the zoom.

name

a property name; omit for the whole group

Also spelled eles.renderedCss.

Returns

the rendered-space value, or the whole group's props

eles.numericStyle

The numeric value of a numeric style prop.

name

a numeric style property

Returns

the number, or undefined when the collection is empty or the prop belongs to the other group

Throws

if the prop resolves to a colour or a keyword rather than a number

eles.effectiveOpacity

The rendered opacity: a node's own opacity times its ancestors' (v3's product rule — the store keeps the folded value in the column, round 14.4); an edge's own opacity (edges have no parent).

Returns

the opacity actually rendered, which is what transparent() tests against 0 — not the declared opacity style value, which style('opacity') reads; undefined when empty or removed

eles.transparent

Whether the first element is fully transparent — its effective opacity, with compound ancestors folded in, is exactly 0.

Returns

true when invisible through opacity

eles.takesUpSpace

The space tier (round 22): shown elements occupy space — they join bb/fit and size their compound parents — even when visibility: 'hidden' keeps them from rendering. display-tier hide() clears it.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

whether the element occupies space — since round 22 this can differ from visible(), which is the paint tier

eles.interactive

Whether the element can be interacted with: visible and not pointer-transparent (events: 'no' — round 20.2).

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

whether any pointer path will resolve to this element; it rides visible(), so an element hidden either way is inert

eles.label

The node's resolved label text ('' when none); read-only in the prototype.

Returns

the resolved text of the first element's label — '' when it has none (a labelled-but-empty label reads the same), and undefined when the collection is empty or the element was removed

eles.padding

v3-parity accessor: node padding. Leaves have no padding in v4 (no compound-free padding prop); parents answer the resolved auto-bounds padding (round 14.3).

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

the resolved padding in model px — 0 for leaves and for any graph with no compounds at all, the derived value for a parent; undefined when the collection is empty

eles.paddedWidth

The drawn box: core dims + 2 x padding (v3's paddedWidth).

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

the padded width — identical to width() for leaves, which have no padding; undefined when empty or removed

eles.paddedHeight

The drawn box height: content height plus twice the padding (v3's paddedHeight). Identical to height() for leaves, which have no padding.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

the padded height, or undefined when empty or removed

eles.outerWidth

The full drawn width including the border — padded width plus the border width. This is the box bounds and endpoint clipping use.

Returns

the outer width, or undefined when empty or removed

eles.outerHeight

The full drawn height including the border.

Returns

the outer height, or undefined when empty or removed

eles.boundingBox

The model-space box enclosing every element of the collection.

Labels are included by default (round 16.4) — v3 excluded them unless asked. Node label terms are exact (the laid text block at its anchor plus text-box padding); edge label terms are conservative (a rotation-safe radius about both endpoints), so a box may be slightly larger than the ink but never smaller. The box also covers ghost offsets, overlay/underlay padding and outlines.

options

{ includeLabels } (default true)

Returns

{ x1, y1, x2, y2, w, h } in model coordinates

Throws

on an unknown option key — a typo must not silently change fit semantics

See

Collection#labelBoundingBox for the label box alone

eles.labelBoundingBox

The exact laid label boxes of this collection's elements, unioned (round 16.4 — the v4 form of v3's text-metrics surface): node labels at their anchors, edge mid-labels at the drawn midpoint, end labels conservatively about their endpoint. Empty (zero) when nothing is labelled. Headless dims are estimates (recorded).

eles.renderedBoundingBox

boundingBox() transformed into rendered (on-screen) coordinates.

options

as boundingBox(): { includeLabels }, default true; an unknown key throws

Also spelled eles.renderedBoundingbox.

Returns

the rendered-space box

eles.renderedWidth

width() scaled by the current zoom — the on-screen width in CSS px.

Returns

the rendered width, or undefined when empty or removed

eles.renderedHeight

height() scaled by the current zoom.

Returns

the rendered height, or undefined when empty or removed

eles.renderedOuterWidth

outerWidth() scaled by the current zoom.

Returns

the rendered outer width, or undefined when empty or removed

eles.renderedOuterHeight

outerHeight() scaled by the current zoom.

Returns

the rendered outer height, or undefined when empty or removed

eles.midpoint

Midpoint of the edge: the curve/route midpoint for curved edges (v3's rs.mid rules per family), the endpoint-center average for straight ones.

Returns

the point a mid-label and a mid-arrow anchor at, in model space; undefined for non-edges. Mid-tween it inherits the position lease's staleness, like the endpoints it derives from

eles.renderedMidpoint

midpoint() in rendered (CSS px) space.

Returns

the rendered midpoint, or undefined for non-edges

eles.sourceEndpoint

The edge's source-side endpoint in model space, resolved through the route evaluator — so it accounts for curve family, node boundary clipping, haystack offsets and any manual source-endpoint.

A straight edge answers the node boundary along the chord between the node centres, pulled back by the arrow shape's spacing (round 55 landed the boundary, round 56 the spacing) — v3's rs.arrowStartX/Y. That is the arrow point, not the drawn line's end: the line stops gap behind the boundary, further back again, which is what makes a hollow head read as one shape.

Returns

the endpoint, or undefined for non-edges

eles.targetEndpoint

The edge's target-side endpoint in model space, resolved through the route evaluator — so it accounts for curve family, node boundary clipping, haystack offsets and any manual target-endpoint.

A straight edge answers the node boundary along the chord between the node centres, pulled back by the arrow shape's spacing (round 55 landed the boundary, round 56 the spacing) — v3's rs.arrowStartX/Y. That is the arrow point, not the drawn line's end: the line stops gap behind the boundary, further back again, which is what makes a hollow head read as one shape.

Returns

the endpoint, or undefined for non-edges

eles.renderedSourceEndpoint

sourceEndpoint() in rendered (CSS px) space.

Returns

the rendered endpoint, or undefined for non-edges

eles.renderedTargetEndpoint

targetEndpoint() in rendered (CSS px) space.

Returns

the rendered endpoint, or undefined for non-edges

eles.controlPoints

The edge's curve control points (model coords): one for a bundled bezier, two for a self-loop, the control list for an unbundled bezier, undefined otherwise — v3's getControlPoints surface (segments/taxi answer segmentPoints() instead).

Returns

the control points in model space, or undefined when the edge has none — which covers straight edges, segments/taxi routes, and a straight edge carrying manual endpoints (the 12c n = 0 chord)

eles.renderedControlPoints

controlPoints() in rendered (CSS px) space.

Returns

the rendered control points, or undefined when the edge has none

eles.segmentPoints

The edge's segment points (model coords) — v3's getSegmentPoints: defined for segments and taxi edges (taxi derives its points), undefined otherwise.

Returns

the interior route points in model space — derived ones for taxi, which computes rather than declares them — or undefined for every other family

eles.renderedSegmentPoints

segmentPoints() in rendered (CSS px) space.

Returns

the rendered segment points, or undefined when the edge has none

Selection Collection

eles.selected

Whether the first element is selected.

Returns

true when selected

eles.selectable

Whether the first element may be selected by the user. The graph-wide cy.autounselectify() overrides this for user gestures.

Returns

true when selectable

eles.select

Select every selectable element, emitting select for each one that changed. Unselectable elements are skipped.

Returns

this collection, for chaining

eles.unselect

Deselect every element, emitting unselect for each one that changed.

Also spelled eles.deselect.

Returns

this collection, for chaining

eles.selectify

Make these elements selectable.

Returns

this collection, for chaining

eles.unselectify

Make these elements unselectable. Does not deselect them; call unselect() for that.

Returns

this collection, for chaining

Grab / lock Collection

eles.grabbable

Pannable elements are not draggable, so pannable overrides grabbable (as in v3).

Returns

whether a drag gesture would move this element — the effective answer, so a grabbable-but-pannable element reads false here while json() reports the raw field

eles.grabbed

Whether the first element is currently held by a drag gesture.

Returns

true while grabbed

eles.grabify

Make these elements grabbable.

Returns

this collection, for chaining

eles.ungrabify

Make these elements ungrabbable — the user can no longer drag them, while programmatic position writes still apply.

Returns

this collection, for chaining

Visibility Collection

eles.visible

Whether the first element renders (round 22: the derived FLAG_DRAWN — shown AND not visibility: 'hidden' on self or, for nodes, any ancestor; edges additionally fold their endpoints, v3's rule). The renderer's cull pass and CPU picking mask on the same bit, so an element that is not visible() neither draws nor picks. For space-tier state (in the bb, sizing its compound parent) see takesUpSpace() — an invisible element keeps its space.

Returns

whether the element draws and picks; false for a removed element, for an edge either of whose endpoints is hidden, and for a node under a hidden or invisible ancestor

eles.hidden

The complement of visible().

Returns

true when the first element does not draw

eles.show

Show these elements — the display tier, v3's structural display: element. Shown elements take up space again, rejoin bounds and fit, and re-fan their bezier bundles.

For paint-only invisibility that keeps space and bundle ranks, use the visibility style property instead (round 22), and for a fade use an opacity transition.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

this collection, for chaining

eles.hide

Hide these elements structurally — v3's display: none. They stop drawing and picking, leave the bounding box and their ancestors' auto-bounds, and their bezier bundles re-fan without them. Descendants of a hidden node are gated too.

Public in v4 by decision (round 90) — v3 kept its counterpart internal.

Returns

this collection, for chaining

eles.locked

Whether the first element is locked — immovable, by layouts, position writes and position tweens alike (one rule since round 114.3: every layout holds a locked node where it is and keeps it in the layout's structure; force treats it as an obstacle its settle separates the others from). A locked child stays where it is when its compound parent is positioned, shifted or dragged — its own subtree with it — and the parent re-derives about the stayers and the movers (116.3, v3's rule). True for every node while cy.autolock( true ) is set, as in v3; the flag column alone is what { locked: true } filters read.

Returns

true when locked

eles.lock

Lock these elements against movement.

Returns

this collection, for chaining

eles.unlock

Unlock these elements.

Returns

this collection, for chaining

Active / pannable Collection

eles.active

Whether the first element is in the transient pressed ("active") state.

Returns

the pressed flag the pointer layer sets while a press is held — transient interaction state, not a persisted property

eles.pannable

Whether dragging the first element pans the graph instead of grabbing it.

Returns

the raw pannable flag; because pannable overrides grabbable, a true here forces grabbable() false

eles.panify

Make dragging these elements pan the viewport instead of moving them. Pannable overrides grabbable, as in v3.

Returns

this collection, for chaining

eles.unpanify

Stop these elements from panning the viewport when dragged, so a grabbable one becomes draggable again.

Returns

this collection, for chaining

Graph manipulation Collection

eles.remove

Remove these elements from the graph; incident edges of removed nodes cascade. Already-removed elements are skipped (no second remove event).

Returns

the elements actually removed — the closure, so it can be larger than the receiver: removing a parent brings its descendants, and removing a node brings its incident edges. The returned refs are dead by construction (v4 removals are terminal), so only their cached id()/group() still read

eles.move

Move elements in place, keeping slot, id and data: { parent } re-parents nodes (null orphans them; the compound move, round 14.2 — emits moveout before and move after per changed node), while { source, target } re-points edges. As in v3 the modes are exclusive — a parent key takes precedence. An unknown parent id is a silent no-op (v3); a cyclic assignment warns and drops (the hierarchy rule).

opts

{ parent } to re-parent nodes (null orphans them), or { source, target } to re-point edges; parent wins if both are given

Returns

this collection, for chaining

Traversal Collection

eles.source

The source node of the first edge.

Returns

the source node, or an empty collection for a non-edge

eles.target

The target node of the first edge.

Returns

the target node, or an empty collection for a non-edge

eles.sources

The source nodes of every edge in the collection, deduped.

Returns

the source nodes

eles.targets

The target nodes of every edge in the collection, deduped.

Returns

the target nodes

eles.connectedEdges

Every edge incident on the nodes in this collection, deduped — answered off the CSR adjacency index, so it is O(incident edges) rather than a scan. Loops appear once.

criterion

an optional query object or predicate to filter the result

Returns

the incident edges

eles.connectedNodes

The endpoint nodes of every edge in this collection, deduped.

criterion

an optional query object or predicate to filter the result

Returns

the endpoint nodes

eles.outgoers

The immediate outgoing neighbourhood: the edges leaving these nodes plus the nodes they point at. One hop only — use successors() for the transitive closure.

criterion

an optional query object or predicate to filter the result

Returns

the outgoing edges and their target nodes

eles.incomers

The immediate incoming neighbourhood: the edges arriving at these nodes plus the nodes they come from. One hop only — use predecessors() for the transitive closure.

criterion

an optional query object or predicate to filter the result

Returns

the incoming edges and their source nodes

eles.neighborhood

The open neighbourhood: the incident edges and the nodes on their far ends, ignoring edge direction, excluding the collection's own elements.

criterion

an optional query object or predicate to filter the result

Also spelled eles.openNeighborhood.

Returns

the neighbouring edges and nodes

See

Collection#closedNeighborhood to include these nodes

eles.closedNeighborhood

The open neighbourhood plus this collection's own nodes.

criterion

an optional query object or predicate to filter the result

Returns

the closed neighbourhood

Compound hierarchy Collection

eles.parent

Immediate parents of every node in the collection (unique). v4 always returns a proper collection — v3's single-element raw-ref shortcut (which also ignored the selector argument) is not ported. *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the immediate parents

eles.parents

All ancestors, level by level: every nearest parent first, then the grandparents, and so on (v3's iterated-parent() order). *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Also spelled eles.ancestors.

Returns

the ancestors, nearest first

eles.children

Direct children of every node, in link order per parent. *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the children

eles.descendants

The subtree below every node in pre-order, excluding the nodes themselves. *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the descendants

eles.siblings

Nodes sharing a parent with the collection's nodes, excluding them; orphans are nobody's siblings (v3). *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the siblings

eles.orphans

The collection's nodes without a parent. *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the parentless nodes

eles.nonorphans

The collection's nodes that have a parent. *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the parented nodes

eles.commonAncestors

Ancestors common to every element, closest first (an edge in the collection has no ancestors, so it empties the result — v3). *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the shared ancestors, closest first

eles.isParent

Whether the first element is a node with at least one child.

Returns

v3's :parent as a predicate; false for edges and for removed elements, which are nodes of no hierarchy

eles.isChildless

Whether the first element is a node with no children.

Returns

v3's :childless; false for edges, so it is not the plain negation of isParent()

eles.isChild

Whether the first element is a node with a parent.

Returns

v3's :child; false for edges and removed elements

eles.isOrphan

Whether the first element is a node without a parent.

Returns

v3's :orphan; false for edges, so it is not the plain negation of isChild()

DAG traversal Collection

eles.roots

Collection nodes with no non-loop incoming edge (whole-graph incidence, as in v3). *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the source nodes

eles.leaves

Collection nodes with no non-loop outgoing edge. *

criterion

an optional query object or predicate applied to the result, exactly as filter() takes it

Returns

the sink nodes

eles.successors

Everything reachable by following outgoing edges, transitively — the edges and nodes of the forward closure, excluding these nodes themselves (unless a cycle reaches them).

criterion

an optional query object or predicate to filter the result

Returns

the reachable edges and nodes

eles.predecessors

Everything that reaches these nodes by following incoming edges, transitively.

criterion

an optional query object or predicate to filter the result

Returns

the edges and nodes of the backward closure

Edge relations Collection

eles.edgesWith

The edges connecting this collection's nodes with others, in either direction.

others

the nodes on the far side (a collection, never a selector string)

Returns

the connecting edges

eles.edgesTo

The edges running from this collection's nodes to othersedgesWith() restricted by direction.

others

the target-side nodes

Returns

the directed connecting edges

eles.parallelEdges

The edges sharing endpoints with these edges, in either direction — including each edge itself. These are the edges a bezier bundle fans apart.

criterion

an optional query object or predicate to filter the result

Returns

the parallel edges

eles.codirectedEdges

The parallel edges pointing the same way — same source and same target — including each edge itself.

criterion

an optional query object or predicate to filter the result

Returns

the codirected edges

Connected components Collection

eles.components

Connected components within this collection (undirected), each as a collection of the reached nodes plus the collection's edges internal to that component.

root

restricts the seed nodes; omit to seed from every node

Also spelled eles.componentsOf.

Returns

one collection per component

eles.component

The whole-graph connected component containing the first element.

Returns

the component as nodes and their connecting edges, computed over the whole graph rather than within this collection; an empty collection when this one is empty

Layouts Collection

eles.layoutDimensions

Node dimensions for layout spacing, as v3's layoutDimensions — the body, plus the label box under nodeDimensionsIncludeLabels: true (114.1 made labels the default; 115 restored v3's body-only default).

options

{ nodeDimensionsIncludeLabels: true } to include the label box

Returns

the first element's { w, h }

eles.layoutPositions

Apply a layout's position function to this collection's nodes with the standard layout options (spacingFactor, transform, fit/zoom/pan, animate) and the layoutstart/layoutready/layoutstop event flow — v3's helper. With animate: true the viewport animates concurrently (a fit targets the bounding box at the final positions, as v3 does).

layout

the layout instance the lifecycle events carry as event.layout; it is not called back, only reported

options

the standard layout options (spacingFactor, transform, fit/padding, zoom/pan, animate, animationDuration, animateFilter)

fn

( node, i ) => position, evaluated once per positioned node; parents are excluded (auto-bounds derive them)

Returns

this collection, for chaining

eles.layout

A layout scoped to this collection.

options

the layout options, as cy.layout(); eles is set to this collection

Also spelled eles.makeLayout, eles.createLayout.

Returns

the layout instance; nothing runs until run()

Graph algorithms Collection

eles.breadthFirstSearch

Breadth-first search from one or more roots over this collection's subgraph, walking slot-native over the CSR adjacency.

args

v3's option shape ({ roots, visit, directed }) or the positional form; roots is a collection, since v4 has no selector strings

Also spelled eles.bfs.

Returns

{ path, found }

eles.depthFirstSearch

Depth-first search from one or more roots. Same options as breadthFirstSearch.

args

{ roots, visit, directed } or the positional form

Also spelled eles.dfs.

Returns

{ path, found }

eles.dijkstra

Dijkstra shortest paths from a root over non-negative weights.

args

{ root, weight, directed }; weight is a plain function ( edge ) => number

Returns

{ distanceTo, pathTo }

eles.aStar

A* shortest path between two nodes.

options

{ root, goal, weight, heuristic, directed }, with weight and heuristic as plain functions

Returns

{ found, distance, path }

eles.bellmanFord

Bellman–Ford shortest paths, which unlike Dijkstra tolerates negative weights and reports negative cycles.

options

{ root, weight, directed }

Returns

{ distanceTo, pathTo, hasNegativeWeightCycle, negativeWeightCycles }

eles.floydWarshall

Floyd–Warshall all-pairs shortest paths. O(n³) — for a single source prefer dijkstra/bellmanFord. Async (round 65): the expensive whole-graph tier returns promises, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the maths runs; 'cpu' is the reproducible reference.

options

{ weight, directed, executor }

Returns

a promise of the { distance, path } accessors

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.kruskal

Kruskal's minimum spanning tree/forest.

weight

( edge ) => number; defaults to unit weights

Returns

the spanning forest's nodes and edges

eles.tarjanStronglyConnected

Tarjan's strongly connected components. Implemented iteratively, so deep graphs cannot overflow the JS stack.

Also spelled eles.tsc, eles.tscc, eles.tarjanStronglyConnectedComponents.

Returns

{ components, cut }

eles.hopcroftTarjanBiconnected

Hopcroft–Tarjan biconnected components and articulation points.

Also spelled eles.htbc, eles.htb, eles.hopcroftTarjanBiconnectedComponents.

Returns

{ components, cut }

eles.hierholzer

Hierholzer's Eulerian path/circuit.

args

{ root } or the positional form

Returns

{ found, trail }

eles.kargerStein

Karger–Stein randomized minimum cut. Randomized, so repeated runs may differ.

Returns

{ cut, components, partition1, partition2 }

eles.pageRank

PageRank over the (directed) subgraph. Async (round 65): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the power method runs; 'cpu' is the reproducible reference.

options

{ dampingFactor, precision, iterations, executor }

Returns

a promise of { rank }, a per-node accessor

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.degreeCentrality

Degree centrality of one node relative to the collection.

options

{ root, weight, alpha, directed }

Also spelled eles.dc.

Returns

{ degree }, or { indegree, outdegree } when directed

eles.degreeCentralityNormalized

Degree centrality for every node, normalized to [0, 1].

options

{ weight, alpha, directed }

Also spelled eles.dcn, eles.degreeCentralityNormalised.

Returns

a degree accessor, or indegree/outdegree when directed

eles.closenessCentrality

Closeness centrality of one node — the reciprocal of its summed shortest-path distances to the rest of the collection.

options

{ root, weight, directed, harmonic }

Also spelled eles.cc.

Returns

the closeness score

eles.closenessCentralityNormalized

Closeness centrality for every node, normalized to [0, 1]. Async (round 69): the whole-collection form is the O(n³) all-pairs tier, so like floydWarshall it returns a promise and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the relaxation runs; 'cpu' is the reproducible reference. The single-root closenessCentrality stays synchronous.

options

{ weight, directed, harmonic, executor }

Also spelled eles.ccn, eles.closenessCentralityNormalised.

Returns

a promise of a closeness accessor

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.betweennessCentrality

Betweenness centrality — how often each node lies on shortest paths between other pairs. Async (round 65): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the Brandes sweep runs. Weighted runs have no GPU path: 'auto' uses the CPU and an explicit 'gpu' rejects.

options

{ weight, directed, executor }

Also spelled eles.bc.

Returns

a promise of the { betweenness, betweennessNormalized } accessors

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable or the run is weighted

eles.katzCentrality

Katz centrality — attenuated walk counting, where a node is central when many short walks end at it and a walk of length k is worth alphaᵏ. Async (round 69): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the iteration runs; like pageRank, 'auto' always uses the sparse CPU iteration and the GPU path serves an explicit 'gpu'. v4-only — v3 has no counterpart.

options

{ alpha, beta, maxIterations, tolerance, directed, weight, executor }

Returns

a promise of the { katz, katzNormalized } accessors

Throws

if executor, alpha or beta is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.triangleCount

Triangle counting: per-node triangle counts, local clustering coefficients, and the collection's transitivity, read over the simple undirected graph (direction ignored, parallel edges collapsed, loops excluded). Async (round 69): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the counting runs — under 'auto' the GPU's A²∘A matmul is used only on graphs dense enough to beat the CPU's sparse walk. v4-only — v3 has no counterpart.

options

{ executor }

Returns

a promise of { triangles, clusteringCoefficient, totalTriangles, transitivity }

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.neighborhoodSimilarity

Neighborhood similarity — pairwise Jaccard, cosine or overlap coefficients over neighbor sets (deduped; loops excluded; directed: true compares out-neighborhoods). The result is all-pairs, so it holds O(n²) counts like floydWarshall. Async (round 69): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the shared-neighbor counts are computed — under 'auto' the GPU's A·Aᵀ matmul is used only on graphs dense enough to beat the CPU's wedge walk. v4-only — v3 has no counterpart.

options

{ metric, directed, executor }

Returns

a promise of the { similarity } accessor

Throws

if executor or metric is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.simRank

SimRank — "two nodes are similar when their neighbors are similar", the Jeh–Widom recursive fixed point, iterated as dense products S′ = C·Q·S·Qᵀ. Async (round 70): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the iteration runs — under 'auto' the GPU only on graphs dense enough to beat the CPU's sparse form. The undirected default compares all neighbors; directed: true compares the classic in-neighborhoods. All-pairs (O(n²) memory). v4-only — v3 has no counterpart.

options

{ dampingFactor, maxIterations, tolerance, directed, executor }

Returns

a promise of the { similarity } accessor

Throws

if executor or dampingFactor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.randomWalkWithRestart

Random walk with restart — network propagation from a seeds collection: a walker follows edges with probability 1−c and restarts at the seeds with probability c, and the stationary distribution scores every node by proximity to the seeds. Async (round 70); the vector iteration is O(E) per step on the CPU, so there is no GPU path — an explicit executor: 'gpu' rejects and points at randomWalkWithRestartProximity. On directed graphs a node with no out-edges absorbs the walk (scores can sum below 1). v4-only — v3 has no counterpart.

options

{ seeds, restartProbability, maxIterations, tolerance, directed, weight, executor }

Returns

a promise of the { score } accessor

Throws

if executor or restartProbability is invalid, or if seeds holds no node of the collection

eles.randomWalkWithRestartProximity

All-pairs random-walk-with-restart proximity — the full matrix S = c·(I − (1−c)·W)⁻¹, whose column s is the walk restarting at s. Async (round 70): executor ('cpu' | 'gpu' | 'auto', default 'auto') picks between one sparse solve per column on the CPU and the dense Neumann iteration on the GPU — under 'auto' the GPU only on graphs dense enough to beat the per-column solves. All-pairs (O(n²) memory). v4-only — v3 has no counterpart.

options

{ restartProbability, maxIterations, tolerance, directed, weight, executor }

Returns

a promise of the { proximity } accessor

Throws

if executor or restartProbability is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.heatDiffusion

Heat diffusion from a seeds collection: unit heat spread over the seeds flows along edges for time, through the kernel exp(−t·L) of the weighted Laplacian. Total heat is conserved. Async (round 70); the vector form is O(E) per series term on the CPU, so there is no GPU path — an explicit executor: 'gpu' rejects and points at heatKernel. Edges are read undirected with positive weights. v4-only — v3 has no counterpart.

options

{ seeds, time, weight, executor }

Returns

a promise of the { score } accessor

Throws

if executor or time is invalid, if seeds holds no node of the collection, or if an edge weight is not positive

eles.heatKernel

The all-pairs heat kernel exp(−t·L) — heat(from, to) is the heat at to after unit heat starts at from (symmetric). Async (round 70): executor ('cpu' | 'gpu' | 'auto', default 'auto') picks between per-column sparse series on the CPU and the dense scaling-and-squaring chain on the GPU — under 'auto' the GPU only on dense graphs. All-pairs (O(n²) memory). v4-only — v3 has no counterpart.

options

{ time, weight, executor }

Returns

a promise of the { heat } accessor

Throws

if executor or time is invalid, or if an edge weight is not positive

eles.effectiveResistance

Effective resistance and commute time — the graph as a resistor network (weights are conductances): resistance(a, b) from the Laplacian pseudo-inverse, commuteTime(a, b) the expected round-trip steps of the random walk (component volume × resistance). Pairs in different components answer Infinity. Async (round 70): executor ('cpu' | 'gpu' | 'auto', default 'auto') picks between dense f64 elimination on the CPU and Newton–Schulz matmul iteration on the GPU; both are O(n³), so 'auto' takes the GPU on size alone. v4-only — v3 has no counterpart.

options

{ weight, executor }

Returns

a promise of the { resistance, commuteTime } accessors

Throws

if executor is invalid; rejects if an edge weight is not positive or executor: 'gpu' is unavailable

eles.motifCensus

The triad census — every three-node subgraph classified into the sixteen Holland–Leinhardt classes ('003' … '300'; '030T' is the feed-forward loop). The counts sum to C(n, 3). Async (round 70): executor ('cpu' | 'gpu' | 'auto', default 'auto') picks between sparse wedge walks on the CPU and matmul trace products on the GPU — under 'auto' the GPU only on dense graphs. directed: false reads every edge as mutual, so only 003 / 102 / 201 / 300 (empty / one-edge / path / triangle) can be non-zero. v4-only — v3 has no counterpart.

options

{ directed, executor }

Returns

a promise of { counts }

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.kMeans

k-means clustering in attribute space. Like v3's clustering algorithms this works on handles and attributes accessors rather than on graph structure.

Async (round 65): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the iteration runs; 'cpu' is the reproducible reference.

options

{ k, attributes, distance, maxIterations, sensitivityThreshold, executor }, with attributes as plain functions

Returns

a promise of one collection per cluster

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.kMedoids

k-medoids clustering — like k-means, but cluster centres are actual elements, which makes it robust to outliers. Async, with the same executor contract as kMeans.

options

as kMeans

Returns

a promise of one collection per cluster

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable, or if k exceeds the node count

eles.fuzzyCMeans

Fuzzy c-means clustering: each element gets a degree of membership in every cluster rather than one hard assignment. Async, with the same executor contract as kMeans.

options

as kMeans, plus the fuzziness exponent

Also spelled eles.fcm.

Returns

a promise of { clusters, degreeOfMembership }

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.hierarchicalClustering

Agglomerative hierarchical clustering. Async (round 65): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the distance matrix is built; the merge chain itself is sequential and always runs on the CPU.

options

{ attributes, distance, linkage, mode, dendrogramDepth, executor }

Also spelled eles.hca.

Returns

a promise of one collection per cluster

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.markovClustering

Markov clustering (MCL) — flow simulation over the graph, so unlike the attribute-space algorithms this one clusters by structure.

Async (round 65): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the expand/inflate iteration runs; 'cpu' is the reproducible reference.

options

{ attributes, expandFactor, inflateFactor, multFactor, maxIterations, executor }

Also spelled eles.mcl.

Returns

a promise of one collection per cluster

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable in this environment

eles.affinityPropagation

Affinity propagation, which picks exemplars by message passing and so needs no target cluster count.

Async (round 65): returns a promise, and executor ('cpu' | 'gpu' | 'auto', default 'auto') picks where the message passing runs; 'cpu' is the reproducible reference.

options

{ attributes, distance, preference, damping, minIterations, maxIterations, executor }

Also spelled eles.ap.

Returns

a promise of one collection per cluster

Throws

if executor is invalid; rejects if executor: 'gpu' is unavailable, or if damping/preference are invalid

Degree Collection

eles.degree

The first element's total degree, in + out, answered in O(1) off the adjacency index.

This is a singular accessor, as in v3 — it reports one node's degree, not a collection-wide figure. For the sum over the whole collection use totalDegree().

includeLoops

whether self-loops count (each contributes 2)

Returns

the degree, or undefined when the first element is not a live node

eles.outdegree

The first element's out-degree, in O(1). Singular, like degree().

includeLoops

whether self-loops count

Returns

the out-degree, or undefined when not a live node

eles.indegree

The first element's in-degree, in O(1). Singular, like degree().

includeLoops

whether self-loops count

Returns

the in-degree, or undefined when not a live node

eles.minDegree

The smallest total degree among the collection's nodes.

includeLoops

whether self-loops count

Returns

the minimum degree, or undefined when there are no nodes

eles.maxDegree

The largest total degree among the collection's nodes.

includeLoops

whether self-loops count

Returns

the maximum degree, or undefined when there are no nodes

eles.minIndegree

The smallest in-degree among the collection's nodes.

includeLoops

whether self-loops count

Returns

the minimum in-degree, or undefined when there are no nodes

eles.maxIndegree

The largest in-degree among the collection's nodes.

includeLoops

whether self-loops count

Returns

the maximum in-degree, or undefined when there are no nodes

eles.minOutdegree

The smallest out-degree among the collection's nodes.

includeLoops

whether self-loops count

Returns

the minimum out-degree, or undefined when there are no nodes

eles.maxOutdegree

The largest out-degree among the collection's nodes.

includeLoops

whether self-loops count

Returns

the maximum out-degree, or undefined when there are no nodes

eles.totalDegree

The summed degree of every node in the collection — the whole-collection figure that degree() deliberately is not.

includeLoops

whether self-loops count

Returns

the total degree (0 when there are no nodes)

Events Collection

eles.on

Listen for events on each element of this collection. The handler is bound per element, and keeps firing across slot compaction — listeners repair with their elements rather than going stale.

Events bubble from an element through its compound ancestors to the core (round 14.5), with stopPropagation() honoured.

Any name registers, as on the core and for the same reason — custom events are supported API (ele.emit( 'foo' )), so names cannot be gated. A name v4 never emits registers cleanly and never fires: that is v3's vmouse* aliases and its raw mouse/touch re-emits — and, since round 41.2, any name containing a dot: there is no namespace machinery, so 'data.ns' is a literal type v4 never raises. See Core#on.

events

one or more space-separated event names

callback

the handler

Also spelled eles.addListener.

Returns

this collection, for chaining

eles.one

Like on(), but each element's handler runs at most once.

events

one or more space-separated event names

callback

the handler

Also spelled eles.once.

Returns

this collection, for chaining

eles.off

Stop listening on each element of this collection.

events

one or more space-separated event names

callback

the handler to remove; omit to remove every handler these elements have for events

Also spelled eles.removeListener.

Returns

this collection, for chaining

eles.emit

Emit an event on each element, bubbling through compound ancestors to the core.

events

one or more space-separated event names

extraParams

extra arguments passed to each handler after the event object

Also spelled eles.trigger.

Returns

this collection, for chaining

eles.promiseOn

Resolve once the next matching event fires on any element of this collection — the promise form of one().

events

one or more space-separated event names

Also spelled eles.pon.

Returns

a promise for the event object

Animation

General Animation

ani.play

Enqueue and start.

Returns

resolves when the animation completes (or is stopped)

ani.stop

Stop in place, or at the targets with jumpToEnd.

jumpToEnd

apply the final values instead of freezing

ani.promise

The completion promise.

Returns

resolves when the animation completes (or is stopped)

ani.playing

Whether the animation is running and not paused.

Returns

true while playing

ani.pause

Round 24.3: freeze in place; the paused span leaves the timeline.

Returns

this handle, for chaining

ani.resume

Resume a paused animation with the clock shifted (round 24.3).

Returns

this handle, for chaining

ani.reverse

Swap the tween's ends with elapsed remapped (round 24.3).

Returns

this handle, for chaining

ani.progress

Elapsed fraction of the duration (read-only — no scrubbing).

Returns

the fraction in [0, 1]

ani.paused

Whether the animation is paused (round 24.3).

Returns

true while paused

Layout context

Scope Layout context

ctx.cy

the core being laid out

ctx.options

the resolved layout options (custom knobs included)

ctx.eles

The layout scope (handles tier); the whole graph unless this run came from eles.layout().

Lazy since round 34.4. It used to be assigned in the constructor, which meant every run of every layout materialized cy.elements() — a handle per element — including for the columnar-first layouts this contract exists to encourage, which never touch it. That cost 333 µs per run at 25k elements for an impl that does nothing. Reading it still costs what it always did; not reading it is now free.

Returns

the scope's handles — eles.layout()'s collection, or the whole graph's elements when the layout was started from the core. Materialized on first read and cached for the run

ctx.nodes

The scope's node handles (lazy — see eles).

Returns

the node subset of eles, unfiltered — unlike nodeSlots(), this keeps locked nodes and compound parents, so a layout iterating it must apply its own rules

ctx.refreshScope

Drop the cached scope so the next eles / nodes read the graph as it now is (118.3): a whole-graph scope is materialized once per run, and a force layout's infinite run rebuilds its sim on an add or remove. A subset scope (eles.layout()) is the caller's collection and stays what it was.

Columnar reads Layout context

ctx.nodeSlots

The slots to lay out: the scope's nodes, pre-filtered to unlocked leaves (locked nodes hold their place; parents derive from their placed children — round 14.11). Scope order.

Returns

the slots to place, in exactly cy.nodes() order — which is load-bearing rather than incidental, since grid and circle assign positions by index, so a different enumeration order is a different layout

ctx.edgeSlots

The scope's edge slots.

Returns

every live edge of the scope in cy.edges() order, with no filtering — the counterpart of nodeSlots(), which does filter

ctx.positions

The live position column (x,y interleaved by slot) — read it, write through setPositions.

Returns

the store's own column, not a copy: it changes underneath a held reference as positions are written, and writing into it directly bypasses the dirty tracking the renderer depends on

ctx.endpoints

The live edge endpoint column (source,target node slots).

Returns

the store's own column, indexed by edge slot — node slots, not ids, so it pairs directly with positions() without a lookup

ctx.degreeOf

O(1) degree off the CSR adjacency.

slot

a node slot, as handed out by nodeSlots()

Returns

its whole-graph degree, loops counted as v3 counts them

ctx.nodeDimensions

The layout boxes of the scope's nodes (round 114.1): slot-parallel node-local extents read off the size, border and label columns — the one reading every built-in spaces by. Labels are included when the run's nodeDimensionsIncludeLabels is true (115: v3's default again), making the box asymmetric when a label hangs below the body; take max( -y1, y2 ) for a symmetric half. Headless label dimensions are estimates (16.4), exact once a renderer has laid the glyphs.

slots

the node slots to measure (default nodeSlots())

options

includeLabels (default: the run's option, itself defaulting to false) and padding (split half per side)

Returns

the boxes, parallel to slots

Bounds Layout context

ctx.boundingBox

The scope's current bounding box, labels included.

Returns

{ x1, y1, x2, y2, w, h } in model coordinates

ctx.width

The viewport width in CSS px — what a layout sizing itself to the screen should use. Headless instances report the configured headless width, so a layout still works without a DOM.

Returns

the viewport width

ctx.height

The viewport height in CSS px.

Returns

the viewport height

Writing positions Layout context

ctx.setPositions

The bulk write: xy[i2], xy[i2+1] land on slots[i] — one dirty span, no handles (the round-5 slot path; under compounds it takes the per-slot sequential path so auto-bounds stay exact).

slots

the node slots to move

xy

the packed positions: xy[i*2], xy[i*2+1] land on slots[i]

ctx.components

The scope's connected components over nodeSlots() (round 114.4, factored out of packComponents for layouts that pack their own arrays): union-find over the scope's own edges — an edge with an endpoint outside the scope connects nothing here — indexed by position in nodeSlots().

Returns

the component assignment, ids in first-seen node order

ctx.packComponents

Separate the scope's disconnected components (round 87.1): v3's separateComponents as a one-call, translation-only post-pass. Per-component bounding boxes at the current positions are shelf-packed largest-first with spacing between them, every member translated with its component, and the largest component's centre held fixed — the dominant structure keeps its place and the strays come to it.

The boxes are body boxes since round 114.4 (nodeDimensions(), labels included by the run's option), so two singleton components end up spacing apart edge to edge rather than centre to centre; bodies: false restores the 87.1 point boxes.

Components are computed over the scope's own edges (an edge with an endpoint outside the scope connects nothing here), and only the nodeSlots() nodes move — a locked node neither moves nor holds its component in place, so a scope mixing locked and unlocked members of one component can separate them. The write lands through setPositions (one dirty span).

spacing

the gap between packed component boxes (default 40, the force layout's componentSpacing default)

options

bodies (default true) packs the nodes' boxes rather than their positions; includeLabels overrides the run's nodeDimensionsIncludeLabels for those boxes; positions packs that array (2n, parallel to nodeSlots()) in place instead of the store — for a layout that lands through finish() and must not write positions before the tween starts

ctx.layoutPositions

The discrete finisher: v3's layoutPositions plumbing over the scope — spacingFactor, transform, animate (with the fit-at-final-positions viewport animation), fit/zoom/pan, and the layoutready/layoutstop events. The wrapper's layoutstart covers the start (no double emit).

fn

called per scoped node with the node and its index, returning the model position to place it at

overrides

an impl's own defaults, merged over the run's options (round 114.2: flow's fit: true default never reached the finisher before this). ready and stop are never overridden — the wrapper's stop is what resolves promise()

ctx.finish

Land computed positions the way a built-in does (round 114.2): the finisher when the run asks for anything it owns — animate, animateFilter, transform, spacingFactor — and otherwise the bulk slot write followed by fit / zoom / pan. One rule for flow, force and any extension that computes into an array.

slots

the node slots the positions land on

xy

the packed positions: xy[i*2], xy[i*2+1] for slots[i]

overrides

the impl's defaults, merged as layoutPositions merges them

Layout

Running a layout Layout

layout.options

the resolved options this run was created with

layout.run

Start the layout. Emits layoutstart on the core, calls impl.run( ctx ) and awaits it if it returns a promise (the shape a GPU-resident layout needs).

The lifecycle fires exactly once per run either way: an impl that finishes through ctx.layoutPositions() lets the finisher emit layoutready/layoutstop, and one that writes positions directly has them emitted here instead.

Returns

this layout, for chaining; await promise() for completion

layout.promise

Resolves at this run's layoutstop (immediately when never run).

layout.stop

Ask the layout to stop early, by calling the impl's optional stop(). An impl without one simply runs to completion.

Returns

this layout, for chaining

layout.reheat

Heat a running layout back up (118.3), by calling the impl's optional reheat(). A force layout's infinite run ticks only while its field is moving and reheats itself on a drag, a moved node and an added or removed element; this is for a change it cannot see — an edge length that changed under a data mapping, a style that resized the boxes. An impl without one ignores it.

alpha

the temperature to restore; the force layout's default is 0.3, d3's drag convention

Returns

this layout, for chaining

Event

What happened Event

event.type

the event type, e.g. 'tap' — never namespaced (round 41.1)

event.target

the core for core-level events, the element for element events

event.cy

the core the event was raised on

event.position

model-space position, on pointer-derived events

event.renderedPosition

rendered-space position; derived from position and the viewport

event.originalEvent

the DOM event behind a gesture, when there was one (round 41.4)

event.layout

the layout instance, on the layout lifecycle events

event.timeStamp

when the event was built, Date.now() unless the caller supplied one

event.isDefaultPrevented

Whether preventDefault() has been called.

Recorded, never read by v4: by decided design preventDefault() suppresses no gesture default — it forwards to the DOM event when one is attached, and gesture defaults are controlled by their explicit toggles instead. See the module comment.

event.isPropagationStopped

Whether stopPropagation() has been called — read by the compound bubbling walk (round 14.5), where it halts the phase sequence.

Controlling propagation Event

event.preventDefault

Mark the event's default as prevented, and prevent the DOM event's default when one is attached.

Browser-level only, by decided design — no v4 code reads isDefaultPrevented(), so this cannot stop a tap from selecting or a grab from starting; use the explicit toggles (autoungrabify, autounselectify, boxSelectionEnabled, …) for gesture control. With originalEvent populated (round 41.4) this reaches the browser's default.

event.stopPropagation

Stop the event bubbling to further phases: the remaining ancestors and the core do not see it (round 14.5). Returning false from a handler does the same. With originalEvent attached (round 41.4) this also calls the DOM event's stopPropagation(), so an outer DOM listener stops seeing it too.