Aller au contenu

Graph views and automatic layouts

Graph accepts fitRequest?: number (declaratively fitRequest: ValueSource<number>). Each time the value changes, the shell frames every node and swimlane. The shell adds no command: the plugin owns it. Example in Notes: command notes-tsx/graph.fitAll (Shift+1, graph toolbar) increments a per-note counter (graphFit in host.ts) that TaskGraph passes to fitRequest.

A plugin can work on any open graph without knowing who owns its data:

  • ctx.graphs.snapshot({ tabId }) returns { viewId, params, nodes, edges, lanes }, with node positions and sizes as rendered.
  • ctx.graphs.applyPositions({ tabId }, nodePositions) sends absolute positions to the view’s positionsEvent (declared in the graph config). The owner applies them in the current transaction, so one undo reverts them.
  • ctx.graphs.provide(capability, viewId, impl) / providers(capability) let plugins exchange per-view-type capabilities without dependsOn.
  • ctx.graphs.subscribeTopology(listener) reports structural changes after rendering; position-only writes never notify.
  • ctx.graphs.subscribeNodeMoves(listener) reports a released user node drag after dispatching the owner’s move event. Layout position writes never notify.

The flow-layout plugin uses this: its pure algorithm (packages/flow-layout-core, flowLayout for one region, layoutLanes per lane) gets the direction and the edge depths from a "flow-layout" provider ({ direction(view), edgeDepth(view, edgeId) }). Notes provides one: direction = the “Flow layout direction” setting, depth = the precedence “Layout depth” field (1 default, 0 ignored, >1 longer, negative reversed). Nodes outside lanes never move; edges between lanes are ignored.

The automatic toggle is per tab. It reruns after topology changes (including edge creation), released node drags and changes to layout inputs. A provider may expose subscribe(listener): () => void to signal possible parameter changes; flow-layout compares the actual direction and edge depths before scheduling. Notes subscribes to its tasks and settings, so editing depth in either the table or Properties, undo/redo and direction changes all work without putting domain attributes in the graph shell. Color, routing and layout-generated position updates do not retrigger it. Notifications are coalesced until the next frame so the owner’s data and rendered geometry are available; disabling automatic mode cancels queued runs.

A data ref may name another plugin with "<pluginId>:<name>", e.g. "rows": { "ref": "base-model:schemaRows" }. It resolves lazily to the ctx.ui.define binding of that plugin (values, tables, graph nodes/edges/lanes), so a satellite plugin can declare one table view per schema with no code. Declare the providing plugin as a dependency. Every declared view’s context carries viewId (the view id as written in ui.json) and pluginId, so the shared source reads context.viewId as the schema name in get(context), and table events receive it in payload.context.

Documentation sous licence CC BY 4.0 · © les contributeurs de SCFlow ·Retour à supplychainflow.org