@fxhash/open-form-graph 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/OpenFormGraph-CdcWNN86.d.ts +24 -0
- package/dist/OpenFormGraph-i8VSTamk.js +2170 -0
- package/dist/OpenFormGraph-i8VSTamk.js.map +1 -0
- package/dist/_types-CjgCTzqc.d.ts +82 -0
- package/dist/components.d.ts +3 -0
- package/dist/components.js +4 -0
- package/dist/constants-BNPHdbBA.d.ts +313 -0
- package/dist/index.d.ts +125 -133
- package/dist/index.js +3 -2098
- package/dist/provider-PqOen2FE.js +106 -0
- package/dist/provider-PqOen2FE.js.map +1 -0
- package/dist/provider.d.ts +3 -0
- package/dist/provider.js +3 -0
- package/package.json +15 -10
- package/dist/index.js.map +0 -1
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"OpenFormGraph-i8VSTamk.js","names":["node: SimNode | string | number","link: SimLink","highlight: CustomHighlight | SimpleHighlight","n: any","id: string","links: SimLink[]","nodeId: string","stopAtId: string","links: RawLink[]","depth: number","id","stop?: string","nodes: SimNode[]","rootId: string","src: string","img","canvas: HTMLCanvasElement","options?: {\n onUpdate?: TransformListener\n onClick?: MouseListener\n onMove?: MouseListener\n offset?: Point\n }","clientX: number","clientY: number","rect","a: number","b: number","t: number","next: Transform","e: WheelEvent","e: MouseEvent","e: TouchEvent","update: Partial<Transform>","worldX: number","worldY: number","newScale?: number","noInteraction: boolean","focus: Focus | null","offset: Point","ctx: CanvasRenderingContext2D","x: number","y: number","radius: number","options?: {\n fill?: boolean\n fillStyle?: string\n stroke?: boolean\n strokeStyle?: string\n lineWidth?: number\n }","width: number","height: number","options?: {\n fill?: boolean\n fillStyle?: string\n stroke?: boolean\n strokeStyle?: string\n lineWidth?: number\n borderRadius?: number\n }","image: HTMLImageElement","borderRadius: number","opacity: number","bgColor?: string","options?: {\n fill?: boolean\n fillStyle?: string\n stroke?: boolean\n strokeStyle?: string\n lineWidth?: number\n rotation?: number\n borderRadius?: number\n }","rgb: RGB","arg: number | ColorTransform","factor: number","white: boolean","images: string[]","maxNodes: number","maxChildren: number","nodes: RawNode[]","links: RawLink[]","index","label: string","startId: string","nodes: SimNode[]","links: SimLink[]","highlights: HighlightStyle[]","rootHashes: string[]","hash: string","nestedChildren: NestedRawNode<RawNode>[]","result: NestedRawNode<RawNode>[]","node: NestedRawNode<RawNode>","nodeHash: string","r: number","cx: number","cy: number","angle: number","x: number","y: number","id: string","x: T","random: () => number","d: NodeDatum","nodeById: Map<string | number, NodeDatum>","nodeId: string | number","links?: LinkDatum[]","id: (node: NodeDatum, i: number, nodes: NodeDatum[]) => string | number","strength: (\n link: LinkDatum,\n i: number,\n links: LinkDatum[]\n ) => number | [number, number]","strengths: (number | [number, number])[]","distance: (link: LinkDatum, i: number, links: LinkDatum[]) => number","distances: number[]","nodes: NodeDatum[] | undefined","count: number[]","bias: number[]","random: (() => number) | undefined","link: LinkDatum","alpha: number","s0: number","s1: number","_nodes: NodeDatum[]","_random: () => number","_?: LinkDatum[]","_?: (node: NodeDatum, i: number, nodes: NodeDatum[]) => string | number","_?: number","_?:\n | number\n | ((\n link: LinkDatum,\n i: number,\n links: LinkDatum[]\n ) => number | [number, number])","_?: number | ((link: LinkDatum, i: number, links: LinkDatum[]) => number)","data: string","depth: number","props: OpenGraphSimulationProps","img","cx: number","cy: number","candidates: SimNode[]","node: SimNode","_x: number","_y: number","worldX: number","worldY: number","x: number","y: number","node: SimNode | null","options: { noToggle?: boolean; triggerFocus?: boolean }","t: Transform","focusSessionNode: null | SimNode","index","data: RawGraphData","rootId: string","x","triggerFocus: boolean","alpha: number","nodeId: string","id: string","link: SimLink","ctx: CanvasRenderingContext2D","options: {\n dim: boolean\n hasSelection: boolean\n highlight?: HighlightStyle\n }","options: {\n dim: boolean\n transform: Transform\n }","size: number","dimmed: boolean","isLight: boolean","options: {\n fill: string\n stroke: string\n highlighted: boolean\n highlightedStroke: string\n isSelected: boolean\n dim: boolean\n transform: Transform\n clusterSize: number\n isLight: boolean\n }","options: {\n fill: string\n stroke: string\n highlighted: boolean\n highlightedStroke: string\n isHovered: boolean\n isLiquidated: boolean\n dim: boolean\n image?: HTMLImageElement\n }","context: CanvasRenderingContext2D","node: any","width: number","height: number","theme: ThemeMode","hide: boolean","highlights: HighlightStyle[]","noInteraction: boolean","nodeId?: string | null","circle","props: OpenFormGraphProps"],"sources":["../src/util/types.ts","../src/util/graph.ts","../src/util/img.ts","../src/sim/TransformCanvas.ts","../src/util/canvas.ts","../src/util/color.ts","../src/util/data.ts","../src/sim/_interfaces.ts","../src/util/math.ts","../src/util/highlights.ts","../src/sim/asymmetric-link.ts","../src/util/hash.ts","../src/sim/OpenGraphSimulation.ts","../src/components/OpenFormGraph.tsx"],"sourcesContent":["import { SimNode, SimLink } from \"@/_types\"\nimport { CustomHighlight, SimpleHighlight } from \"@/sim/_types\"\n\nexport function isSimNode(node: SimNode | string | number): node is SimNode {\n return typeof node === \"object\" && \"id\" in node\n}\n\nexport function isSimLink(link: SimLink): link is SimLink {\n return (\n typeof link === \"object\" &&\n \"source\" in link &&\n typeof link.source !== \"string\"\n )\n}\n\nexport function isCustomHighlight(\n highlight: CustomHighlight | SimpleHighlight\n): highlight is CustomHighlight {\n if (typeof highlight === \"string\") return false\n return true\n}\n","import { SimLink, RawLink, SimNode } from \"@/_types\"\nimport { isSimNode } from \"./types\"\n\nexport function getNodeId(n: any) {\n return typeof n === \"object\" && n !== null && \"id\" in n ? n.id : n\n}\n\nexport function getParents(id: string, links: SimLink[]): string[] {\n return links\n .filter(l => {\n const targetId = isSimNode(l.target) ? l.target.id : l.target\n return targetId === id\n })\n .map(link =>\n isSimNode(link.source) ? link.source.id : link.source.toString()\n )\n}\n\nexport function getAllParentsUntil(\n nodeId: string,\n links: SimLink[],\n stopAtId: string\n): string[] {\n const parent = getParents(nodeId, links)[0]\n\n if (!parent || parent === stopAtId) {\n return []\n }\n\n return [parent, ...getAllParentsUntil(parent, links, stopAtId)]\n}\n\nexport function getChildren(id: string, links: SimLink[]): string[] {\n return links\n .filter(l => {\n const sourceId = isSimNode(l.source) ? l.source.id : l.source\n return sourceId === id\n })\n .map(link => link.target.toString())\n}\n\nexport function getClusterSize(id: string, links: RawLink[]): number {\n const children = getChildren(id, links)\n return children.reduce((acc, childId) => {\n return acc + getClusterSize(childId, links)\n }, children.length || 0)\n}\n\nexport function getNodeDepth(id: string, links: RawLink[]): number {\n function getDepth(id: string, depth: number): number {\n const parents = getParents(id, links)\n if (parents.length === 0) return depth\n return getDepth(parents[0], depth + 1)\n }\n return getDepth(id, 0)\n}\n\nexport function getRootParent(\n id: string,\n links: RawLink[],\n stop?: string\n): string | null {\n let currentId = id\n while (true) {\n const parents = getParents(currentId, links)\n if (stop && parents.includes(stop)) return currentId\n if (parents.length === 0) return currentId\n currentId = parents[0]\n }\n}\n\nexport function hasOnlyLeafs(id: string, links: RawLink[]): boolean {\n const children = getChildren(id, links)\n return children.every(childId => getChildren(childId, links).length === 0)\n}\n\nexport function getNodeSubgraph(\n nodeId: string,\n nodes: SimNode[],\n links: SimLink[],\n rootId: string\n): { nodes: SimNode[]; links: SimLink[] } {\n const nodesById = Object.fromEntries(nodes.map(n => [n.id, n]))\n const parentSet = new Set<string>()\n const childSet = new Set<string>()\n const subLinks = new Set<SimLink>()\n\n let currentId = nodeId\n while (currentId !== rootId) {\n const parentLink = links.find(l => {\n const targetId = isSimNode(l.target) ? l.target.id : l.target\n return targetId === currentId\n })\n if (!parentLink) break\n const parentId = isSimNode(parentLink.source)\n ? parentLink.source.id\n : parentLink.source\n if (parentSet.has(parentId.toString())) break\n parentSet.add(parentId.toString())\n subLinks.add(parentLink)\n currentId = parentId.toString()\n }\n\n function collectChildren(id: string) {\n for (const link of links) {\n const sourceId = isSimNode(link.source) ? link.source.id : link.source\n const targetId = isSimNode(link.target) ? link.target.id : link.target\n if (sourceId === id && !childSet.has(targetId.toString())) {\n childSet.add(targetId.toString())\n subLinks.add(link)\n collectChildren(targetId.toString())\n }\n }\n }\n collectChildren(nodeId)\n\n const validIds = new Set<string>([...parentSet, nodeId, ...childSet])\n const filteredLinks = Array.from(subLinks).filter(link => {\n const sourceId = isSimNode(link.source) ? link.source.id : link.source\n const targetId = isSimNode(link.target) ? link.target.id : link.target\n return (\n validIds.has(sourceId.toString()) && validIds.has(targetId.toString())\n )\n })\n\n const allNodeIds = Array.from(validIds)\n const subNodes = allNodeIds.map(id => nodesById[id]).filter(Boolean)\n\n return { nodes: subNodes, links: filteredLinks }\n}\n","export function loadHTMLImageElement(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n img.onload = () => resolve(img)\n img.onerror = reject\n img.src = src\n })\n}\n","import {\n Transform,\n Point,\n TransformListener,\n MouseListener,\n Focus,\n} from \"./_types\"\n\nconst MIN_ZOOM = 0.1\nconst MAX_ZOOM = 10\nconst CLICK_THRESHOLD = 5\nconst ANIMATION_SPEED = 0.07\nconst DRAG_ANIMATION_SPEED = 0.5\nconst ANIMATION_THRESHOLD = { x: 0.5, y: 0.5, scale: 0.001 }\nconst MOMENTUM_DAMPING = 0.91\nconst MIN_VELOCITY = 0.5\n\nexport class TransformCanvas {\n private canvas: HTMLCanvasElement\n private transform: Transform = { x: 0, y: 0, scale: 1 }\n private targetTransform: Transform = { x: 0, y: 0, scale: 1 }\n private isAnimating = false\n private animationFrame: number | null = null\n private focus: Focus | null = null\n private offset: Point = { x: 0, y: 0 }\n\n private isDragging = false\n private dragStart: Point | null = null\n private hasMoved = false\n private lastPointerPos: Point = { x: 0, y: 0 }\n private lastMovePos: Point = { x: 0, y: 0 }\n\n private velocity: Point = { x: 0, y: 0 }\n private lastDragTime: number = 0\n private momentumFrame: number | null = null\n\n private touchStart: Point | null = null\n private pinchStartDist: number | null = null\n private pinchStartScale: number = 1\n\n private noInteraction: boolean = false\n private dpr: number = 1\n private resizeObserver: ResizeObserver | null = null\n private mediaQueryList: MediaQueryList | null = null\n\n onUpdate?: TransformListener\n onClick?: MouseListener\n onMove?: MouseListener\n\n constructor(\n canvas: HTMLCanvasElement,\n options?: {\n onUpdate?: TransformListener\n onClick?: MouseListener\n onMove?: MouseListener\n offset?: Point\n }\n ) {\n this.canvas = canvas\n this.onUpdate = options?.onUpdate\n this.onClick = options?.onClick\n this.onMove = options?.onMove\n this.offset = options?.offset || { x: 0, y: 0 }\n this.dpr = window.devicePixelRatio || 1\n\n this.bindEventHandlers()\n this.attachEventListeners()\n this.setupDPRMonitoring()\n }\n\n private bindEventHandlers() {\n this.handleWheel = this.handleWheel.bind(this)\n this.handleMouseDown = this.handleMouseDown.bind(this)\n this.handleMouseMove = this.handleMouseMove.bind(this)\n this.handleMouseUp = this.handleMouseUp.bind(this)\n this.handleCanvasClick = this.handleCanvasClick.bind(this)\n this.handleTouchStart = this.handleTouchStart.bind(this)\n this.handleTouchMove = this.handleTouchMove.bind(this)\n this.handleTouchEnd = this.handleTouchEnd.bind(this)\n }\n\n private attachEventListeners() {\n this.canvas.addEventListener(\"wheel\", this.handleWheel, { passive: false })\n this.canvas.addEventListener(\"mousedown\", this.handleMouseDown)\n this.canvas.addEventListener(\"click\", this.handleCanvasClick)\n window.addEventListener(\"mousemove\", this.handleMouseMove)\n window.addEventListener(\"mouseup\", this.handleMouseUp)\n\n this.canvas.addEventListener(\"touchstart\", this.handleTouchStart, {\n passive: false,\n })\n this.canvas.addEventListener(\"touchmove\", this.handleTouchMove, {\n passive: false,\n })\n this.canvas.addEventListener(\"touchend\", this.handleTouchEnd, {\n passive: false,\n })\n this.canvas.addEventListener(\"touchcancel\", this.handleTouchEnd, {\n passive: false,\n })\n }\n\n private setupDPRMonitoring() {\n if (typeof ResizeObserver !== \"undefined\") {\n this.resizeObserver = new ResizeObserver(() => {\n this.updateDPR()\n })\n this.resizeObserver.observe(this.canvas)\n }\n\n const updateDPRFromMediaQuery = () => {\n this.updateDPR()\n }\n\n const dpr = window.devicePixelRatio || 1\n this.mediaQueryList = window.matchMedia(`(resolution: ${dpr}dppx)`)\n\n if (this.mediaQueryList.addEventListener) {\n this.mediaQueryList.addEventListener(\"change\", updateDPRFromMediaQuery)\n }\n }\n\n private updateDPR() {\n const newDPR = window.devicePixelRatio || 1\n if (newDPR !== this.dpr) {\n const oldDPR = this.dpr\n this.dpr = newDPR\n\n const scale = newDPR / oldDPR\n this.transform.x *= scale\n this.transform.y *= scale\n this.targetTransform.x *= scale\n this.targetTransform.y *= scale\n\n this.onUpdate?.(this.transform)\n\n if (this.mediaQueryList) {\n const updateDPRFromMediaQuery = () => {\n this.updateDPR()\n }\n\n if (this.mediaQueryList.removeEventListener) {\n this.mediaQueryList.removeEventListener(\n \"change\",\n updateDPRFromMediaQuery\n )\n }\n this.mediaQueryList = window.matchMedia(`(resolution: ${newDPR}dppx)`)\n\n if (this.mediaQueryList.addEventListener) {\n this.mediaQueryList.addEventListener(\n \"change\",\n updateDPRFromMediaQuery\n )\n }\n }\n }\n }\n\n public toCanvasCoords(clientX: number, clientY: number): Point {\n const rect = this.canvas.getBoundingClientRect()\n return {\n x: (clientX - rect.left) * this.dpr,\n y: (clientY - rect.top) * this.dpr,\n }\n }\n\n private toCSSCoords(clientX: number, clientY: number): Point {\n const rect = this.canvas.getBoundingClientRect()\n return {\n x: clientX - rect.left,\n y: clientY - rect.top,\n }\n }\n\n private startMomentum() {\n if (\n Math.abs(this.velocity.x) > MIN_VELOCITY ||\n Math.abs(this.velocity.y) > MIN_VELOCITY\n ) {\n if (!this.momentumFrame) {\n this.momentumFrame = requestAnimationFrame(this.applyMomentum)\n }\n }\n }\n\n private applyMomentum = () => {\n this.targetTransform.x += this.velocity.x * this.dpr\n this.targetTransform.y += this.velocity.y * this.dpr\n\n this.velocity.x *= MOMENTUM_DAMPING\n this.velocity.y *= MOMENTUM_DAMPING\n\n if (\n Math.abs(this.velocity.x) > MIN_VELOCITY ||\n Math.abs(this.velocity.y) > MIN_VELOCITY\n ) {\n this.startAnimation()\n this.momentumFrame = requestAnimationFrame(this.applyMomentum)\n } else {\n this.velocity = { x: 0, y: 0 }\n this.momentumFrame = null\n }\n }\n\n private lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t\n }\n\n private animateTransform = () => {\n const target = this.focus?.() || this.targetTransform\n const prev = this.transform\n\n const animationSpeed = this.isDragging\n ? DRAG_ANIMATION_SPEED\n : ANIMATION_SPEED\n\n const next: Transform = {\n x: this.lerp(prev.x, target.x, animationSpeed / this.dpr),\n y: this.lerp(prev.y, target.y, animationSpeed / this.dpr),\n scale: this.lerp(prev.scale, target.scale, animationSpeed / this.dpr),\n }\n\n const done =\n Math.abs(next.x - target.x) < ANIMATION_THRESHOLD.x &&\n Math.abs(next.y - target.y) < ANIMATION_THRESHOLD.y &&\n Math.abs(next.scale - target.scale) < ANIMATION_THRESHOLD.scale\n\n if (done) {\n this.transform = { ...target }\n this.stopAnimation()\n } else {\n this.transform = next\n this.onUpdate?.(this.transform)\n this.animationFrame = requestAnimationFrame(this.animateTransform)\n }\n }\n\n private startAnimation() {\n if (!this.isAnimating) {\n this.isAnimating = true\n this.animationFrame = requestAnimationFrame(this.animateTransform)\n }\n }\n\n private stopAnimation() {\n this.isAnimating = false\n this.focus = null\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame)\n this.animationFrame = null\n }\n }\n\n private interruptAnimation() {\n this.targetTransform = { ...this.transform }\n if (this.isAnimating) {\n this.stopAnimation()\n }\n if (this.momentumFrame) {\n cancelAnimationFrame(this.momentumFrame)\n this.momentumFrame = null\n this.velocity = { x: 0, y: 0 }\n }\n }\n\n private handleWheel(e: WheelEvent) {\n e.preventDefault()\n e.stopPropagation()\n if (this.noInteraction) return\n\n if (this.momentumFrame) {\n cancelAnimationFrame(this.momentumFrame)\n this.momentumFrame = null\n this.velocity = { x: 0, y: 0 }\n }\n\n if (this.focus) {\n this.interruptAnimation()\n this.focus = null\n }\n\n const canvasCoords = this.toCanvasCoords(e.clientX, e.clientY)\n const scaleFactor = e.deltaY > 0 ? 0.95 : 1.05\n\n const newScale = Math.max(\n MIN_ZOOM,\n Math.min(MAX_ZOOM, this.targetTransform.scale * scaleFactor)\n )\n\n const { x: currentX, y: currentY, scale: currentScale } = this.transform\n\n const worldX =\n (canvasCoords.x - currentX - this.offset.x * currentScale) / currentScale\n const worldY =\n (canvasCoords.y - currentY - this.offset.y * currentScale) / currentScale\n\n const newX = canvasCoords.x - worldX * newScale - this.offset.x * newScale\n const newY = canvasCoords.y - worldY * newScale - this.offset.y * newScale\n\n this.targetTransform = {\n x: newX,\n y: newY,\n scale: newScale,\n }\n\n this.startAnimation()\n }\n\n private handleMouseDown(e: MouseEvent) {\n if (this.noInteraction) return\n\n this.interruptAnimation()\n this.isDragging = true\n this.hasMoved = false\n this.dragStart = { x: e.clientX, y: e.clientY }\n this.lastPointerPos = { x: e.clientX, y: e.clientY }\n }\n\n private handleMouseMove(e: MouseEvent) {\n if (this.noInteraction) return\n\n this.lastMovePos = { x: e.clientX, y: e.clientY }\n\n const cssCoords = this.toCSSCoords(e.clientX, e.clientY)\n this.onMove?.(cssCoords.x, cssCoords.y)\n\n if (!this.isDragging || !this.dragStart) return\n\n const dx = e.clientX - this.dragStart.x\n const dy = e.clientY - this.dragStart.y\n\n if (Math.abs(dx) > CLICK_THRESHOLD || Math.abs(dy) > CLICK_THRESHOLD) {\n this.hasMoved = true\n\n const deltaX = (e.clientX - this.lastPointerPos.x) * this.dpr\n const deltaY = (e.clientY - this.lastPointerPos.y) * this.dpr\n\n this.targetTransform.x += deltaX\n this.targetTransform.y += deltaY\n\n const now = Date.now()\n const dt = now - this.lastDragTime\n if (dt > 0 && dt < 100) {\n this.velocity.x = (deltaX / dt) * 16\n this.velocity.y = (deltaY / dt) * 16\n }\n\n this.lastPointerPos = { x: e.clientX, y: e.clientY }\n this.lastDragTime = now\n\n this.startAnimation()\n }\n }\n\n private handleMouseUp(e: MouseEvent) {\n if (this.isDragging && this.hasMoved) {\n this.startMomentum()\n }\n this.isDragging = false\n this.dragStart = null\n }\n\n private handleCanvasClick(e: MouseEvent) {\n if (this.noInteraction || this.hasMoved) return\n\n const cssCoords = this.toCSSCoords(e.clientX, e.clientY)\n this.onClick?.(cssCoords.x, cssCoords.y)\n }\n\n private handleTouchStart(e: TouchEvent) {\n if (this.noInteraction) return\n e.preventDefault()\n\n this.interruptAnimation()\n\n if (e.touches.length === 1) {\n const touch = e.touches[0]\n this.isDragging = true\n this.hasMoved = false\n this.touchStart = { x: touch.clientX, y: touch.clientY }\n this.lastPointerPos = { x: touch.clientX, y: touch.clientY }\n this.lastMovePos = { x: touch.clientX, y: touch.clientY }\n } else if (e.touches.length === 2) {\n this.isDragging = false\n const [t1, t2] = Array.from(e.touches)\n this.pinchStartDist = Math.hypot(\n t2.clientX - t1.clientX,\n t2.clientY - t1.clientY\n )\n this.pinchStartScale = this.targetTransform.scale\n }\n }\n\n private handleTouchMove(e: TouchEvent) {\n if (this.noInteraction) return\n e.preventDefault()\n\n if (e.touches.length === 1 && this.isDragging && this.touchStart) {\n const touch = e.touches[0]\n const dx = touch.clientX - this.touchStart.x\n const dy = touch.clientY - this.touchStart.y\n\n if (Math.abs(dx) > CLICK_THRESHOLD || Math.abs(dy) > CLICK_THRESHOLD) {\n this.hasMoved = true\n\n const deltaX = touch.clientX - this.lastPointerPos.x\n const deltaY = touch.clientY - this.lastPointerPos.y\n\n this.targetTransform.x += deltaX * this.dpr\n this.targetTransform.y += deltaY * this.dpr\n\n const now = Date.now()\n const dt = now - this.lastDragTime\n if (dt > 0 && dt < 100) {\n this.velocity.x = (deltaX / dt) * 16\n this.velocity.y = (deltaY / dt) * 16\n }\n\n this.lastPointerPos = { x: touch.clientX, y: touch.clientY }\n this.lastMovePos = { x: touch.clientX, y: touch.clientY }\n this.lastDragTime = now\n\n this.startAnimation()\n\n const cssCoords = this.toCSSCoords(touch.clientX, touch.clientY)\n this.onMove?.(cssCoords.x, cssCoords.y)\n }\n } else if (e.touches.length === 2 && this.pinchStartDist != null) {\n if (this.momentumFrame) {\n cancelAnimationFrame(this.momentumFrame)\n this.momentumFrame = null\n this.velocity = { x: 0, y: 0 }\n }\n\n const [t1, t2] = Array.from(e.touches)\n const dist = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY)\n\n let newScale = (dist / this.pinchStartDist) * this.pinchStartScale\n newScale = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, newScale))\n\n const centerX = (t1.clientX + t2.clientX) / 2\n const centerY = (t1.clientY + t2.clientY) / 2\n const canvasCenter = this.toCanvasCoords(centerX, centerY)\n\n const { x: currentX, y: currentY, scale: currentScale } = this.transform\n\n const worldX =\n (canvasCenter.x - currentX - this.offset.x * currentScale) /\n currentScale\n const worldY =\n (canvasCenter.y - currentY - this.offset.y * currentScale) /\n currentScale\n\n const newX = canvasCenter.x - worldX * newScale - this.offset.x * newScale\n const newY = canvasCenter.y - worldY * newScale - this.offset.y * newScale\n\n this.targetTransform = {\n x: newX,\n y: newY,\n scale: newScale,\n }\n\n this.startAnimation()\n }\n }\n\n private handleTouchEnd(e: TouchEvent) {\n if (this.noInteraction) return\n\n if (e.touches.length === 0) {\n if (this.isDragging && this.hasMoved) {\n this.startMomentum()\n } else if (\n this.isDragging &&\n !this.hasMoved &&\n this.onClick &&\n this.touchStart\n ) {\n const cssCoords = this.toCSSCoords(this.touchStart.x, this.touchStart.y)\n this.onClick(cssCoords.x, cssCoords.y)\n }\n\n this.isDragging = false\n this.touchStart = null\n this.hasMoved = false\n this.pinchStartDist = null\n } else if (e.touches.length === 1) {\n const touch = e.touches[0]\n this.isDragging = true\n this.hasMoved = false\n this.touchStart = { x: touch.clientX, y: touch.clientY }\n this.lastPointerPos = { x: touch.clientX, y: touch.clientY }\n this.pinchStartDist = null\n this.velocity = { x: 0, y: 0 }\n this.lastDragTime = Date.now()\n }\n }\n\n resetZoom() {\n this.targetTransform = { x: 0, y: 0, scale: 1 }\n this.startAnimation()\n }\n\n transformTo(update: Partial<Transform>) {\n this.targetTransform = { ...this.targetTransform, ...update }\n this.startAnimation()\n }\n\n public getTransformationFromWorld(\n worldX: number,\n worldY: number,\n newScale?: number\n ) {\n const scale = newScale ?? this.transform.scale\n\n const x =\n this.canvas.width / 2 +\n this.offset.x * this.dpr -\n worldX * scale -\n (this.canvas.width / 2 + this.offset.x * this.dpr) * scale\n const y =\n this.canvas.height / 2 +\n this.offset.y * this.dpr -\n worldY * scale -\n (this.canvas.height / 2 + this.offset.y * this.dpr) * scale\n\n return { x, y, scale }\n }\n\n public transformToWorld(worldX: number, worldY: number, newScale?: number) {\n const transform = this.getTransformationFromWorld(worldX, worldY, newScale)\n this.transformTo(transform)\n }\n\n trackCursor() {\n const cssCoords = this.toCSSCoords(this.lastMovePos.x, this.lastMovePos.y)\n this.onMove?.(cssCoords.x, cssCoords.y)\n }\n\n setNoInteraction(noInteraction: boolean) {\n this.noInteraction = noInteraction\n if (noInteraction) {\n this.isDragging = false\n this.dragStart = null\n }\n }\n\n focusOn(focus: Focus | null) {\n this.focus = focus\n if (focus) {\n const _focus = focus\n this.focus = () => {\n const worldFocus = _focus()\n if (!worldFocus) return null\n const transform = this.getTransformationFromWorld(\n worldFocus.x,\n worldFocus.y,\n worldFocus.scale\n )\n return transform\n }\n this.startAnimation()\n }\n }\n\n resetFocus() {\n this.focus = null\n }\n\n destroy() {\n this.stopAnimation()\n\n if (this.momentumFrame) {\n cancelAnimationFrame(this.momentumFrame)\n this.momentumFrame = null\n }\n\n this.canvas.removeEventListener(\"wheel\", this.handleWheel)\n this.canvas.removeEventListener(\"mousedown\", this.handleMouseDown)\n this.canvas.removeEventListener(\"click\", this.handleCanvasClick)\n this.canvas.removeEventListener(\"touchstart\", this.handleTouchStart)\n this.canvas.removeEventListener(\"touchmove\", this.handleTouchMove)\n this.canvas.removeEventListener(\"touchend\", this.handleTouchEnd)\n this.canvas.removeEventListener(\"touchcancel\", this.handleTouchEnd)\n window.removeEventListener(\"mousemove\", this.handleMouseMove)\n window.removeEventListener(\"mouseup\", this.handleMouseUp)\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect()\n this.resizeObserver = null\n }\n\n if (this.mediaQueryList) {\n const updateDPRFromMediaQuery = () => {\n this.updateDPR()\n }\n\n if (this.mediaQueryList.removeEventListener) {\n this.mediaQueryList.removeEventListener(\n \"change\",\n updateDPRFromMediaQuery\n )\n }\n this.mediaQueryList = null\n }\n }\n\n getTransform(): Readonly<Transform> {\n return { ...this.transform }\n }\n\n getTargetTransform(): Readonly<Transform> {\n return { ...this.targetTransform }\n }\n getFocus(): Readonly<Focus | null> {\n return this.focus ? { ...this.focus } : null\n }\n setOffset(offset: Point) {\n this.offset = offset\n }\n}\n","/**\n * draws a circle on the canvas\n * @param ctx - The canvas rendering context\n * @param x - The x-coordinate of the circle's center\n * @param y - The y-coordinate of the circle's center\n * @param radius - The radius of the circle (default is 5)\n * @param options - Optional parameters for styling the circle\n * @param options.fill - Whether to fill the circle (default is true)\n * @param options.fillStyle - The fill color of the circle\n * @param options.stroke - Whether to stroke the circle (default is false)\n * @param options.strokeStyle - The stroke color of the circle\n * @param options.lineWidth - The width of the stroke (default is 0.2)\n * @returns void\n */\nexport function circle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n radius: number = 5,\n options?: {\n fill?: boolean\n fillStyle?: string\n stroke?: boolean\n strokeStyle?: string\n lineWidth?: number\n }\n) {\n const {\n fill = true,\n fillStyle,\n stroke = false,\n strokeStyle,\n lineWidth = 0.2,\n } = options || {}\n\n ctx.save()\n if (fillStyle !== undefined) ctx.fillStyle = fillStyle\n if (strokeStyle !== undefined) ctx.strokeStyle = strokeStyle\n if (lineWidth !== undefined) ctx.lineWidth = lineWidth\n\n ctx.beginPath()\n ctx.arc(x, y, radius, 0, 2 * Math.PI)\n ctx.closePath()\n\n if (fill) {\n ctx.fill()\n }\n\n if (stroke) {\n ctx.stroke()\n }\n\n ctx.restore()\n}\n\n/**\n * draws a rectangle on the canvas\n * @param ctx - The canvas rendering context\n * @param x - The x-coordinate of the rectangle's top-left corner\n * @param y - The y-coordinate of the rectangle's top-left corner\n * @param width - The width of the rectangle\n * @param height - The height of the rectangle\n * @param options - Optional parameters for styling the rectangle\n * @param options.fill - Whether to fill the rectangle (default is true)\n * @param options.fillStyle - The fill color of the rectangle\n * @param options.stroke - Whether to stroke the rectangle (default is false)\n * @param options.strokeStyle - The stroke color of the rectangle\n * @param options.lineWidth - The width of the stroke (default is 0.2)\n * @param options.borderRadius - The radius of the corners (default is 0)\n * @returns void\n */\nexport function rect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n options?: {\n fill?: boolean\n fillStyle?: string\n stroke?: boolean\n strokeStyle?: string\n lineWidth?: number\n borderRadius?: number\n }\n) {\n const {\n fill = true,\n fillStyle,\n stroke = false,\n strokeStyle,\n lineWidth = 0.2,\n borderRadius = 0,\n } = options || {}\n\n ctx.save()\n\n if (fillStyle !== undefined) ctx.fillStyle = fillStyle\n if (strokeStyle !== undefined) ctx.strokeStyle = strokeStyle\n if (lineWidth !== undefined) ctx.lineWidth = lineWidth\n\n const r = Math.min(borderRadius, width / 2, height / 2)\n\n ctx.beginPath()\n\n if (r > 0) {\n ctx.moveTo(x + r, y)\n ctx.lineTo(x + width - r, y)\n ctx.quadraticCurveTo(x + width, y, x + width, y + r)\n ctx.lineTo(x + width, y + height - r)\n ctx.quadraticCurveTo(x + width, y + height, x + width - r, y + height)\n ctx.lineTo(x + r, y + height)\n ctx.quadraticCurveTo(x, y + height, x, y + height - r)\n ctx.lineTo(x, y + r)\n ctx.quadraticCurveTo(x, y, x + r, y)\n } else {\n ctx.rect(x, y, width, height)\n }\n\n ctx.closePath()\n\n if (fill) {\n ctx.fill()\n }\n\n if (stroke) {\n ctx.stroke()\n }\n\n ctx.restore()\n}\n\n/**\n * draws an image on the canvas with optional border radius and opacity\n * @param ctx - The canvas rendering context\n * @param image - The HTMLImageElement to draw\n * @param x - The x-coordinate of the image's top-left corner\n * @param y - The y-coordinate of the image's top-left corner\n * @param width - The width of the image\n * @param height - The height of the image\n * @param borderRadius - The radius of the corners (default is 0)\n * @param opacity - The opacity of the image (default is 1.0)\n * @param bgColor - Optional background color to fill the clipped area\n * @returns void\n */\nexport function img(\n ctx: CanvasRenderingContext2D,\n image: HTMLImageElement,\n x: number,\n y: number,\n width: number,\n height: number,\n borderRadius: number = 0,\n opacity: number = 1.0,\n bgColor?: string\n) {\n ctx.save()\n ctx.beginPath()\n ctx.globalAlpha = 1.0\n if (borderRadius > 0) {\n const r = Math.min(borderRadius, width / 2, height / 2)\n ctx.moveTo(x + r, y)\n ctx.lineTo(x + width - r, y)\n ctx.quadraticCurveTo(x + width, y, x + width, y + r)\n ctx.lineTo(x + width, y + height - r)\n ctx.quadraticCurveTo(x + width, y + height, x + width - r, y + height)\n ctx.lineTo(x + r, y + height)\n ctx.quadraticCurveTo(x, y + height, x, y + height - r)\n ctx.lineTo(x, y + r)\n ctx.quadraticCurveTo(x, y, x + r, y)\n } else {\n ctx.rect(x, y, width, height)\n }\n ctx.closePath()\n if (bgColor && opacity < 1) {\n ctx.save()\n ctx.fillStyle = bgColor\n ctx.fill()\n ctx.restore()\n }\n ctx.clip()\n ctx.globalAlpha = opacity\n ctx.drawImage(image, x, y, width, height)\n ctx.restore()\n}\n/*\n * draws a hexagon on the canvas\n * @param ctx - The canvas rendering context\n * @param x - The x-coordinate of the hexagon's center\n * @param y - The y-coordinate of the hexagon's center\n * @param radius - The radius of the hexagon\n * @param options - Optional parameters for styling the hexagon\n * @param options.fill - Whether to fill the hexagon (default is true)\n * @param options.fillStyle - The fill color of the hexagon\n * @param options.stroke - Whether to stroke the hexagon (default is false)\n * @param options.strokeStyle - The stroke color of the hexagon\n * @param options.lineWidth - The width of the stroke (default is 0.2)\n * @param options.rotation - The rotation angle of the hexagon in radians (default is 0)\n * @param options.borderRadius - The radius of the corners (default is 0)\n * @returns void\n */\nexport function hexagon(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n radius: number,\n options?: {\n fill?: boolean\n fillStyle?: string\n stroke?: boolean\n strokeStyle?: string\n lineWidth?: number\n rotation?: number\n borderRadius?: number\n }\n) {\n const {\n fill = true,\n fillStyle,\n stroke = false,\n strokeStyle,\n lineWidth = 0.2,\n rotation = 0,\n borderRadius = 0,\n } = options || {}\n\n ctx.save()\n\n if (fillStyle !== undefined) ctx.fillStyle = fillStyle\n if (strokeStyle !== undefined) ctx.strokeStyle = strokeStyle\n if (lineWidth !== undefined) ctx.lineWidth = lineWidth\n\n const sides = 6\n const angleStep = (Math.PI * 2) / sides\n\n ctx.beginPath()\n\n const points = []\n for (let i = 0; i < sides; i++) {\n const angle = rotation + i * angleStep\n points.push({\n x: x + radius * Math.cos(angle),\n y: y + radius * Math.sin(angle),\n })\n }\n\n if (borderRadius > 0) {\n const maxBorderRadius = Math.min(borderRadius, radius / 3)\n\n for (let i = 0; i < sides; i++) {\n const current = points[i]\n const next = points[(i + 1) % sides]\n const prev = points[(i - 1 + sides) % sides]\n\n const toPrev = { x: prev.x - current.x, y: prev.y - current.y }\n const toNext = { x: next.x - current.x, y: next.y - current.y }\n\n const lenPrev = Math.sqrt(toPrev.x * toPrev.x + toPrev.y * toPrev.y)\n const lenNext = Math.sqrt(toNext.x * toNext.x + toNext.y * toNext.y)\n\n const normPrev = { x: toPrev.x / lenPrev, y: toPrev.y / lenPrev }\n const normNext = { x: toNext.x / lenNext, y: toNext.y / lenNext }\n\n const cpPrev = {\n x: current.x + normPrev.x * maxBorderRadius,\n y: current.y + normPrev.y * maxBorderRadius,\n }\n\n const cpNext = {\n x: current.x + normNext.x * maxBorderRadius,\n y: current.y + normNext.y * maxBorderRadius,\n }\n\n if (i === 0) {\n ctx.moveTo(cpPrev.x, cpPrev.y)\n } else {\n ctx.lineTo(cpPrev.x, cpPrev.y)\n }\n\n ctx.quadraticCurveTo(current.x, current.y, cpNext.x, cpNext.y)\n }\n } else {\n ctx.moveTo(points[0].x, points[0].y)\n for (let i = 1; i < sides; i++) {\n ctx.lineTo(points[i].x, points[i].y)\n }\n }\n\n ctx.closePath()\n\n if (fill) {\n ctx.fill()\n }\n\n if (stroke) {\n ctx.stroke()\n }\n\n ctx.restore()\n}\n","import { ColorTransform, RGB } from \"@/_types\"\n\nexport interface ColorHandler {\n (arg?: number): string\n (arg: ColorTransform): ColorHandler\n rgb: RGB\n}\n/**\n * Some utility functions to handle colors\n */\nexport function color(rgb: RGB): ColorHandler {\n const colorHandler = function (\n arg: number | ColorTransform\n ): string | ColorHandler {\n if (typeof arg === \"number\") {\n return `rgba(${rgb[0]},${rgb[1]},${rgb[2]},${arg})`\n }\n\n if (typeof arg === \"function\") {\n const transformedRGB = arg(rgb)\n return color(transformedRGB)\n }\n\n return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`\n }\n\n colorHandler.rgb = rgb\n\n return colorHandler as ColorHandler\n}\n\n/**\n * Dims a color to white or black\n * @param color An array of 3 numbers representing RGB values (0-255)\n * @param dimFactor A value between 0 and 1 where 0 is completely black and 1 is the original color\n * @returns A new array with the dimmed RGB values\n */\nexport function dim(\n factor: number = 0.6,\n white: boolean = true\n): ColorTransform {\n const base = white ? 255 : 0\n return function (rgb: RGB): RGB {\n return [\n Math.round(rgb[0] + (base - rgb[0]) * (1 - factor)),\n Math.round(rgb[1] + (base - rgb[1]) * (1 - factor)),\n Math.round(rgb[2] + (base - rgb[2]) * (1 - factor)),\n ]\n }\n}\n","import {\n RawGraphData,\n RawNode,\n RawLink,\n SimLink,\n SimNode,\n NestedRawNode,\n} from \"@/_types\"\nimport { VOID_ROOT_ID } from \"@/context/constants\"\nimport { isSimNode } from \"./types\"\nimport { HighlightStyle } from \"@/sim/_types\"\n\nconst images: string[] = []\n\nexport function generateTree(\n maxNodes: number,\n maxChildren: number\n): RawGraphData {\n const nodes: RawNode[] = []\n const links: RawLink[] = []\n\n let index = 0\n\n function createNode(label: string): RawNode {\n const isRoot = label === VOID_ROOT_ID\n const idx = isRoot ? VOID_ROOT_ID : index++\n return {\n id: idx.toString(),\n label,\n imgSrc: isRoot ? undefined : images[index % images.length],\n }\n }\n\n const root = createNode(VOID_ROOT_ID)\n nodes.push(root)\n\n const queue = [root]\n\n while (queue.length > 0 && nodes.length < maxNodes) {\n const parent = queue.shift()!\n\n const rand = Math.random()\n const biased = Math.floor(Math.pow(rand, 2) * (maxChildren + 1)) // Skew towards 0\n const childrenCount = Math.min(biased, maxChildren)\n\n for (let i = 0; i < childrenCount; i++) {\n if (nodes.length >= maxNodes) break\n\n const child = createNode(`Node ${nodes.length}`)\n nodes.push(child)\n links.push({ source: parent.id, target: child.id })\n queue.push(child)\n }\n }\n\n return { nodes, links }\n}\n\nexport function getPrunedData(\n startId: string,\n nodes: SimNode[],\n links: SimLink[],\n highlights: HighlightStyle[] = []\n) {\n const nodesById = Object.fromEntries(nodes.map(node => [node.id, node]))\n const visibleNodes = []\n const visibleLinks = []\n const visited = new Set()\n\n ;(function traverseTree(node = nodesById[startId]) {\n // avoid circles\n if (!node || visited.has(node.id)) return\n visited.add(node.id)\n\n // Skip liquidated nodes unless they are highlighted\n if (\n node.status === \"LIQUIDATED\" &&\n !highlights.find(h => h.id === node.id)\n ) {\n return\n }\n\n visibleNodes.push(node)\n if (node?.state?.collapsed) return\n\n const childLinks = links.filter(\n l => (isSimNode(l.source) ? l.source.id : l.source) === node.id\n )\n\n for (const link of childLinks) {\n const targetNode = isSimNode(link.target)\n ? link.target\n : nodesById[link.target.toString()]\n\n // Check whether child should be included before adding link\n if (\n targetNode?.status === \"LIQUIDATED\" &&\n !highlights.find(h => h.id === targetNode.id)\n ) {\n continue // skip adding link to liquidated non-highlighted child\n }\n\n visibleLinks.push(link)\n traverseTree(targetNode)\n }\n })()\n\n return {\n nodes: visibleNodes,\n links: visibleLinks,\n }\n}\n\n/**\n * Automatically identifies root nodes and builds a nested structure\n * @param nodes Array of raw nodes\n * @param links Array of links between nodes\n * @returns Array of nested nodes starting from identified roots\n */\nexport function buildTreeFromGraphData(\n nodes: RawNode[],\n links: RawLink[]\n): NestedRawNode<RawNode>[] {\n // Create node map for faster lookups\n const nodeMap = new Map<string, RawNode>()\n nodes.forEach(node => nodeMap.set(node.id, node))\n\n // Create parent-child relationships\n const childrenMap = new Map<string, string[]>()\n const parentMap = new Map<string, string[]>()\n\n // Initialize with empty arrays\n nodes.forEach(node => {\n childrenMap.set(node.id, [])\n parentMap.set(node.id, [])\n })\n\n // Populate relationships based on links\n links.forEach(link => {\n // Assuming source is parent and target is child\n if (nodeMap.has(link.source) && nodeMap.has(link.target)) {\n // Add child to parent's children list\n const children = childrenMap.get(link.source) || []\n if (!children.includes(link.target)) {\n children.push(link.target)\n childrenMap.set(link.source, children)\n }\n\n // Add parent to child's parent list\n const parents = parentMap.get(link.target) || []\n if (!parents.includes(link.source)) {\n parents.push(link.source)\n parentMap.set(link.target, parents)\n }\n }\n })\n\n // Identify root nodes (nodes with no parents)\n const rootHashes: string[] = []\n nodeMap.forEach((_, hash) => {\n const parents = parentMap.get(hash) || []\n if (parents.length === 0) {\n rootHashes.push(hash)\n }\n })\n\n // Function to build a nested node and its descendants\n const buildNode = (\n hash: string,\n visited = new Set<string>()\n ): NestedRawNode<RawNode> | null => {\n if (visited.has(hash)) return null // Prevent circular references\n visited.add(hash)\n\n const node = nodeMap.get(hash)\n if (!node) return null\n\n const childHashes = childrenMap.get(hash) || []\n const nestedChildren: NestedRawNode<RawNode>[] = []\n\n childHashes.forEach(childHash => {\n const childNode = buildNode(childHash, new Set([...visited]))\n if (childNode) {\n nestedChildren.push(childNode)\n }\n })\n\n return {\n ...node,\n children: nestedChildren,\n }\n }\n\n // Build the nested structure starting from root nodes\n const result: NestedRawNode<RawNode>[] = []\n rootHashes.forEach(rootHash => {\n const nestedRoot = buildNode(rootHash)\n if (nestedRoot) {\n result.push(nestedRoot)\n }\n })\n\n // Handle orphaned cycles (if any) - nodes that are part of a cycle but have no root\n const processedNodes = new Set<string>()\n\n // Mark all nodes in the result as processed\n const markProcessed = (node: NestedRawNode<RawNode>) => {\n processedNodes.add(node.id)\n node.children.forEach(markProcessed)\n }\n result.forEach(markProcessed)\n\n // Find any unprocessed nodes and treat them as independent roots\n nodeMap.forEach((_, hash) => {\n if (!processedNodes.has(hash)) {\n const orphanedRoot = buildNode(hash)\n if (orphanedRoot) {\n result.push(orphanedRoot)\n }\n }\n })\n\n return result\n}\n\n/**\n * Recursively retrieves all parents of a node from a graph data structure\n * @param {string} nodeHash - The hash of the node to find parents for\n * @param {RawNode[]} nodes - Array of nodes in the graph\n * @param {RawLink[]} links - Array of links connecting the nodes\n * @returns {RawNode[]} - Array of parent nodes\n */\nexport function searchParents(\n nodeHash: string,\n nodes: RawNode[],\n links: RawLink[]\n): RawNode[] {\n const visited = new Set<string>()\n\n function findParents(hash: string): RawNode[] {\n if (visited.has(hash)) {\n return []\n }\n visited.add(hash)\n\n const immediateParents = links\n .filter(link => link.target === hash)\n .map(link => link.source)\n\n const parentNodes = nodes.filter(node => immediateParents.includes(node.id))\n\n const ancestorNodes = immediateParents.flatMap(parentHash =>\n findParents(parentHash)\n )\n\n return [...parentNodes, ...ancestorNodes]\n }\n\n return findParents(nodeHash)\n}\n","import { EventEmitter } from \"@fxhash/utils\"\nimport { HighlightStyle, Transform } from \"./_types\"\nimport {\n RawGraphData,\n RootNodeImageSources,\n SimNode,\n ThemeMode,\n} from \"@/_types\"\nimport { GraphConfig } from \"@/_interfaces\"\nimport { TransformCanvas } from \"./TransformCanvas\"\n\nexport interface IOpenGraphSimulation {\n width: number\n height: number\n config: GraphConfig\n rootImageSources: RootNodeImageSources\n canvas: HTMLCanvasElement\n theme: ThemeMode\n emitter: OpenGraphEventEmitter\n selectedNode: SimNode | null\n hoveredNode: SimNode | null\n highlights: HighlightStyle[]\n transformCanvas: TransformCanvas\n\n initialize(data: RawGraphData, rootId: string): void\n restart(): void\n resize(width: number, height: number): void\n setTheme(theme: ThemeMode): void\n setHideThumbnails(hide: boolean): void\n setSelectedNode(node: SimNode | null): void\n setHighlights(highlights: HighlightStyle[]): void\n setNoInteraction(noInteraction: boolean): void\n getNodeById(nodeId: string): SimNode | null\n getNodeScreenPosition(node: SimNode): { x: number; y: number }\n getNodeSize(nodeId: string): number\n destroy(): void\n}\n\nexport type OpenGraphEventsTypemap = {\n \"transform-changed\": Transform\n \"hovered-node-changed\": SimNode | null\n \"selected-node-changed\": SimNode | null\n draw: IOpenGraphSimulation\n}\nexport class OpenGraphEventEmitter extends EventEmitter<OpenGraphEventsTypemap> {}\n","type Point = { x: number; y: number }\n\nexport function distance(p1: Point, p2: Point): number {\n const dx = p2.x - p1.x\n const dy = p2.y - p1.y\n return Math.sqrt(dx * dx + dy * dy)\n}\n\nexport function getRadialPoint(\n r: number,\n cx: number,\n cy: number,\n angle: number = Math.random() * 2 * Math.PI\n): Point {\n return {\n x: cx + r * Math.cos(angle),\n y: cy + r * Math.sin(angle),\n }\n}\n\nexport function getAngle(cx: number, cy: number, x: number, y: number): number {\n return Math.atan2(y - cy, x - cx)\n}\n","import { RGB } from \"@/_types\"\nimport { CustomHighlight } from \"@/sim/_types\"\n\nconst blue = [94, 112, 235] as RGB\nexport const red = [238, 125, 121] as RGB\nconst redred = [255, 0, 0] as RGB\n\nexport class Highlight {\n static owner = (id: string): CustomHighlight => {\n return {\n id,\n strokeColor: red,\n }\n }\n static primary = (id: string): CustomHighlight => {\n return {\n id,\n linkTo: id,\n scale: 4.0,\n strokeColor: redred,\n linkColor: redred,\n onTop: true,\n isDetached: true,\n }\n }\n static evolved = (id: string): CustomHighlight => {\n return {\n id,\n linkTo: id,\n scale: 2.1,\n strokeColor: redred,\n linkColor: redred,\n onTop: true,\n isDetached: true,\n }\n }\n static minted = (id: string): CustomHighlight => {\n return {\n id,\n linkTo: id,\n scale: 1.5,\n strokeColor: redred,\n linkColor: redred,\n isDetached: true,\n onTop: true,\n }\n }\n}\n","import { SimulationNodeDatum, SimulationLinkDatum, Force } from \"d3-force\"\n\n// Type definitions\nexport interface AsymmetricLink<\n NodeDatum extends SimulationNodeDatum = SimulationNodeDatum,\n> extends SimulationLinkDatum<NodeDatum> {\n index?: number\n}\n\nexport interface AsymmetricLinkForce<\n NodeDatum extends SimulationNodeDatum,\n LinkDatum extends AsymmetricLink<NodeDatum> = AsymmetricLink<NodeDatum>,\n> extends Force<NodeDatum, LinkDatum> {\n links(): LinkDatum[]\n links(links: LinkDatum[]): this\n\n id(): (node: NodeDatum, i: number, nodes: NodeDatum[]) => string | number\n id(\n id: (node: NodeDatum, i: number, nodes: NodeDatum[]) => string | number\n ): this\n\n iterations(): number\n iterations(iterations: number): this\n\n strength(): (\n link: LinkDatum,\n i: number,\n links: LinkDatum[]\n ) => number | [number, number]\n strength(\n strength:\n | number\n | ((\n link: LinkDatum,\n i: number,\n links: LinkDatum[]\n ) => number | [number, number])\n ): this\n\n distance(): (link: LinkDatum, i: number, links: LinkDatum[]) => number\n distance(\n distance:\n | number\n | ((link: LinkDatum, i: number, links: LinkDatum[]) => number)\n ): this\n}\n\n// Helper functions\nfunction constant<T>(x: T): () => T {\n return function () {\n return x\n }\n}\n\nfunction jiggle(random: () => number): number {\n return (random() - 0.5) * 1e-6\n}\n\nfunction index<NodeDatum extends SimulationNodeDatum>(\n d: NodeDatum\n): string | number {\n return d.index!\n}\n\nfunction find<NodeDatum extends SimulationNodeDatum>(\n nodeById: Map<string | number, NodeDatum>,\n nodeId: string | number\n): NodeDatum {\n const node = nodeById.get(nodeId)\n if (!node) throw new Error(\"node not found: \" + nodeId)\n return node\n}\n\n// Main force function\nexport function asymmetricLinks<\n NodeDatum extends SimulationNodeDatum = SimulationNodeDatum,\n LinkDatum extends AsymmetricLink<NodeDatum> = AsymmetricLink<NodeDatum>,\n>(links?: LinkDatum[]): AsymmetricLinkForce<NodeDatum, LinkDatum> {\n let id: (node: NodeDatum, i: number, nodes: NodeDatum[]) => string | number =\n index\n let strength: (\n link: LinkDatum,\n i: number,\n links: LinkDatum[]\n ) => number | [number, number] = defaultStrength\n let strengths: (number | [number, number])[]\n let distance: (link: LinkDatum, i: number, links: LinkDatum[]) => number =\n constant(30)\n let distances: number[]\n let nodes: NodeDatum[] | undefined\n let count: number[]\n let bias: number[]\n let random: (() => number) | undefined\n let iterations = 1\n\n if (links == null) links = []\n\n function defaultStrength(link: LinkDatum): number {\n return (\n 1 /\n Math.min(\n count[(link.source as NodeDatum).index!],\n count[(link.target as NodeDatum).index!]\n )\n )\n }\n\n function force(alpha: number): void {\n for (let k = 0, n = links!.length; k < iterations; ++k) {\n for (let i = 0; i < n; ++i) {\n const link = links![i]\n const source = link.source as NodeDatum\n const target = link.target as NodeDatum\n\n let x =\n target.x! + target.vx! - source.x! - source.vx! || jiggle(random!)\n let y =\n target.y! + target.vy! - source.y! - source.vy! || jiggle(random!)\n let l = Math.sqrt(x * x + y * y)\n\n l = ((l - distances[i]) / l) * alpha\n x *= l\n y *= l\n\n const b = bias[i]\n const strengthValue = strengths[i]\n let s0: number, s1: number\n\n if (Array.isArray(strengthValue)) {\n ;[s0, s1] = strengthValue\n } else {\n s0 = s1 = strengthValue\n }\n\n target.vx! -= x * b * s0\n target.vy! -= y * b * s0\n source.vx! += x * (1 - b) * s1\n source.vy! += y * (1 - b) * s1\n }\n }\n }\n\n function initialize(): void {\n if (!nodes) return\n\n const n = nodes.length\n const m = links!.length\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes!), d]))\n\n count = new Array(n).fill(0)\n\n for (let i = 0; i < m; ++i) {\n const link = links![i]\n link.index = i\n\n if (typeof link.source !== \"object\") {\n link.source = find(nodeById, link.source)\n }\n if (typeof link.target !== \"object\") {\n link.target = find(nodeById, link.target)\n }\n\n count[(link.source as NodeDatum).index!]++\n count[(link.target as NodeDatum).index!]++\n }\n\n bias = new Array(m)\n for (let i = 0; i < m; ++i) {\n const link = links![i]\n const sourceCount = count[(link.source as NodeDatum).index!]\n const targetCount = count[(link.target as NodeDatum).index!]\n bias[i] = sourceCount / (sourceCount + targetCount)\n }\n\n strengths = new Array(m)\n initializeStrength()\n distances = new Array(m)\n initializeDistance()\n }\n\n function initializeStrength(): void {\n if (!nodes) return\n\n for (let i = 0, n = links!.length; i < n; ++i) {\n strengths[i] = strength(links![i], i, links!)\n }\n }\n\n function initializeDistance(): void {\n if (!nodes) return\n\n for (let i = 0, n = links!.length; i < n; ++i) {\n distances[i] = +distance(links![i], i, links!)\n }\n }\n\n force.initialize = function (\n _nodes: NodeDatum[],\n _random: () => number\n ): void {\n nodes = _nodes\n random = _random\n initialize()\n }\n\n force.links = function (_?: LinkDatum[]): any {\n return arguments.length ? ((links = _!), initialize(), force) : links\n }\n\n force.id = function (\n _?: (node: NodeDatum, i: number, nodes: NodeDatum[]) => string | number\n ): any {\n return arguments.length ? ((id = _!), force) : id\n }\n\n force.iterations = function (_?: number): any {\n return arguments.length ? ((iterations = +_!), force) : iterations\n }\n\n force.strength = function (\n _?:\n | number\n | ((\n link: LinkDatum,\n i: number,\n links: LinkDatum[]\n ) => number | [number, number])\n ): any {\n return arguments.length\n ? ((strength = typeof _ === \"function\" ? _ : constant(+_!)),\n initializeStrength(),\n force)\n : strength\n }\n\n force.distance = function (\n _?: number | ((link: LinkDatum, i: number, links: LinkDatum[]) => number)\n ): any {\n return arguments.length\n ? ((distance = typeof _ === \"function\" ? _ : constant(+_!)),\n initializeDistance(),\n force)\n : distance\n }\n\n return force as AsymmetricLinkForce<NodeDatum, LinkDatum>\n}\n","import { float2hex, xorshiftString } from \"@fxhash/utils\"\n\nexport function quickHash(data: string): string {\n return float2hex(xorshiftString(data))\n}\n","import {\n Simulation,\n forceSimulation,\n forceManyBody,\n forceCenter,\n forceRadial,\n forceCollide,\n} from \"d3-force\"\nimport {\n GraphData,\n NodeState,\n RawGraphData,\n RootNodeImageSources,\n SimLink,\n SimNode,\n ThemeMode,\n} from \"@/_types\"\nimport {\n hasOnlyLeafs,\n getChildren,\n getClusterSize,\n getNodeSubgraph,\n getNodeId,\n getParents,\n getNodeDepth,\n getAllParentsUntil,\n} from \"@/util/graph\"\nimport { GraphConfig } from \"@/_interfaces\"\nimport { DEFAULT_GRAPH_CONFIG, VOID_DETACH_ID } from \"@/provider\"\nimport { isSimNode } from \"@/util/types\"\nimport { loadHTMLImageElement } from \"@/util/img\"\nimport { TransformCanvas } from \"./TransformCanvas\"\nimport { circle, img, rect } from \"@/util/canvas\"\nimport { color, dim } from \"@/util/color\"\nimport { scaleLinear, scaleLog } from \"d3-scale\"\nimport { getPrunedData } from \"@/util/data\"\nimport { Transform, HighlightStyle, Point } from \"./_types\"\nimport { IOpenGraphSimulation, OpenGraphEventEmitter } from \"./_interfaces\"\nimport { distance, getAngle, getRadialPoint } from \"@/util/math\"\nimport { red } from \"@/util/highlights\"\nimport { asymmetricLinks } from \"./asymmetric-link\"\nimport { quickHash } from \"@/util/hash\"\n\nconst RADIAL_FORCES = false\n\n// TODO: potentially implement strategy to retrieve radius based\n// on number of nodes per depth\nconst INITIAL_RADIUS = 300\nconst INCREMENTAL = 200\nfunction getRadius(depth: number) {\n if (depth === 0) return INITIAL_RADIUS\n return INCREMENTAL * depth + INITIAL_RADIUS\n}\n\ninterface OpenGraphSimulationProps {\n width: number\n height: number\n config?: GraphConfig\n rootImageSources?: RootNodeImageSources\n canvas: HTMLCanvasElement\n theme?: ThemeMode\n loadNodeImage?: (node: SimNode) => Promise<string | undefined>\n translate?: { x: number; y: number }\n lockedNodeId?: string\n highlights?: HighlightStyle[]\n}\n\ninterface RenderLayer<T> {\n regular: T[]\n highlighted: T[]\n}\n\nexport class OpenGraphSimulation implements IOpenGraphSimulation {\n width: number\n height: number\n config: GraphConfig\n rootImageSources: RootNodeImageSources\n canvas: HTMLCanvasElement\n transformCanvas: TransformCanvas\n theme: ThemeMode\n\n private rawData?: RawGraphData\n\n public emitter: OpenGraphEventEmitter\n\n private translate: { x: number; y: number } = { x: 0, y: 0 }\n\n private data: GraphData = { nodes: [], links: [] }\n private prunedData: GraphData = { nodes: [], links: [] }\n private subGraph: GraphData = { nodes: [], links: [] }\n private rootId: string = \"\"\n private simulation: Simulation<SimNode, SimLink> | null = null\n private clusterSizeRange: [number, number] = [0, 1]\n private maxDepth: number = 0\n\n private isTicking: boolean = false\n private tickCount = 0\n\n private loadNodeImage?: (node: SimNode) => Promise<string | undefined>\n private imageCache: Map<string, HTMLImageElement> = new Map()\n private rootImages: HTMLImageElement[] = []\n private hideThumbnails: boolean = false\n private noInteraction: boolean = false\n\n public lockedNodeId?: string\n public selectedNode: SimNode | null = null\n public hoveredNode: SimNode | null = null\n\n public highlights: HighlightStyle[] = []\n\n private renderLayers: {\n links: RenderLayer<SimLink>\n nodes: RenderLayer<SimNode>\n } = {\n links: { regular: [], highlighted: [] },\n nodes: { regular: [], highlighted: [] },\n }\n\n constructor(props: OpenGraphSimulationProps) {\n this.emitter = new OpenGraphEventEmitter()\n\n this.theme = props.theme || \"light\"\n this.width = props.width\n this.height = props.height\n this.config = props.config || DEFAULT_GRAPH_CONFIG\n this.rootImageSources = props.rootImageSources || []\n this.canvas = props.canvas\n\n this.lockedNodeId = props.lockedNodeId\n\n this.loadNodeImage = props.loadNodeImage\n\n this.translate = props.translate || { x: 0, y: 0 }\n\n this.transformCanvas = new TransformCanvas(this.canvas, {\n onUpdate: this.handleTransform,\n onClick: this.handleClick,\n onMove: this.handleMove,\n })\n\n this.rootImageSources.forEach((src, idx) => {\n if (src && !this.imageCache.get(src)) {\n loadHTMLImageElement(src).then(img => {\n this.imageCache.set(src, img)\n this.rootImages[idx] = img\n })\n }\n })\n }\n\n private get center() {\n return {\n x: 0,\n y: 0,\n }\n }\n\n private get origin() {\n const dpi = devicePixelRatio || 1\n return {\n x: (this.translate.x + this.width / 2) * dpi,\n y: (this.translate.y + this.height / 2) * dpi,\n }\n }\n\n private getNodeAtPosition = (cx: number, cy: number): SimNode | null => {\n const transform = this.transformCanvas.getTransform()\n const { x: tx, y: ty, scale } = transform\n const dpi = devicePixelRatio || 1\n\n const canvasX = cx * dpi\n const canvasY = cy * dpi\n\n const scaledX = (canvasX - tx) / scale\n const scaledY = (canvasY - ty) / scale\n\n const graphX = scaledX - this.origin.x\n const graphY = scaledY - this.origin.y\n\n const candidates: SimNode[] = []\n\n for (let node of this.data.nodes) {\n const r = this.getNodeSize(node.id) / 2\n if (node.x == null || node.y == null) continue\n const dx = node.x - graphX\n const dy = node.y - graphY\n if (dx * dx + dy * dy < r * r) {\n // only consider nodes that are in the pruned data (visible)\n if (!this.prunedData.nodes.find(n => n.id === node.id)) continue\n candidates.push(node)\n }\n }\n\n if (candidates.length === 0) return null\n if (candidates.length === 1) return candidates[0]\n\n for (let i = this.renderLayers.nodes.highlighted.length - 1; i >= 0; i--) {\n const node = this.renderLayers.nodes.highlighted[i]\n if (candidates.find(c => c.id === node.id)) {\n return node\n }\n }\n\n for (let node of this.renderLayers.nodes.regular) {\n if (candidates.find(c => c.id === node.id)) {\n return node\n }\n }\n\n return candidates[0]\n }\n\n public getNodeScreenPosition = (node: SimNode): { x: number; y: number } => {\n const transform = this.transformCanvas.getTransform()\n const x = transform.x + (node.x || 0 + this.origin.x) * transform.scale\n const y = transform.y + (node.y || 0 + this.origin.y) * transform.scale\n return { x, y }\n }\n\n public getNodeCanvasPosition = (node: SimNode): { x: number; y: number } => {\n const _x = node.x || 0\n const _y = node.y || 0\n const transform = this.transformCanvas.getTransform()\n const x = this.origin.x - _x * transform.scale\n const y = this.origin.y - _y * transform.scale\n return { x, y }\n }\n\n public screenToWorld(_x: number, _y: number) {\n const transform = this.transformCanvas.getTransform()\n const { x: tx, y: ty, scale } = transform\n const dpi = devicePixelRatio || 1\n\n const canvasX = _x * dpi\n const canvasY = _y * dpi\n\n const scaledX = (canvasX - tx) / scale\n const scaledY = (canvasY - ty) / scale\n\n const x = scaledX - this.origin.x\n const y = scaledY - this.origin.y\n return { x, y }\n }\n\n public worldToScreen(worldX: number, worldY: number) {\n const transform = this.transformCanvas.getTransform()\n const { x: tx, y: ty, scale } = transform\n const dpi = devicePixelRatio || 1\n\n const scaledX = (worldX + this.origin.x) * scale\n const scaledY = (worldY + this.origin.y) * scale\n\n const canvasX = scaledX + tx\n const canvasY = scaledY + ty\n\n const screenX = canvasX / dpi\n const screenY = canvasY / dpi\n\n return { x: screenX, y: screenY }\n }\n\n handleClick = (x: number, y: number) => {\n let node = this.getNodeAtPosition(x, y)\n if (node?.state?.sessionNode) return\n // when we have lockedNodeId, we will always select that node\n // instead of deselection\n if (this.lockedNodeId && !node) {\n node = this.getNodeById(this.lockedNodeId)\n }\n this.handleClickNode(node)\n }\n\n handleClickNode = (\n node: SimNode | null,\n options: { noToggle?: boolean; triggerFocus?: boolean } = {\n noToggle: false,\n triggerFocus: false,\n }\n ) => {\n let wasOpened = false\n if (node) {\n if (node.id === this.rootId) {\n this.selectedNode = null\n this.emitter.emit(\"selected-node-changed\", null)\n this.subGraph = {\n nodes: [],\n links: [],\n }\n this.updateRenderLayers()\n this.updateScene()\n return\n }\n if (node.state) {\n const children = getChildren(node.id, this.data.links)\n if (children.length > 0 && !options?.noToggle) {\n if (this.selectedNode?.id !== node.id) {\n if (node.state.collapsed) {\n wasOpened = true\n }\n node.state.collapsed = false\n } else {\n node.state.collapsed = !node.state.collapsed\n }\n if (!node.state.collapsed) {\n // distance from parent to cluster center\n const clusterDistance = 100\n const clusterRadius = 50\n\n const parentX = node.x || this.center.x\n const parentY = node.y || this.center.y\n\n const dirX = parentX - this.center.x\n const dirY = parentY - this.center.y\n const length = Math.sqrt(dirX * dirX + dirY * dirY) || 1\n\n const normX = dirX / length\n const normY = dirY / length\n\n const clusterX = parentX + normX * clusterDistance\n const clusterY = parentY + normY * clusterDistance\n\n // we place the children in a circle around the cluster center\n // which is n units away from the parent\n children.forEach(childId => {\n const childNode = this.data.nodes.find(n => n.id === childId)\n if (childNode && isSimNode(childNode)) {\n const angle = Math.random() * 2 * Math.PI\n const radius = Math.random() * clusterRadius\n childNode.x = clusterX + Math.cos(angle) * radius\n childNode.y = clusterY + Math.sin(angle) * radius\n }\n })\n }\n }\n }\n // if the node is not collapsed, we need to expand its parents\n if (!node.state?.collapsed) {\n const parents = getParents(node.id, this.data.links)\n parents.forEach(parentId => {\n const parentNode = this.data.nodes.find(n => n.id === parentId)\n if (parentNode && isSimNode(parentNode) && parentNode.state) {\n parentNode.state.collapsed = false\n }\n })\n }\n this.subGraph = getNodeSubgraph(\n node.id,\n this.data.nodes,\n this.data.links,\n this.rootId\n )\n }\n if (this.selectedNode?.id !== node?.id) {\n this.selectedNode = node\n this.emitter.emit(\"selected-node-changed\", node)\n this.updateRenderLayers()\n }\n if (node) {\n this.restart(wasOpened ? 0.05 : 0)\n if (wasOpened || options?.triggerFocus) {\n this.transformCanvas.focusOn(() => {\n const t = this.transformCanvas.getTransform()\n const _node = this.getNodeById(node.id)\n return { x: _node?.x!, y: _node?.y!, scale: t.scale }\n })\n }\n } else if (!node && this.selectedNode) {\n // handle deselection\n this.selectedNode = null\n this.emitter.emit(\"selected-node-changed\", null)\n this.subGraph = {\n nodes: [],\n links: [],\n }\n this.updateRenderLayers()\n this.updateScene()\n }\n }\n\n updateScene = () => {\n if (this.isTicking) return\n this.onDraw()\n }\n\n handleMove = (x: number, y: number) => {\n const world = this.screenToWorld(x, y)\n // TODO: Implement custom find node?\n const node = this.simulation?.find(world.x, world.y, 10) || null\n if (node?.state?.sessionNode) return\n if (this.hoveredNode === node) return\n this.hoveredNode = node\n this.emitter.emit(\"hovered-node-changed\", node)\n this.canvas.style.cursor = node ? \"pointer\" : \"default\"\n this.updateScene()\n }\n\n handleTransform = (t: Transform) => {\n this.emitter.emit(\"transform-changed\", t)\n this.updateScene()\n }\n\n updateHighlights = () => {\n //this.transformCanvas.resetFocus()\n // for detached highlights we need to create the session nodes and\n // links accordingly\n const detachedHighlights = this.highlights.filter(h => h.isDetached)\n const validSessionIds = new Set<string>()\n let focusSessionNode: null | SimNode = null\n detachedHighlights.forEach(h => {\n const highlightedNode = this.data.nodes.find(n => n.id === h.id)\n if (!highlightedNode) return\n const existingLink = this.data.links.find(l => {\n return isSimNode(l.target) ? l.target.id === h.id : l.target === h.id\n })\n if (!existingLink) return\n const id = isSimNode(existingLink.source)\n ? existingLink.source.id\n : existingLink.source.toString()\n const parentNode = this.getNodeById(id)\n if (!parentNode) return\n // session id is either provided or is the parent node\n const _sessionId = h.sessionId || parentNode.id\n const sessionId = parentNode.state?.sessionNode\n ? parentNode.id\n : `${VOID_DETACH_ID}-${_sessionId}`\n validSessionIds.add(sessionId)\n let sessionNode = this.data.nodes.find(n => n.id === sessionId)\n if (!sessionNode) {\n const depth = (highlightedNode?.depth || 1) + 1\n const angle = getAngle(\n this.center.x,\n this.center.y,\n parentNode?.x!,\n parentNode?.y!\n )\n const circlePos = getRadialPoint(\n getRadius(depth),\n this.center.x,\n this.center.y,\n angle\n )\n sessionNode = {\n id: sessionId,\n state: { collapsed: false, image: undefined, sessionNode: true },\n depth,\n clusterSize: 1,\n x: circlePos.x,\n y: circlePos.y,\n }\n this.data.nodes.push(sessionNode)\n // connect the session node to the parent node\n this.data.links.push({ target: sessionNode, source: parentNode })\n }\n // remove the existing link from the parent to the highlighted node\n const existingLinkIndex = this.data.links.findIndex(\n l => l === existingLink\n )\n this.data.links.splice(existingLinkIndex, 1)\n // add the link between the session node and the highlighted node\n this.data.links.push({\n target: highlightedNode,\n source: sessionNode,\n })\n // TODO: maybe should be centralized,\n // initialize function also sets the collapsed state\n //\n // OPEN THE TREE\n // highlightedNodes and their parents should never be collapsed\n const parents = getAllParentsUntil(\n highlightedNode.id,\n this.data.links,\n this.rootId\n )\n parents.forEach(parentId => {\n const node = this.data.nodes.find(n => n.id === parentId)\n if (node?.state) {\n node.state.collapsed = false\n }\n })\n if (highlightedNode.state) {\n highlightedNode.state.collapsed = false\n }\n // We focus on the first session node we find\n if (!focusSessionNode) {\n focusSessionNode = sessionNode\n }\n })\n\n // we need to cleanup the session nodes if they are not part of\n // the highlights anymore\n const sessionNodesToRemove = this.data.nodes.filter(\n n => n.state?.sessionNode && !validSessionIds.has(n.id)\n )\n sessionNodesToRemove.forEach(sessionNode => {\n const childLinks = this.data.links.filter(\n l => isSimNode(l.source) && l.source.id === sessionNode.id\n )\n const incomingLink = this.data.links.find(\n l => isSimNode(l.target) && l.target.id === sessionNode.id\n )\n const parentNode = incomingLink\n ? isSimNode(incomingLink.source)\n ? incomingLink.source\n : this.getNodeById(incomingLink.source.toString())\n : null\n this.data.links = this.data.links.filter(\n l =>\n !(isSimNode(l.source) && l.source.id === sessionNode.id) &&\n !(isSimNode(l.target) && l.target.id === sessionNode.id)\n )\n if (parentNode) {\n childLinks.forEach(link => {\n const targetNode = isSimNode(link.target)\n ? link.target\n : this.getNodeById(link.target.toString())\n if (targetNode) {\n this.data.links.push({\n source: parentNode,\n target: targetNode,\n })\n }\n })\n }\n const index = this.data.nodes.findIndex(n => n.id === sessionNode.id)\n if (index !== -1) this.data.nodes.splice(index, 1)\n })\n\n // since we are modifing the graph, in case there is a selection we need\n // to recalculate the subgraph\n if (this.selectedNode) {\n this.subGraph = getNodeSubgraph(\n this.selectedNode.id,\n this.data.nodes,\n this.data.links,\n this.rootId\n )\n }\n this.restart()\n // when there is no selectio we focus on the first session node we found\n // TODO: We could calcluate a point between all session nodes to focus the\n // camera on\n if (focusSessionNode) {\n this.transformCanvas.focusOn(() => {\n if (!focusSessionNode) return null\n const t = this.transformCanvas.getTransform()\n const _node = this.getNodeById(focusSessionNode.id)\n if (!_node) return null\n return { x: _node?.x!, y: _node?.y!, scale: t.scale }\n })\n }\n }\n\n initialize = (data: RawGraphData, rootId: string) => {\n this.rawData = data\n this.rootId = rootId\n const _links = data.links.map(l => ({ ...l }))\n const _nodes = data.nodes\n .map(n => {\n const existingData = this.data.nodes.find(x => x.id === n.id)\n const parents = getParents(n.id, _links)\n const parentNode = this.data.nodes.find(p => p.id === parents[0])\n const clusterSize = getClusterSize(n.id, _links)\n const depth = getNodeDepth(n.id, _links)\n const circlePos = getRadialPoint(\n getRadius(depth),\n this.center.x,\n this.center.y\n )\n\n const x =\n depth > 0 ? null : existingData?.x || parentNode?.x || circlePos.x\n const y =\n depth > 0 ? null : existingData?.y || parentNode?.y || circlePos.y\n return {\n ...n,\n state: {\n // TODO: this should maybe be centralized since highlights\n // also influence this state\n collapsed:\n hasOnlyLeafs(n.id, _links) &&\n getChildren(n.id, _links).length > 1,\n ...existingData?.state,\n } as NodeState,\n clusterSize,\n depth,\n x,\n y,\n }\n })\n .sort((a, b) => a.depth - b.depth)\n // we make a second pass to position nodes based on their parents\n _nodes.forEach((n, i, arr) => {\n const existingData = _nodes.find(x => x.id === n.id)\n const parents = getParents(n.id, _links)\n const parentNode = _nodes.find(p => p.id === parents[0])\n const depth = n.depth\n const parentAngle =\n depth > 0\n ? getAngle(\n this.center.x,\n this.center.y,\n parentNode?.x!,\n parentNode?.y!\n )\n : undefined\n\n const circlePos = getRadialPoint(\n getRadius(depth),\n this.center.x,\n this.center.y,\n parentAngle\n )\n const x =\n depth > 0\n ? existingData?.x || circlePos.x\n : existingData?.x || circlePos.x\n const y =\n depth > 0\n ? existingData?.y || circlePos.y\n : existingData?.y || circlePos.y\n\n _nodes[i].x = x\n _nodes[i].y = y\n })\n\n // if rootId is not in the nodes, add it\n if (!data.nodes.find(n => n.id === this.rootId)) {\n _nodes.push({\n id: this.rootId,\n state: { collapsed: false, image: undefined },\n depth: -1,\n clusterSize: 1,\n x: this.center.x,\n y: this.center.y,\n })\n }\n\n // connect all nodes without a source in the links to the root node\n const targetIds = new Set(_links.map(link => link.target))\n const rootNodes = _nodes.filter(node => !targetIds.has(node.id))\n for (const node of rootNodes) {\n _links.push({\n source: this.rootId,\n target: node.id,\n })\n }\n\n this.maxDepth = Math.max(..._nodes.map(n => n.depth || 0))\n this.data = { nodes: _nodes as SimNode[], links: _links }\n this.loadNodeImages()\n // this.restart()\n this.updateHighlights()\n this.triggerSelected(true)\n }\n\n get lockedNode() {\n return this.lockedNodeId ? this.getNodeById(this.lockedNodeId) : null\n }\n\n triggerSelected = (triggerFocus: boolean = false) => {\n if (this.selectedNode) {\n this.handleClickNode(this.selectedNode, {\n noToggle: true,\n triggerFocus,\n })\n } else if (this.lockedNode) {\n this.handleClickNode(this.lockedNode, { noToggle: true, triggerFocus })\n } else {\n this.setSelectedNode(null)\n }\n }\n\n restart = (alpha: number = 0.1) => {\n this.tickCount = 0\n this.prunedData = getPrunedData(\n this.rootId,\n this.data.nodes,\n this.data.links,\n this.highlights\n )\n this.updateRenderLayers()\n this.clusterSizeRange = this.prunedData.nodes\n .filter(n => n.state?.collapsed)\n .reduce(\n (acc, node) => [\n Math.min(acc[0], node.clusterSize || 1),\n Math.max(acc[1], node.clusterSize || 1),\n ],\n [Infinity, -Infinity] as [number, number]\n )\n if (this.simulation) {\n this.simulation.stop()\n this.simulation.on(\"tick\", null)\n this.simulation.on(\"end\", null)\n }\n this.simulation = forceSimulation<SimNode, SimLink>(this.prunedData.nodes)\n .alpha(this.simulation ? alpha : 0.5)\n .force(\n \"collide\",\n forceCollide(n => this.getNodeSize(n.id) / 2)\n )\n .force(\n \"link\",\n asymmetricLinks<SimNode, SimLink>(this.prunedData.links)\n .id(d => d.id)\n .distance(l => {\n const size = this.getNodeSize(\n isSimNode(l.target) ? l.target.id : l.target.toString()\n )\n if (isSimNode(l.target)) {\n const state = l.target?.state\n if (!state?.collapsed) {\n return size\n }\n }\n\n return size * 3\n })\n .strength(l => {\n return [0.66, 0.08]\n })\n )\n .force(\n \"charge\",\n forceManyBody<SimNode>().strength(node => {\n return -150\n })\n )\n .force(\"center\", forceCenter(this.center.x, this.center.y).strength(0.1))\n .restart()\n\n if (RADIAL_FORCES) {\n for (let i = 0; i < this.maxDepth; i++) {\n const depth = i\n const r = getRadius(depth)\n const x = this.center.x\n const y = this.center.y\n console.log(\n \"Adding radial force for depth\",\n depth,\n \"with radius\",\n r,\n x,\n y\n )\n\n this.simulation.force(\n `radial-${depth}`,\n forceRadial<SimNode>(r, x, y).strength(n => {\n if (n.id === this.rootId) return 0\n if (n.depth === 0) return 0\n if (n.depth === depth) return 0.01\n return 0\n })\n )\n }\n }\n this.simulation.on(\"tick\", this.handleTick)\n this.simulation.on(\"end\", this.onEnd)\n }\n\n get rootNode() {\n return this.data.nodes.find(n => n.id === this.rootId) || null\n }\n\n handleTick = () => {\n this.isTicking = true\n this.onDraw()\n this.tickCount++\n }\n\n setTranslate({ x, y }: { x: number; y: number }) {\n this.translate = { x, y }\n this.transformCanvas.setOffset(this.translate)\n }\n\n get visiblityScale() {\n return scaleLog()\n .domain(this.clusterSizeRange)\n .range([1.5, 0.9])\n .clamp(true)\n }\n\n get color() {\n return color(\n this.theme === \"light\" ? this.config.theme.dark : this.config.theme.light\n )\n }\n get colorContrast() {\n return color(\n this.theme === \"light\" ? this.config.theme.light : this.config.theme.dark\n )\n }\n\n getNodeSize = (nodeId: string): number => {\n const { nodeSize } = this.config\n const highlight = this.highlights.find(h => h.id === nodeId)\n const sizeScale = highlight?.scale || 1\n if (nodeId === this.rootId) return nodeSize * 2 * sizeScale\n const node = this.data.nodes.find(n => n.id === nodeId)\n if (node?.state?.sessionNode) return 5\n const isCollapsed = !!node?.state?.collapsed\n if (isCollapsed) {\n const scale = scaleLinear()\n .domain(this.clusterSizeRange)\n .range([nodeSize, nodeSize * 3])\n return scale(node.clusterSize || 1)\n }\n const isSelected = this.selectedNode?.id === nodeId\n const isLiquidated =\n node?.status === \"LIQUIDATED\" || node?.status === \"REGENERATED\"\n const _size = isLiquidated ? nodeSize * 0.2 : nodeSize\n return isSelected ? _size * 4 : _size * sizeScale\n }\n\n private updateRenderLayers() {\n const isHighlighted = (id: string) => {\n const highlight = this.highlights.find(h => h.id === id)\n return (\n (!this.selectedNode && highlight?.onTop) ||\n this.selectedNode?.id === id ||\n this.subGraph.nodes.find(n => n.id === id)\n )\n }\n\n this.renderLayers.nodes.regular = []\n this.renderLayers.nodes.highlighted = []\n\n this.prunedData.nodes.forEach(node => {\n if (isHighlighted(node.id)) {\n this.renderLayers.nodes.highlighted.push(node)\n } else {\n this.renderLayers.nodes.regular.push(node)\n }\n })\n\n this.renderLayers.links.regular = []\n this.renderLayers.links.highlighted = []\n\n const isLinkInSubgraph = (link: SimLink) => {\n if (!this.selectedNode) return false\n const sourceId = isSimNode(link.source) ? link.source.id : link.source\n const targetId = isSimNode(link.target) ? link.target.id : link.target\n\n return this.subGraph.links.some(l => {\n const lSourceId = getNodeId(l.source)\n const lTargetId = getNodeId(l.target)\n return (\n (lSourceId === sourceId && lTargetId === targetId) ||\n (lSourceId === targetId && lTargetId === sourceId)\n )\n })\n }\n\n const isLinkInHighlights = (link: SimLink) => {\n const sourceId = isSimNode(link.source) ? link.source.id : link.source\n const targetId = isSimNode(link.target) ? link.target.id : link.target\n return (\n !this.selectedNode &&\n !!this.highlights.find(\n h => h.isDetached && (h.id === sourceId || h.id === targetId)\n )\n )\n }\n\n this.prunedData.links.forEach(link => {\n const inSubgraph = isLinkInSubgraph(link)\n const inHighlights = isLinkInHighlights(link)\n if (inSubgraph || inHighlights) {\n this.renderLayers.links.highlighted.push(link)\n } else {\n this.renderLayers.links.regular.push(link)\n }\n })\n this.renderLayers.links.highlighted.sort((a, b) => {\n const inSubgraphA = isLinkInSubgraph(a)\n const inSubgraphB = isLinkInSubgraph(b)\n if (inSubgraphA || inSubgraphB) return 2\n return -1\n })\n this.renderLayers.nodes.highlighted.sort((a, b) => {\n const highlightA = this.highlights.find(h => h.id === a.id)\n const highlightB = this.highlights.find(h => h.id === b.id)\n if (\n this.subGraph.nodes.find(n => n.id === a.id) ||\n this.subGraph.nodes.find(n => n.id === b.id)\n )\n return 2\n if (a.id === this.selectedNode?.id || b.id === this.selectedNode?.id)\n return 2\n if (highlightA?.onTop || highlightB?.onTop) return 1\n return -1\n })\n }\n\n private renderLink(\n ctx: CanvasRenderingContext2D,\n link: SimLink,\n options: {\n dim: boolean\n hasSelection: boolean\n highlight?: HighlightStyle\n }\n ) {\n const sourceId = isSimNode(link.source) ? link.source.id : link.source\n const targetId = isSimNode(link.target) ? link.target.id : link.target\n\n let sourceNode = this.data.nodes.find(n => n.id === sourceId)\n\n const isLight = this.theme === \"light\"\n const { dim: _dim, hasSelection, highlight } = options\n\n let stroke = _dim\n ? this.color(dim(0.09, isLight))()\n : hasSelection\n ? this.color(dim(0.4, isLight))()\n : this.color(dim(0.18, isLight))()\n\n ctx.globalAlpha = highlight ? 1 : 0.5\n\n const sx = (sourceNode && sourceNode.x) || 0\n const sy = (sourceNode && sourceNode.y) || 0\n const tx = (isSimNode(link.target) && link.target.x) || 0\n const ty = (isSimNode(link.target) && link.target.y) || 0\n\n if (highlight?.linkColor) {\n const gradient = ctx.createLinearGradient(sx, sy, tx, ty)\n gradient.addColorStop(0, stroke)\n gradient.addColorStop(1, color(highlight.linkColor)())\n ctx.strokeStyle = gradient\n } else {\n ctx.strokeStyle = stroke\n }\n\n ctx.lineWidth = _dim ? 0.3 : 0.8\n ctx.beginPath()\n ctx.moveTo(sx, sy)\n ctx.lineTo(tx, ty)\n ctx.stroke()\n ctx.closePath()\n }\n\n private renderNode(\n ctx: CanvasRenderingContext2D,\n node: SimNode,\n options: {\n dim: boolean\n transform: Transform\n }\n ) {\n const x = node.x || 0\n const y = node.y || 0\n const isSelected = this.selectedNode?.id === node.id\n const isHovered = this.hoveredNode?.id === node.id\n const isCollapsed = !!node.state?.collapsed\n const isLiquidated =\n node.status === \"LIQUIDATED\" || node.status === \"REGENERATED\"\n const isLight = this.theme === \"light\"\n const { dim: _dim, transform } = options\n\n const fill = _dim\n ? this.color(dim(0.075, isLight))()\n : isCollapsed\n ? this.color(dim(0.18, isLight))()\n : isHovered\n ? this.color(dim(0.4, isLight))()\n : this.color()\n\n const stroke = this.colorContrast()\n const nodeSize = this.getNodeSize(node.id)\n const highlight = this.highlights.find(h => h.id === node.id)\n const highlighted = !!highlight\n\n let highlightedStroke = _dim\n ? color(highlight?.strokeColor || red)(dim(0.4, isLight))()\n : color(highlight?.strokeColor || red)()\n\n if (node.id === this.rootId) {\n this.renderRootNode(ctx, x, y, nodeSize, _dim, isLight)\n } else if (node.state?.sessionNode) {\n this.renderSessionNode(ctx, x, y, nodeSize)\n } else if (isCollapsed) {\n this.renderCollapsedNode(ctx, x, y, nodeSize, {\n fill,\n stroke,\n highlighted,\n highlightedStroke,\n isSelected,\n dim: _dim,\n transform,\n clusterSize: node.clusterSize || 1,\n isLight,\n })\n } else {\n this.renderExpandedNode(ctx, x, y, nodeSize, {\n fill,\n stroke,\n highlighted,\n highlightedStroke,\n isHovered,\n isLiquidated,\n dim: _dim,\n image: node.state?.image,\n })\n }\n }\n\n private renderSessionNode(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n ) {\n const isLight = this.theme === \"light\"\n circle(ctx, x, y, size / 2, {\n stroke: true,\n strokeStyle: this.colorContrast(),\n lineWidth: 0.2,\n fill: true,\n fillStyle: this.color(dim(0.18, isLight))(),\n })\n }\n\n private renderRootNode(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n dimmed: boolean,\n isLight: boolean\n ) {\n circle(ctx, x, y, size / 2, {\n stroke: false,\n strokeStyle: this.colorContrast(),\n lineWidth: 0.2,\n fill: true,\n fillStyle: this.color(dim(0.18, isLight))(),\n })\n\n if (this.rootImages) {\n const _idx = Math.min(isLight ? 0 : 1, this.rootImages.length - 1)\n const _img = this.rootImages[_idx]\n const _imgSize = size * 0.55\n if (_img) {\n img(\n ctx,\n _img,\n x - _imgSize / 2,\n y - _imgSize / 2,\n _imgSize,\n _imgSize,\n 0,\n dimmed ? 0.1 : 1\n )\n }\n }\n }\n\n private renderCollapsedNode(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n options: {\n fill: string\n stroke: string\n highlighted: boolean\n highlightedStroke: string\n isSelected: boolean\n dim: boolean\n transform: Transform\n clusterSize: number\n isLight: boolean\n }\n ) {\n const {\n fill,\n stroke,\n highlighted,\n highlightedStroke,\n isSelected,\n dim: _dim,\n transform,\n clusterSize,\n isLight,\n } = options\n\n if (highlighted) {\n const _size = size + 4\n circle(ctx, x, y, _size / 2, {\n stroke: true,\n strokeStyle: highlightedStroke,\n lineWidth: 1,\n fill: false,\n fillStyle: fill,\n })\n }\n\n circle(ctx, x, y, size / 2, {\n stroke: true,\n strokeStyle: stroke,\n lineWidth: isSelected ? 1 : 0.2,\n fill: true,\n fillStyle: fill,\n })\n\n const showLabel =\n transform.scale >= this.visiblityScale(clusterSize) ? 1 : 0\n\n if (showLabel) {\n ctx.font = `${14 / transform.scale}px Sans-Serif`\n ctx.textAlign = \"center\"\n ctx.textBaseline = \"middle\"\n ctx.fillStyle = this.color(dim(_dim ? 0.2 : 0.5, isLight))()\n ctx.fillText(clusterSize.toString(), x, y)\n }\n }\n\n private renderExpandedNode(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n options: {\n fill: string\n stroke: string\n highlighted: boolean\n highlightedStroke: string\n isHovered: boolean\n isLiquidated: boolean\n dim: boolean\n image?: HTMLImageElement\n }\n ) {\n const {\n fill,\n highlighted,\n highlightedStroke,\n isHovered,\n isLiquidated,\n dim: _dim,\n image,\n } = options\n\n const _size = size + 1\n\n rect(ctx, x - _size / 2, y - _size / 2, _size, _size, {\n stroke: highlighted || isHovered,\n strokeStyle: isHovered ? fill : highlightedStroke,\n lineWidth: 0.5,\n fill: this.hideThumbnails || isLiquidated || !image,\n fillStyle: fill,\n borderRadius: 1,\n })\n\n if (image && !this.hideThumbnails && !isLiquidated) {\n img(\n ctx,\n image,\n x - size / 2,\n y - size / 2,\n size,\n size,\n 1,\n _dim ? 0.1 : 1,\n fill\n )\n }\n }\n\n onDraw = () => {\n const context = this.canvas?.getContext(\"2d\")\n const transform = this.transformCanvas.getTransform()\n if (!context) return\n\n const dpi = devicePixelRatio || 1\n context.save()\n context.scale(dpi, dpi)\n context.clearRect(0, 0, this.width, this.height)\n context.setTransform(\n transform.scale,\n 0,\n 0,\n transform.scale,\n transform.x,\n transform.y\n )\n context.translate(this.origin.x, this.origin.y)\n context.save()\n\n const hasSelection = !!this.selectedNode\n\n this.renderLayers.links.regular.forEach(link => {\n const sourceId = isSimNode(link.source) ? link.source.id : link.source\n const targetId = isSimNode(link.target) ? link.target.id : link.target\n\n const _dim =\n hasSelection &&\n !this.subGraph.links.find(\n sl =>\n getNodeId(sl.source) === sourceId &&\n getNodeId(sl.target) === targetId\n )\n\n this.renderLink(context, link, { dim: _dim, hasSelection })\n })\n\n context.globalAlpha = 1\n this.renderLayers.nodes.regular.forEach(node => {\n const _dim =\n hasSelection && !this.subGraph.nodes.some(n => n.id === node.id)\n this.renderNode(context, node, { dim: _dim, transform })\n })\n\n this.renderLayers.links.highlighted.forEach(link => {\n const sourceId = isSimNode(link.source) ? link.source.id : link.source\n const targetId = isSimNode(link.target) ? link.target.id : link.target\n\n const _dim =\n hasSelection &&\n !this.subGraph.links.find(\n sl =>\n getNodeId(sl.source) === sourceId &&\n getNodeId(sl.target) === targetId\n )\n\n const highlight = this.highlights.find(\n h => h.id === sourceId || h.id === targetId\n )\n\n this.renderLink(context, link, { dim: _dim, hasSelection, highlight })\n })\n\n context.globalAlpha = 1\n this.renderLayers.nodes.highlighted.forEach(node => {\n const _dim =\n hasSelection && !this.subGraph.nodes.some(n => n.id === node.id)\n this.renderNode(context, node, { dim: _dim, transform })\n })\n\n // this.drawDebugDepthCircles(context)\n\n context.restore()\n context.restore()\n // this.drawDebug(context)\n this.transformCanvas.trackCursor()\n }\n\n private drawDebug(context: CanvasRenderingContext2D) {\n const transform = this.transformCanvas.getTransform()\n context.font = `${14}px Sans-Serif`\n context.textAlign = \"left\"\n context.fillStyle = \"#000000\"\n context.fillText(\n `${transform.x}, ${transform.y}, ${transform.scale}`,\n 0,\n 15\n )\n const center = this.worldToScreen(this.rootNode?.x!, this.rootNode?.y!)\n context.fillText(`${center.x}, ${center.y}`, 0, 30)\n }\n\n private drawDebugDepthCircles(context: CanvasRenderingContext2D) {\n const transform = this.transformCanvas.getTransform()\n for (let i = 0; i < this.maxDepth; i++) {\n const depth = i\n const r = getRadius(depth)\n const x = this.center.x\n const y = this.center.y\n circle(context, x, y, r, {\n fill: false,\n stroke: true,\n strokeStyle: \"#00ff00\",\n })\n context.font = `${40 / transform.scale}px Sans-Serif`\n context.textAlign = \"center\"\n context.textBaseline = \"middle\"\n context.fillStyle = this.color()\n context.fillText(depth.toString(), x + r, y)\n }\n }\n\n private onEnd = () => {\n this.isTicking = false\n }\n\n private loadNodeImages = () => {\n this.data.nodes.forEach((node: any) => {\n // root node images are loaded separately\n if (node.id === this.rootId) return\n if (node.imgSrc && this.imageCache.get(node.imgSrc)) {\n node.state = node.state || {}\n node.state.image = this.imageCache.get(node.imgSrc)\n return\n }\n const loadImage = async () => {\n const src = this.loadNodeImage\n ? await this.loadNodeImage(node)\n : node.imgSrc\n if (!src) return\n const html =\n this.imageCache.get(src) || (await loadHTMLImageElement(src))\n this.imageCache.set(src, html)\n node.state = node.state || {}\n node.state.image = html\n }\n loadImage()\n })\n }\n\n destroy = () => {\n this.simulation?.stop()\n this.simulation?.on(\"tick\", null)\n this.simulation?.on(\"end\", null)\n this.transformCanvas.destroy()\n }\n\n resize = (width: number, height: number) => {\n this.width = width\n this.height = height\n this.updateScene()\n }\n\n setTheme = (theme: ThemeMode) => {\n this.theme = theme\n this.updateScene()\n }\n\n setHideThumbnails = (hide: boolean) => {\n this.hideThumbnails = hide\n this.updateScene()\n }\n\n setSelectedNode = (node: SimNode | null) => {\n this.selectedNode = node\n this.updateRenderLayers()\n this.updateScene()\n }\n\n private _highlightHash?: string\n\n setHighlights = (highlights: HighlightStyle[]) => {\n const hash = quickHash(JSON.stringify(highlights))\n if (hash === this._highlightHash) return\n this._highlightHash = hash\n this.highlights = highlights\n this.updateHighlights()\n // this.triggerSelected()\n }\n\n setNoInteraction = (noInteraction: boolean) => {\n this.noInteraction = noInteraction\n this.transformCanvas.setNoInteraction(this.noInteraction)\n this.updateScene()\n }\n\n getNodeById = (nodeId: string): SimNode | null => {\n return this.data.nodes.find(n => n.id === nodeId) || null\n }\n\n setLockedNodeId = (nodeId?: string | null) => {\n this.lockedNodeId = nodeId || undefined\n }\n\n // DEBUG\n handleClickDebug = (x: number, y: number) => {\n const p = this.screenToWorld(x, y)\n this.circles.push(p)\n // this.transformCanvas.transformToWorld(p.x, p.y)\n\n this.transformCanvas.focusOn(() => {\n const circle = this.circles[this.circles.length - 1]\n return {\n x: circle.x,\n y: circle.y,\n scale: this.transformCanvas.getTransform().scale,\n }\n })\n this.updateScene()\n }\n\n circles: Array<Point> = []\n\n onDrawDebug = () => {\n const context = this.canvas?.getContext(\"2d\")\n const transform = this.transformCanvas.getTransform()\n if (!context) return\n\n const dpi = devicePixelRatio || 1\n context.save()\n context.scale(dpi, dpi)\n context.clearRect(0, 0, this.width, this.height)\n context.setTransform(\n transform.scale,\n 0,\n 0,\n transform.scale,\n transform.x,\n transform.y\n )\n context.translate(this.origin.x, this.origin.y)\n context.save()\n\n this.circles.map(c => {\n circle(context, c.x, c.y, 5, {\n fill: true,\n fillStyle: \"#ff0000\",\n stroke: false,\n })\n })\n circle(context, 0, 0, 5, {\n fill: true,\n fillStyle: \"#ff0000\",\n stroke: false,\n })\n\n context.restore()\n context.restore()\n }\n}\n","import { SimNode } from \"@/_types\"\nimport { useOpenFormGraph } from \"@/provider\"\nimport { HighlightStyle, Transform } from \"@/sim/_types\"\nimport { OpenGraphSimulation } from \"@/sim/OpenGraphSimulation\"\nimport { MouseEventHandler, useEffect, useRef } from \"react\"\n\ninterface OpenFormGraphProps {\n width: number\n height: number\n highlights?: HighlightStyle[]\n className?: string\n noInteraction?: boolean\n onMouseEnter?: MouseEventHandler\n onMouseLeave?: MouseEventHandler\n loadNodeImage?: (node: SimNode) => Promise<string | undefined>\n translate?: { x: number; y: number }\n onTransform?: (transform: Transform) => void\n}\n\nexport function OpenFormGraph(props: OpenFormGraphProps) {\n const {\n width,\n height,\n highlights = [],\n className,\n noInteraction = false,\n loadNodeImage,\n translate,\n onTransform,\n } = props\n const {\n simulation,\n data,\n rootId,\n rootImageSources,\n theme,\n hideThumbnails,\n setHoveredNode,\n setSelectedNode,\n lockedNodeId,\n } = useOpenFormGraph()\n const canvasRef = useRef<HTMLCanvasElement | null>(null)\n\n useEffect(() => {\n if (!canvasRef.current) return\n simulation.current = new OpenGraphSimulation({\n width,\n height,\n canvas: canvasRef.current,\n rootImageSources,\n loadNodeImage,\n theme,\n translate,\n lockedNodeId,\n })\n simulation.current.emitter.on(\"selected-node-changed\", setSelectedNode)\n simulation.current.emitter.on(\"hovered-node-changed\", setHoveredNode)\n return () => {\n simulation.current?.emitter.off(\"selected-node-changed\", setSelectedNode)\n simulation.current?.emitter.off(\"hovered-node-changed\", setHoveredNode)\n simulation.current?.destroy()\n }\n }, [])\n\n useEffect(() => {\n if (!simulation.current) return\n if (!onTransform) return\n simulation.current.emitter.on(\"transform-changed\", onTransform)\n return () => {\n simulation.current?.emitter.off(\"transform-changed\", onTransform)\n }\n }, [onTransform])\n\n useEffect(() => {\n if (!simulation.current) return\n simulation.current.resize(width, height)\n }, [width, height])\n\n useEffect(() => {\n if (!simulation.current || !theme) return\n simulation.current.setTheme(theme)\n }, [theme])\n\n useEffect(() => {\n if (!simulation.current) return\n simulation.current.setHideThumbnails(hideThumbnails)\n }, [hideThumbnails])\n\n useEffect(() => {\n if (!simulation.current) return\n simulation.current.setHighlights(highlights)\n }, [highlights])\n\n useEffect(() => {\n if (!simulation.current) return\n simulation.current.setNoInteraction(noInteraction)\n }, [noInteraction])\n\n useEffect(() => {\n if (!simulation.current) return\n simulation.current.initialize(data, rootId)\n }, [data])\n\n useEffect(() => {\n if (!simulation.current) return\n if (!translate) return\n simulation.current.setTranslate(translate)\n }, [translate?.y, translate?.x])\n\n useEffect(() => {\n if (!simulation.current) return\n if (simulation.current.lockedNodeId === lockedNodeId) return\n simulation.current.setLockedNodeId(lockedNodeId)\n }, [translate?.y, translate?.x])\n\n const dpi = devicePixelRatio || 1\n\n return (\n <canvas\n onMouseEnter={props.onMouseEnter}\n onMouseLeave={props.onMouseLeave}\n ref={canvasRef}\n className={className}\n width={`${width * dpi}px`}\n height={`${height * dpi}px`}\n style={{\n width: `${width}px`,\n height: `${height}px`,\n }}\n />\n )\n}\n"],"mappings":"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"}
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import { SimulationLinkDatum, SimulationNodeDatum } from "d3-force";
|
2
|
+
|
3
|
+
//#region src/_types.d.ts
|
4
|
+
type RootNodeImageSources = [string?, string?];
|
5
|
+
type RawNode = {
|
6
|
+
id: string;
|
7
|
+
label?: string;
|
8
|
+
imgSrc?: string;
|
9
|
+
status?: string;
|
10
|
+
signed?: boolean;
|
11
|
+
};
|
12
|
+
type NestedRawNode<N extends RawNode> = {
|
13
|
+
children: NestedRawNode<N>[];
|
14
|
+
} & N;
|
15
|
+
type RawLink = {
|
16
|
+
source: string;
|
17
|
+
target: string;
|
18
|
+
};
|
19
|
+
type Link = {
|
20
|
+
source: Node;
|
21
|
+
target: Node;
|
22
|
+
};
|
23
|
+
type Node = {
|
24
|
+
collapsed: boolean;
|
25
|
+
hide: boolean;
|
26
|
+
clusterSize: number;
|
27
|
+
level?: number;
|
28
|
+
childLinks: Link[];
|
29
|
+
image?: HTMLImageElement;
|
30
|
+
} & RawNode;
|
31
|
+
type RawGraphData = {
|
32
|
+
nodes: RawNode[];
|
33
|
+
links: RawLink[];
|
34
|
+
};
|
35
|
+
type GraphData = {
|
36
|
+
nodes: SimNode[];
|
37
|
+
links: SimLink[];
|
38
|
+
};
|
39
|
+
type ThemeMode = "dark" | "light";
|
40
|
+
type RGB = [number, number, number];
|
41
|
+
type ColorTransform = (rgb: RGB) => RGB;
|
42
|
+
type NodeState = {
|
43
|
+
collapsed?: boolean;
|
44
|
+
image?: HTMLImageElement;
|
45
|
+
sessionNode?: boolean;
|
46
|
+
};
|
47
|
+
type SimNode = {
|
48
|
+
state?: NodeState;
|
49
|
+
clusterSize?: number;
|
50
|
+
depth?: number;
|
51
|
+
} & RawNode & SimulationNodeDatum;
|
52
|
+
type SimLink = {} & SimulationLinkDatum<SimNode>;
|
53
|
+
//#endregion
|
54
|
+
//#region src/sim/_types.d.ts
|
55
|
+
type Transform = {
|
56
|
+
x: number;
|
57
|
+
y: number;
|
58
|
+
scale: number;
|
59
|
+
};
|
60
|
+
type Point = {
|
61
|
+
x: number;
|
62
|
+
y: number;
|
63
|
+
};
|
64
|
+
type TransformListener = (t: Transform) => void;
|
65
|
+
type MouseListener = (x: number, y: number) => void;
|
66
|
+
type Focus = () => Transform | null;
|
67
|
+
type SimpleHighlight = string;
|
68
|
+
type CustomHighlight = {
|
69
|
+
id: string;
|
70
|
+
linkFrom?: string;
|
71
|
+
linkTo?: string;
|
72
|
+
strokeColor?: RGB;
|
73
|
+
linkColor?: RGB;
|
74
|
+
scale?: number;
|
75
|
+
isDetached?: boolean;
|
76
|
+
sessionId?: string;
|
77
|
+
onTop?: boolean;
|
78
|
+
};
|
79
|
+
type HighlightStyle = CustomHighlight;
|
80
|
+
//#endregion
|
81
|
+
export { ColorTransform, CustomHighlight, Focus, GraphData, HighlightStyle, Link, MouseListener, NestedRawNode, Node, NodeState, Point, RGB, RawGraphData, RawLink, RawNode, RootNodeImageSources, SimLink, SimNode, SimpleHighlight, ThemeMode, Transform, TransformListener };
|
82
|
+
//# sourceMappingURL=_types-CjgCTzqc.d.ts.map
|