import {FirstRenderedNodeData, RendererNode, RendererNodeType} from "./RendererNodeData"; import {TreeNode} from "./TreeNode"; import {StateBranchNode} from "./StateBranchNode"; import {GeneralHelpers} from "@xyflow/react"; import {getNode} from "./store"; import {getDimensions} from "../Tree"; export class TreeNodeAnchor implements RendererNode, FirstRenderedNodeData { constructor(public treeNode: TreeNode) {} getId(): string { return this.treeNode.id; } /** * Its target is always the testable node of the tree node it belongs to */ getTargetRenderNode(): RendererNodeType | undefined { return this.treeNode.testableNode } /** * Its source is the previous tree node's source anchor, unless it's the first tree node in the grove in which case it has no source */ getSourceRenderNode(): RendererNodeType | undefined { /** * This probably violates the Law of Demeter pretty badly but it will have to do srry.- */ if (this.treeNode.grove.isFirst(this.treeNode.id)) { return undefined; } return this.treeNode.grove.getPreviousTreeNode(this.treeNode.id)?.sourceAnchor as RendererNodeType } treeNodeForCalculatingFullWidth(): TreeNode | undefined { return (this.getTargetRenderNode() as StateBranchNode).getTreeNode() } /** * The source x here needs to be 0 because we're getting it from the x and width of the source, * we need to explicitly set to 0 to tell the engine that we don't want any extra x * (in tiers,in their respective node classes, for example, this method returns undefined to tell the engine to use the source's x) */ horizontalSourceX(getNode: GeneralHelpers["getNode"]): number | undefined { return 0 } /** * Since this anchor is horizontally centered and its tiny, we need to calculate half of this tree's root testable so that it is aligned property */ leftSpacing(): number { const {width} = getDimensions((this.getTargetRenderNode()!.getId())) || {width: 0, height: 0}; const leftSpacing = 60 return Math.max((width / 2), 0) + leftSpacing } getTargetRenderNodeId(): string { return this.getTargetRenderNode()!.getId() } getSourceRenderNodeId(): string { return this.getSourceRenderNode()?.getId() || '' } }