cytoscape.js v4 HEAD · 96942db8 · built 2026-08-05 20:14Z

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.

362 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.

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)

cy.constructor

Build a core over a fresh columnar store. Prefer the cytoscape( options ) factory: it is the documented entry point and additionally ingests options.elements, runs options.layout, and attaches a renderer when a container is given. Constructing directly yields a headless, empty instance regardless of those options.

Unknown options are ignored, deliberately (decided 2026-08-04, fifth design sitting). This is the one v4 entry point that does not fail loudly on a name it does not know — an unknown sheet key, style property or query key all throw — because strictness here resolves at the type layer: TypeScript's excess-property check rejects { motionBlur: true } and any other typo against CytoscapeOptions, and v4 does not replicate at runtime what the build already checks. The boundary is TypeScript's: excess-property checking applies to object literals, so options assembled into a variable first are widened and pass. Pinned by the compile-only consumer test in typescript/tests/gpu.test-d.ts.

options

the instance options (see CytoscapeOptions); viewport, interaction-gating and interaction-tuning options are applied here, and style compiles immediately. Unrecognized keys are kept as given and returned by options(), never validated.

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.batching

True while inside a startBatch()/endBatch() pair.

Returns

whether a batch is open at any depth — nesting is counted, and only the outermost endBatch flushes the deferred style work

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

cy.batchData

v3 compat: per-id data() patches applied in one batch.

map

element id → the data keys to merge into that element

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.

Returns

a collection of zero elements

cy.getElementById

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

id

the element id

Also spelled cy.$id.

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

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, cy.listen, cy.bind.

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, cy.unlisten, cy.unbind.

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 }.

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.getFitViewport

The { zoom, pan } that would fit the given elements — computed, not applied.

eles

the elements to fit; omit for the whole graph

padding

rendered px of margin to leave on every side

Returns

the viewport, or null when there is nothing to fit

cy.getCenterPan

The pan that would center the given elements.

eles

the elements to center; omit for the whole graph

zoom

the zoom to center at; defaults to the current one

Returns

the pan, or null when there is nothing to center

cy.pick

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

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.renderer

The renderer, or null when headless. Its stats() carry 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

the renderer, or null on a headless instance

cy.forceRender

Force a redraw next frame (no-op when headless; the loop is render-on-dirty).

cy.resize

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

Also spelled cy.invalidateSize.

cy.onRender

Run a callback after each rendered frame — sugar for on( 'render', … ). With no animation queue and no step callback, this plus animation promises is how v4 observes progress.

callback

the per-frame handler

Returns

this core, for chaining

cy.offRender

Stop running a per-frame callback.

callback

the handler to remove; omit to remove all of them

Returns

this core, for chaining

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.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).

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.instanceString

The type tag 'core' — the counterpart of a collection's 'collection', for code that accepts either.

Returns

'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.

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.

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.

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.

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.

id

the element id

Returns

true when the graph holds that element

cy.mutableElements

All elements (the prototype has no immutable/"read-only" collections) — elements() by another name, memo included.

Returns

every element in the graph

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.

Returns

the global window, or null outside a browser

cy.options

The options the instance was constructed with.

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.

eles.constructor

Build a collection over a ref list. Not part of the public API — collections come from the core (cy.nodes(), cy.$id(), cy.collection()) and from other collections; going through those keeps handle interning and dedupe correct.

cy

the owning core

refs

the element refs to hold

opts

singleton for the interned per-slot handle, unique when the refs are already deduped, live when they are also known current (both skip work on the hot path)

Core reference & identity Collection

eles.instanceString

The type tag 'collection' — the counterpart of the core's 'core', for code that accepts either.

Returns

'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.renderer

The renderer, or null when headless.

Returns

the renderer, or null on a headless instance — the model is CPU-canonical, so a null renderer costs drawing, picking and image export and nothing else

eles.element

The first element as a length-1 collection (empty collection when empty).

Returns

a length-1 collection, or an empty one — v4 has no separate element type, so this narrows rather than unwraps

eles.collection

An empty collection in the same core.

Returns

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

eles.hasElementWithId

Whether this collection contains an element with the given id.

id

the element id

Returns

true when a member has that id

eles.indexOf

Index of an element within this collection.

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.

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.byGroup

Split into { nodes, edges }.

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 ({ value: -Infinity, ele: undefined } when 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.silentPosition

Like position(), but a write emits no position event. For bulk or intermediate moves — a layout's own iterations — where per-step events would be noise.

dim

'x'/'y', or a { x, y } object

value

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

Returns

the position when reading, 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

eles.silentPositions

Like positions(), but emits no position events.

pos

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

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.silentShift

Like shift(), but emits no position events.

dim

'x'/'y', or a { x, y } offset

value

the offset, with the 'x'/'y' form

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.

args

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

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.

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: style() returns all of the first element's group props, style(name) one value (numbers for numeric props, rgb()/rgba() strings for colors, keywords otherwise).

Setter forms throw — v4 has no per-element bypass. Per-element styling is declarative instead: a case mapper for conditionals, a data(key) scale for per-element values. (Until round 31 both this comment and the throw pointed at "the function form of the stylesheet", which round 8 removed and 29.3 made throw — following the advice hit a second error.)

name

a property name to read one value; omit for the whole group. An object or a second argument is a setter form

value

never valid; present so the setter form throws rather than silently ignoring it

Also spelled eles.css.

Returns

one resolved value, or the whole group's props

Throws

if called in any setter form

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.

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).

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).

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).

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.

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.

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.

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.isBundledBezier

Whether the edge participates in bezier bundling — v3 semantics: a style check (curve-style: bezier), true even for the lone or odd-middle member that renders straight.

Returns

whether the styled record says bezier — a question about style, not about the rendered shape, which is why a lone edge under curve-style: bezier answers true while drawing as a line. False for nodes and for removed elements

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.

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.

Returns

this collection, for chaining

eles.locked

Whether the first element is locked — immovable, by layouts and position writes alike. The force layout treats locked nodes as fixed obstacles.

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.inactive

True when the first element is live and not active (v3 inactive()).

Returns

not simply the negation of active(): a removed element is neither active nor inactive, so both read false for it

eles.activate

Put these elements into the transient pressed ("active") state, the one the pointer layer sets while a press is held.

Returns

this collection, for chaining

eles.unactivate

Clear the pressed ("active") state.

Returns

this collection, for chaining

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

eles.boundingBoxAt

The bounding box this collection would have if its nodes sat at the given hypothetical positions (a position fn or one shared position) — v3's boundingBoxAt, computed directly with no store writes. Edges span their endpoints' hypothetical (or, outside the collection, current) positions.

Layouts Collection

eles.layoutDimensions

Node dimensions for layout spacing, as v3's layoutDimensions.

options

{ nodeDimensionsIncludeLabels } to measure the label box too rather than the node body alone

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).

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.

options

{ weight, directed }

Returns

{ distance, path } accessors

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.

options

{ dampingFactor, precision, iterations }

Returns

{ rank }, a per-node accessor

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].

options

{ weight, directed, harmonic }

Also spelled eles.ccn, eles.closenessCentralityNormalised.

Returns

a closeness accessor

eles.betweennessCentrality

Betweenness centrality — how often each node lies on shortest paths between other pairs.

options

{ weight, directed }

Also spelled eles.bc.

Returns

{ betweenness, betweennessNormalized } accessors

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.

options

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

Returns

one collection per cluster

eles.kMedoids

k-medoids clustering — like k-means, but cluster centres are actual elements, which makes it robust to outliers.

options

as kMeans

Returns

one collection per cluster

eles.fuzzyCMeans

Fuzzy c-means clustering: each element gets a degree of membership in every cluster rather than one hard assignment.

options

as kMeans, plus the fuzziness exponent

Also spelled eles.fcm.

Returns

{ clusters, degreeOfMembership }

eles.hierarchicalClustering

Agglomerative hierarchical clustering.

options

{ attributes, distance, linkage, mode, dendrogramDepth }

Also spelled eles.hca.

Returns

one collection per cluster

eles.markovClustering

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

options

{ attributes, expandFactor, inflateFactor, multFactor, maxIterations }

Also spelled eles.mcl.

Returns

one collection per cluster

eles.affinityPropagation

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

options

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

Also spelled eles.ap.

Returns

one collection per cluster

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, eles.listen, eles.bind.

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, eles.unlisten, eles.unbind.

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

State Animation

ani.refs

the elements being animated (empty for a viewport animation)

ani.isViewport

true when this animates the viewport rather than elements

ani.durationMs

The animation's real length: the requested duration times the easing's durationScale, which is 1 for every curve except a spring (whose duration is perceptual — the pace of the key movement — leaving the settling tail to run past it).

ani.easingProgram

The compiled easing: a kind plus either a bezier tuple or a progression array. One curve layer, two executors — the CPU tick calls it directly and the GPU kernel reads it out of its params, so the two agree to float precision without parallel implementations.

ani.gpuDriven

set when the renderer's GPU tween runtime drives this animation

ani.gpuId

batch id in the GPU tween runtime (null until registered)

ani.lastNow

the shared clock as of the last manager tick — what pause/resume/ reverse/progress read, so the controls stay deterministic under test-driven ticks (the manager stamps it every advance)

ani.preset

A transition animation (round 24.1): the style engine diffed stored truth around a restyle into per-column writes; nothing to capture.

Returns

an animation whose values are already resolved — it never reads the columns at play time, so the restyle's own diff is the only place stored truth is consulted

ani.constructor

Build an animation. Reached through eles.animate()/ eles.animation() and cy.animate()/cy.animation() rather than constructed directly.

store

the columnar store the tween writes into

viewport

the viewport, for a viewport animation

refs

the elements to animate

isViewport

whether this targets the viewport

opts

targets, duration, easing, delay, complete

styleEngine

needed to resolve style targets and the arrow colour fold

Throws

if easing is a function — a closure cannot cross to the device, so accepting one would make the curve depend on whether the animation got offloaded

ani.done

True once the animation has completed or been stopped.

Returns

whether it is over, not whether it succeeded — a stop and a natural completion are the same answer here, and both resolve the promise

ani.touchedColumns

The store columns this animation writes — the round-21 concurrency contract: two animations on the same element run together exactly when their column sets are disjoint, and overlap evicts the older one. A no-op tween (delay()) touches nothing.

Returns

the set of column ids, computed once and cached

ani.hasPan

Viewport channels (round 21): pan and zoom compose when disjoint.

Returns

whether this animation tweens the pan — the pair are separate channels, so a pan animation and a zoom animation run together rather than evicting each other

ani.hasZoom

Whether this viewport animation tweens the zoom.

Returns

whether the zoom channel is claimed; see hasPan for why the two are tracked apart

ani.repairRefs

Slot compaction (19.3): repair the target and channel-write refs through the store's forwarding (in place) and re-point the parallel slot arrays — apply indexes columns by slots[i], which would otherwise write the tween into whatever moved into the old slot.

store

the store that just compacted, whose forwarding chain resolves the pre-move refs

Playback Animation

ani.running

True once the delay has elapsed and interpolation is under way.

Returns

whether values are actually moving — false during the delay, when the animation is live and owns its channels but has not started interpolating

ani.promise

A promise that resolves when the animation completes (or is stopped).

ani.tick

Advance this animation.

now

the shared clock in ms

Returns

true when the animation finished on this tick

ani.stop

Stop now.

jumpToEnd

apply the final frame first, instead of freezing at the value the tween reached

Controls Animation

ani.paused

Whether the animation is paused: values hold where they are and the promise stays pending. A paused animation still owns its channels, so the round-21 eviction stops it like any running one.

Returns

whether the clock is frozen; a paused animation is not a stopped one — it still holds its channels against everything else

ani.progress

Elapsed fraction of the duration (0 before start, 1 when done; frozen at the pause point while paused). Read-only — no scrubbing.

Returns

the eased-time input in [0, 1], before the easing curve is applied — so it is linear in wall time, not in the value being tweened

ani.pause

Freeze in place.

now

the clock to freeze against; defaults to the last tick

ani.resume

Continue, excluding the paused span from the timeline.

now

the clock to resume against; defaults to the last tick

ani.reverse

Swap the tween's ends and remap elapsed to 1 − t, so the current value is continuous (exactly for point-symmetric easings — linear included; v3's start/end swap carried the same rule). Reversing inside the delay completes at the captured start state. Works paused (the frozen value is the pivot) — resume plays backward.

ani.applyNow

Write the value reached at now onto the CPU columns without finishing — how a GPU-driven animation leaves the device for a pause or reverse (the caller unregisters the batch).

now

the clock to evaluate at; defaults to the last tick

ani.gpuEligible

Whether the GPU tween runtime can drive this animation outright.

All-or-nothing: one non-offloadable channel keeps the whole animation on the CPU, so a column is never half-owned. Position qualifies under the round-9 lease (the pass barrier lets cull and the edge shaders read the tweened positions, so edges follow for free); paint qualifies because nothing on the CPU reads it; geometry channels and the viewport do not — geometry is read by cull, the CPU pick replica and every columnar scan, so it stays CPU-canonical (round 25).

Returns

whether every write may offload — all-or-nothing per animation, so one geometry channel among the writes keeps the whole animation on the CPU rather than splitting it

ani.gpuBatches

Resolve this animation into per-column GPU batches, capturing start values. Sets the start clock so CPU settle and GPU evaluation share it.

now

the clock the batch's params are anchored to

Returns

one ChannelWrite per tweened column

ani.schedule

Pin the start clock on the first tick, so startMs reads true before capture.

now

the clock of that first tick

ani.startMs

Start time in the shared clock (set once scheduled); ms.

Returns

the instant interpolation begins — the delay is already added in, so this is not the moment play() was called; 0 before the animation has been scheduled at all

ani.settleGpu

Settle a GPU-driven animation onto the CPU columns at now and finish it — the tween is CPU-reproducible, so the exact current value is lerp(from, to, ease(t)) (t = 1 on natural completion). Also how an interrupted animation lands: without it the CPU would keep the start values while the GPU buffers hold the last frame drawn, and nothing would ever dirty the column to reconcile them.

now

the clock to settle at; t = 1 on natural completion

ani.demoteGpu

Leave the GPU path mid-flight without ending the animation (slot compaction, 19.4): write the exact value reached onto the CPU columns and keep ticking as a CPU tween — the device-side slot buffers held pre-compaction slots, and 19.3's repair re-points the CPU slot arrays. The caller unregisters the GPU batch.

now

the clock whose value is written to the CPU columns

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.constructor

Built by the wrapper, once per run — a layout impl receives one of these and never constructs it.

cy

the core being laid out

layout

the wrapper, passed through as event.layout on the lifecycle events

options

the resolved layout options; eles narrows the scope (from eles.layout()), defaulting to the whole graph

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

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.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

Layout

Running a layout Layout

layout.options

the resolved options this run was created with

layout.constructor

Wrap a layout impl. Reached through cy.layout( { impl } ) / eles.layout( { impl } ) rather than constructed directly.

cy

the core to lay out

options

must carry impl, a class constructed with no arguments or a plain object, implementing { run( ctx ), stop?() }

Throws

if impl is missing, or does not implement run( ctx )

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

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: nothing in v4 reads this yet, so calling preventDefault() suppresses no gesture default — it only forwards to the DOM event when one is attached. Making it functional is decided but not yet built; see the module comment and PLAN.md's open calls.

event.isPropagationStopped

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

event.constructor

Build an event.

props

the fields to carry; type is required in practice and defaults to the empty string so a malformed emit is inert rather than throwing inside a handler loop

event.instanceString

v3's type tag, kept because is.event()-style checks and user code read it.

Returns

the string 'event'

Controlling propagation Event

event.preventDefault

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

Inert for v4's own gesture defaults today — no v4 code reads isDefaultPrevented(), so this cannot stop a tap from selecting or a grab from starting. The DOM half does work: 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.