import { I as VisualGraph, d as EntityRect, f as Graph, k as Point, y as GraphNode } from "../types-BAEQTwK_.mjs"; //#region src/layout/index.d.ts /** * Common options understood by every layout adapter. Engine-specific options * extend this per adapter. */ interface LayoutOptions { /** * Layout direction. Defaults to `graph.direction ?? 'down'`. */ direction?: 'up' | 'down' | 'left' | 'right'; /** * Spacing hints (engines map these to their native options where the * mapping is well-defined; engines without one ignore them — see each * adapter's JSDoc). */ spacing?: { /** Space between sibling nodes. */ node?: number; /** Space between layers/ranks (hierarchical engines). */ layer?: number; }; /** * Node size resolver. Text measurement belongs to the renderer, so layout * adapters never guess: sizes come from this callback, falling back to the * node's own `width`/`height`, falling back to {@link DEFAULT_NODE_SIZE}. */ measure?: (node: GraphNode) => { width: number; height: number; }; /** * Pinned nodes keep their current `x`/`y` (for engines that support * fixing, e.g. d3-force `fx`/`fy`). */ isFixed?: (node: GraphNode) => boolean; /** Seed for engines with randomness — same seed, same layout. */ seed?: number; /** * Portable layout constraints. **Advisory**, like port `direction`: engines * that can express a constraint honor it, others ignore it. Per-adapter * support is documented on each adapter. */ constraints?: LayoutConstraints; } /** * Portable constraints understood by (some) layout adapters. * * | Constraint | ELK | Graphviz (dot) | dagre | force engines | * |------------|-----|----------------|-------|----------------| * | `layer` | partitions | `rank=same` groups | ignored | ignored | */ interface LayoutConstraints { /** * Assign nodes to ordered layers along the flow axis (`0`, `1`, `2`, …; * `undefined` leaves the node unconstrained). Nodes with the same value * land in the same layer; smaller values come earlier in the layout * direction. ELK maps this to partitions * (`elk.partitioning.partition`); the Graphviz `dot` engine maps it to * `{ rank=same; … }` groups (same-layer grouping — ordering *between* * constrained layers still follows the edges). */ layer?: (node: GraphNode) => number | undefined; } /** * A one-shot layout: pure function from graph to a positioned * {@link VisualGraph}. Async when the engine is async (ELK, Graphviz WASM) — * engine async-ness is not ours to hide. */ type LayoutFn = (graph: Graph | VisualGraph, options?: O) => VisualGraph | Promise; /** * One frame of an iterative (physics) layout: node positions by id, plus the * simulation's remaining energy. Positions are node *top-left* corners, * consistent with `VisualNode.x/y`. */ interface LayoutFrame { positions: Record; /** Remaining simulation energy, 1 → 0. */ alpha: number; } /** * An iterative layout (force simulations): each `next()` advances one tick * and yields a {@link LayoutFrame}; the caller owns pacing (e.g. one tick per * animation frame) and cancellation (drop the generator). The generator's * return value is the settled {@link VisualGraph}. */ type IterativeLayoutFn = (graph: Graph | VisualGraph, options?: O) => Generator; /** Fallback node size when neither `measure` nor node dimensions are set. */ declare const DEFAULT_NODE_SIZE: { readonly width: 100; readonly height: 50; }; /** * Resolve a node's layout size: `options.measure` → node `width`/`height` → * {@link DEFAULT_NODE_SIZE}. Zero sizes count as unset (layout engines * overlap zero-sized nodes). */ declare function getNodeSize(node: GraphNode, options?: Pick): { width: number; height: number; }; /** * **Mutable.** Write a {@link LayoutFrame}'s positions onto the graph's nodes * in place. Positions are non-structural, so this is safe under the index * contract (no `invalidateIndex` needed) and cheap enough for per-animation- * frame use. Nodes absent from the frame are left untouched. * * @example * ```ts * for (const frame of genForceLayout(graph)) { * applyLayoutFrame(graph, frame); * render(graph); * } * ``` */ declare function applyLayoutFrame(graph: Graph, frame: LayoutFrame): void; /** * Bounding rect of all positioned nodes (and edge route points, when * present). Returns a zero rect for graphs with no geometry. * * @example * ```ts * const bounds = getLayoutBounds(laidOut); * svg.setAttribute('viewBox', `${bounds.x} ${bounds.y} ${bounds.width} ${bounds.height}`); * ``` */ declare function getLayoutBounds(graph: Graph | VisualGraph): EntityRect; interface LayoutTransitionOptions { /** Number of frames to yield. Default: 30. */ steps?: number; /** * Easing function mapping linear progress `t` (0 → 1] to eased progress. * Default: smoothstep (`t² · (3 − 2t)`). */ ease?: (t: number) => number; } /** * Animate between two layouts of the same graph: yields interpolated * {@link LayoutFrame}s from the node positions in `from` to those in `to` * (drive them with {@link applyLayoutFrame}, e.g. one per animation frame), * and returns `to`. This is what makes layouts swappable live — lay out with * one engine, re-lay out with another, and tween between them. * * Nodes are matched by id; nodes without a position in `from` (or absent from * it) start at their `to` position. Edge routes are not interpolated — frames * carry node positions only; hide or re-route edges during the transition. * `alpha` cools linearly 1 → 0 like the physics layouts. * * @example * ```ts * const next = await getElkLayout(graph); * for (const frame of genLayoutTransition(graph, next)) { * applyLayoutFrame(graph, frame); * render(graph); * } * ``` */ declare function genLayoutTransition(from: Graph | VisualGraph, to: VisualGraph, options?: LayoutTransitionOptions): Generator; /** * **Mutable.** Shift the graph's geometry by `(dx, dy)` in place: node * positions, edge route `points`, and edge label rects. Non-structural, so no * index invalidation is needed. * * Hierarchy-aware: child nodes (`parentId` set) use parent-relative * coordinates (the ELK/xyflow convention), so only top-level nodes are * shifted — children move with their parents. Likewise, an edge's geometry is * shifted only when its containing coordinate system is the root (the LCA of * its endpoints is no node). */ declare function translateGraph(graph: Graph, dx: number, dy: number): void; /** * **Mutable.** Translate the graph in place so its {@link getLayoutBounds} * center coincides with `rect`'s center — e.g. center a fresh layout in the * viewport. Graphs without geometry are left untouched. * * @example * ```ts * centerGraph(laidOut, { x: 0, y: 0, width: canvas.width, height: canvas.height }); * ``` */ declare function centerGraph(graph: Graph, rect: EntityRect): void; //#endregion export { DEFAULT_NODE_SIZE, IterativeLayoutFn, LayoutConstraints, LayoutFn, LayoutFrame, LayoutOptions, LayoutTransitionOptions, applyLayoutFrame, centerGraph, genLayoutTransition, getLayoutBounds, getNodeSize, translateGraph };