Skip to content

@graphty/graphty-element / index / UpdateManager

Class: UpdateManager ​

Defined in: graphty-element/src/managers/UpdateManager.ts:212

Manages the update loop logic for the graph Coordinates updates across nodes, edges, layout, and camera

Implements ​

Constructors ​

Constructor ​

new UpdateManager(eventManager, statsManager, layoutManager, dataManager, camera, graphContext, config?): UpdateManager

Defined in: graphty-element/src/managers/UpdateManager.ts:287

Creates a new update manager

Parameters ​

eventManager ​

EventManager

Event manager for emitting update events

statsManager ​

StatsManager

Stats manager for performance tracking

layoutManager ​

LayoutManager

Layout manager for graph layout

dataManager ​

DataManager

Data manager for nodes and edges

camera ​

CameraManager

Camera manager for view control

graphContext ​

GraphContext

Graph context for accessing shared resources

config? ​

UpdateManagerConfig = {}

Optional configuration

Returns ​

UpdateManager

Accessors ​

frameIsStable ​

Get Signature ​

get frameIsStable(): boolean

Defined in: graphty-element/src/managers/UpdateManager.ts:733

Whether the picture on screen is the finished one.

True only when the layout has converged, no framing is outstanding that could still move the camera, no style work is queued, every drawn mesh has its shader, AND a frame has been drawn since all of that became true. It is the difference between graph-settled, which fires the instant the LAYOUT stops and one pass before the final framing is even requested, and a picture that will not change again.

It says nothing about a reader: somebody dragging the camera or a node changes the picture, and the element does not call that instability.

Returns ​

boolean

True when the last drawn frame drew the finished picture.


zoomToFitCompleted ​

Get Signature ​

get zoomToFitCompleted(): boolean

Defined in: graphty-element/src/managers/UpdateManager.ts:1592

Check if zoom to fit has been completed

Returns ​

boolean

True if zoom to fit has completed at least once

Methods ​

bindViewMasks() ​

bindViewMasks(masks): void

Defined in: graphty-element/src/managers/UpdateManager.ts:349

Say where the renderer reads the selection and visibility masks from.

Binding is how the element's own model reaches the render loop: the masks belong to the session, one per dataset, and every view of that dataset honours the same two. Passing null unbinds them, which draws the whole graph with no highlight.

Parameters ​

masks ​

ViewMasks | null

The two mask sources, or null.

Returns ​

void


disableZoomToFit() ​

disableZoomToFit(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:648

Disable zoom to fit

Returns ​

void


dispose() ​

dispose(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:335

Dispose the update manager

Returns ​

void

Implementation of ​

Manager.dispose


enableZoomToFit() ​

enableZoomToFit(explicit?): void

Defined in: graphty-element/src/managers/UpdateManager.ts:630

Frame the whole graph on the next frame that has something to measure.

The request is HONOURED rather than merely permitted. Everything below this line paces the periodic re-framing that follows a moving layout around, and that pacing answers "no" to every frame once the layout has stopped -- so routing an explicit request through it made Graph.zoomToFit() silent from the first settlement onwards, and made the element's own "re-frame now that the layout has truly settled" call dead on arrival.

Parameters ​

explicit? ​

boolean = false

True when a consumer asked, so UpdateManager.stopAutoZoomToFit leaves the request standing.

Returns ​

void


forceEdgeWalk() ​

forceEdgeWalk(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:1368

Make the next frame visit every edge, whatever the nodes say.

Called when something other than a position has changed what an edge should draw: a style pass has repainted, or the dataset has been replaced. A repaint can change a node's SIZE, which moves where its edges have to stop without moving the node at all.

Returns ​

void


getRenderFrameCount() ​

getRenderFrameCount(): number

Defined in: graphty-element/src/managers/UpdateManager.ts:679

Get the current render frame count

Returns ​

number

Total number of frames rendered


init() ​

init(): Promise<void>

Defined in: graphty-element/src/managers/UpdateManager.ts:327

Initialize the update manager

Returns ​

Promise<void>

Promise that resolves when initialization is complete

Implementation of ​

Manager.init


invalidateViewMasks() ​

invalidateViewMasks(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:361

Forget which mask versions the meshes are in line with, so the next pass writes all of them.

Call this when the render objects have changed under the masks -- a dataset load, a clear, a 2D/3D switch -- because the versions would otherwise say "nothing moved" about elements that are not the elements those versions were measured against.

Returns ​

void


isZoomToFitEnabled() ​

isZoomToFitEnabled(): boolean

Defined in: graphty-element/src/managers/UpdateManager.ts:671

Get current zoom to fit state

Returns ​

boolean

True if zoom to fit is enabled


meshesAdded() ​

meshesAdded(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:752

Say that meshes were built outside a pass that moves anything, so the finished picture has to be earned again.

A new mesh can bring a shader variant nothing has compiled, or a texture still loading, and a frame skips a mesh that is not ready. Most doors that build meshes also move something -- a load starts the layout, a forward dimension change frames the camera -- and that clears the finished flags on the next pass. An undo of a dimension change moves nothing, because the layout stays at rest and the camera is the reader's; nor does a skybox. Without this the last finished frame would still be called final while the new meshes are drawn as nothing: an empty canvas after undoing 2D to 3D, and the old background after setting a skybox.

Returns ​

void


rebindScene() ​

rebindScene(camera): void

Defined in: graphty-element/src/managers/UpdateManager.ts:316

Follows the graph onto the scene and camera of the renderer chosen at init, which replace the ones this manager was built with. The old scene is disposed, and its watcher with it.

Parameters ​

camera ​

CameraManager

The new scene's camera manager.

Returns ​

void


redrawArrangement() ​

redrawArrangement(moved?): void

Defined in: graphty-element/src/managers/UpdateManager.ts:1173

Move every node and edge to where the position array has it now, without stepping the layout: how a restored arrangement reaches the picture while the layout is at rest.

Parameters ​

moved? ​

boolean = true

Whether any coordinate was written; when none was, the nodes are placed and the edges, whose endpoints are where they were, are left as they are drawn.

Returns ​

void


renderFrames() ​

renderFrames(count): void

Defined in: graphty-element/src/managers/UpdateManager.ts:711

Update AND draw a number of frames, the way the render loop does.

The render loop is one update pass followed by one scene.render(), so this is that pair repeated: after it returns, what is on the canvas is what the model says, and a frame drawn while the picture was finished has been counted as such by UpdateManager.frameIsStable.

Parameters ​

count ​

number

How many frames to update and draw.

Returns ​

void


stepFrames() ​

stepFrames(count): void

Defined in: graphty-element/src/managers/UpdateManager.ts:696

Run a number of MODEL-UPDATE passes, drawing nothing.

One pass is the half of a frame that happens before the picture: it steps the layout, moves the meshes, applies queued style work and may re-frame the camera. It never puts a pixel on screen, because that is scene.render() and this method does not call it. Use it when what is being checked is the MODEL -- a mesh's material, a node's position, whether a framing happened -- and use UpdateManager.renderFrames when a picture is needed.

It was called renderFixedFrames, and every caller that read the name and wanted a picture got layout steps and no frames instead.

Parameters ​

count ​

number

How many update passes to run.

Returns ​

void


stopAutoZoomToFit() ​

stopAutoZoomToFit(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:660

Stop the element's own framing -- the follow of a moving layout and any request the element made itself -- but keep a consumer's outstanding zoomToFit(), which is answered once.

Returns ​

void


syncStyles() ​

syncStyles(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:558

Bring the meshes into line with what the session's style stack painted.

THE DIRTY SET IS THE WHOLE POINT, and it is the renderer's half of the repaint's cost contract. A style pass bounds its own work to the elements an edit touched; without this the renderer would then rebuild every mesh in the graph to find them, and the pass's bound would buy nothing. So the painter hands back exactly the indices the pass repainted, and a layer over 300 elements costs 300 elements whatever the graph's size.

An element whose paint has not changed still costs nothing: Node.applySessionPaint and Edge.applySessionPaint compare the source mesh they are handed with the one already on screen and rebuild only when it differs, so a colour change on a node is one buffer write and no geometry at all.

Returns ​

void


syncViewMasks() ​

syncViewMasks(): void

Defined in: graphty-element/src/managers/UpdateManager.ts:395

Bring the meshes into line with the two masks.

THE WHOLE POINT IS THE DELTA. A pass costs one integer comparison when nothing has moved, and when something has it walks the render objects and writes ONLY the ones whose state actually changed -- Node.setRenderState and Edge.setRenderVisible return false and touch no mesh when handed what they already hold. So scrubbing a time window that moves 200 nodes costs 200 mesh operations and not 50,000, and re-running a filter that lands on the same answer costs none.

Mesh instancing is what bounds the rest: a node is one InstancedMesh of a source shared by every node of its style, so hiding one is a flag on that instance rather than a geometry change. Babylon offers no way to hide a SUBSET of a source's instances in one call, so the first application of a large filter is one flag write per element that moved; that is the floor, and the delta above is what keeps every later pass off it.

An element the store has no row for -- INVALID_INDEX, which is what a record that never reached the builder carries -- is drawn and is not selected. The element has always drawn such a record, and a mask cannot answer for a row that does not exist.

READING A MASK RESYNCS IT against the current graph, which is the one cost this pass cannot avoid and must not: a mask that was not regrown answers "not a member" for every node that arrived since it was last evaluated, so skipping the resync would silently hide every newly loaded node while a filter is on. The resync is an identity comparison whenever the graph has not moved, so the cost lands only while records are actually arriving.

Returns ​

void


update() ​

update(frameMs?): void

Defined in: graphty-element/src/managers/UpdateManager.ts:951

Update the graph for the current frame.

The pass itself is the private runUpdatePass(); what is added here is the one question a consumer cares about and the pass has several exits from -- whether the state it leaves behind is a finished picture.

Parameters ​

frameMs? ​

number = 0

How long the previous frame took. A running layout keeps to one step per nominal 60 Hz frame of that time, so it settles in the same seconds however slowly the frames are drawn. Omitted or 0 -- every hand-pumped pass -- it takes one step.

Returns ​

void


updateConfig() ​

updateConfig(config): void

Defined in: graphty-element/src/managers/UpdateManager.ts:1600

Update configuration

Parameters ​

config ​

Partial<UpdateManagerConfig>

Partial configuration to merge

Returns ​

void


whyFrameIsNotStable() ​

whyFrameIsNotStable(): string

Defined in: graphty-element/src/managers/UpdateManager.ts:764

What is still keeping the picture from being final, in a consumer's words.

Written for the message a timed-out wait carries, because "the frame never settled" on its own sends the reader to a debugger.

Returns ​

string

One phrase naming the thing that is still moving.