Classes
Import these from @grafloria/renderer.
Classes
EdgeOptimizer
tsclass EdgeOptimizer
Methods
constructor(options: EdgeOptimizerOptions = {})get stats(): Readonly<OptimizerStats>update(frame: OptimizerFrame): void— Run the pass for a frame. Cheap when little changed: a frame whose links and nodes all carry the same signatures as last time performs zero segment tests and zero label searches.getJumps(linkId: string): Intersection[]— The crossings on this link, for the jump-point path builder. Empty when the link draws no jumps.getLabelOffset(linkId: string, labelId: string, fallback: Point): Point— The offset this label should actually be drawn at. For a label that did not opt intoautoOffsetthis is exactly the offset the author set.reset(): void— Drop all state (renderer disposal, or a wholesale diagram swap).
JumpPointDetector
JumpPointDetector detects line-line intersections for jump point rendering.
Features:
- Line segment intersection detection
- Angle calculation between intersecting lines
- Multiple detection modes (all, perpendicular, threshold)
- Performance optimized for many links
Algorithm: Uses parametric line intersection algorithm with bounds checking.
tsclass JumpPointDetector
Methods
findIntersection(line1: LineSegment, line2: LineSegment): Intersection | null— Find intersection between two line segmentsdetectIntersections( targetLink: LinkWithPoints, otherLinks: LinkWithPoints[], mode: DetectionMode = 'all', threshold: number = 45 ): Intersection[]— Detect all intersections for a link with other links
JumpPointRenderer
JumpPointRenderer modifies link paths to show jump points at intersections.
Supports three visual styles:
- arc: Small arc over intersection
- gap: Break in line
- bridge: Bridge shape over intersection
Algorithm:
- Parse path to extract points
- Sort intersections by position
- Split path at intersections
- Insert jump point geometry
- Reconstruct path
tsclass JumpPointRenderer
Methods
renderWithJumpPoints( pathData: string, intersections: Intersection[], config: JumpPointConfig, originalProps?: Record<string, any> ): VNode— Render path with jump points at intersections
LabelRenderer
LabelRenderer generates SVG (or HTML) VNodes for link labels.
Features:
- Position labels at any point along path (0-1), or in one of three slots
- Auto-rotation with path or fixed angle
- Text wrapping with maxWidth
- Multiple labels per link
- Rich styling support
- HTML content and author templates
Architecture: Uses LinkModel utilities (getPointAtPosition, getAngleAt) for positioning. Returns VNode tree compatible with framework-agnostic rendering.
tsclass LabelRenderer
Methods
renderLabel(label: LinkLabel, link: LinkModel, context: LabelRenderContext = {}): VNode | null— Render a label on a linklabelBox(label: LinkLabel): { width: number; height: number }— Estimated on-screen box of a label, in LOCAL units (before the path anchor and offset are applied). The edge optimizer needs a box to test collisions against; HTML/template labels declare their own, and text labels are measured with the same estimator the background rect already uses.
RouteMemo
tsclass RouteMemo
Methods
get stats(): Readonly<RouteMemoStats>get size(): numberbeginFrame(rects: Map<string, Rect>, obstacleEpoch: string): Rect[]— Start a frame. Diffs this frame's node rectangles against last frame's and returns the world regions that changed — each moved node contributes BOTH where it was and where it now is, because a link routed around its old position is just as stale as one routed through its new one.
obstacleEpoch covers obstacle-set changes that are NOT node rects — a
group collapsing hides its members and adds a block, and no node moved. A
change there drops the whole cache, which is the honest thing to do: it is
rare, and reasoning about which links a collapse touched is how you ship a
stale route.
lookup(linkId: string, key: string): RoutedPath | undefined— The route for this link if its inputs are unchanged since we cached it.store(linkId: string, key: string, routed: RoutedPath): voiddrop(linkId: string): void— A route computed but NOT cacheable (e.g. no route found) must not keep a stale entry.invalidate(linkIds: Iterable<string>): voidclear(): void
RouteSolverBridge
tsclass RouteSolverBridge
Methods
constructor(options: RouteSolverBridgeOptions = {})get stats(): Readonly<RouteSolverStats>hasRoutesFor(version: number): boolean— True once the solver has an answer for THIS world — i.e. one safe to paint.routeFor(linkId: string, version: number): RoutedPath | undefinedsubmit(version: number, edges: SolverEdge[], obstacles: Obstacle[]): void— Ask for this world to be solved. Idempotent per version: submitting the same world twice does nothing, so calling this every frame is free.
If a solve is already running for an older world, the new one is QUEUED, not raced — and if a third arrives first, it replaces the queued one. At most one solve in flight, and the newest world always wins.
dispose(): void
Was this page helpful?