@fxhash/open-form-graph 0.0.1 → 0.0.2
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-0EqYrhjv.d.ts +17 -0
- package/dist/OpenFormGraph-wo_Y20C6.js +1277 -0
- package/dist/OpenFormGraph-wo_Y20C6.js.map +1 -0
- package/dist/components.d.ts +2 -0
- package/dist/components.js +4 -0
- package/dist/constants-DU_wYtaU.d.ts +242 -0
- package/dist/index.d.ts +111 -133
- package/dist/index.js +3 -2098
- package/dist/provider-CTDz6ZQd.js +103 -0
- package/dist/provider-CTDz6ZQd.js.map +1 -0
- package/dist/provider.d.ts +2 -0
- package/dist/provider.js +3 -0
- package/package.json +14 -7
- package/dist/index.js.map +0 -1
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"OpenFormGraph-wo_Y20C6.js","names":["node: SimNode | string | number","link: SimLink","n: any","id: string","links: SimLink[]","links: RawLink[]","nodeId: string","nodes: SimNode[]","rootId: string","src: string","img","canvas: HTMLCanvasElement","options?: {\n onUpdate?: TransformListener\n onClick?: MouseListener\n onMove?: MouseListener\n }","a: number","b: number","t: number","next: Transform","e: WheelEvent","rect","e: MouseEvent","e: TouchEvent","update: Partial<Transform>","noInteraction: boolean","focus: Focus | null","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[]","label: string","startId: string","nodes: SimNode[]","links: SimLink[]","rootHashes: string[]","hash: string","nestedChildren: NestedRawNode<RawNode>[]","result: NestedRawNode<RawNode>[]","node: NestedRawNode<RawNode>","nodeHash: string","props: OpenGraphSimulationProps","img","cx: number","cy: number","node: SimNode","x: number","y: number","node: SimNode | null","nodePos","data: RawGraphData","rootId: string","nodeId: string","node: any","width: number","height: number","theme: ThemeMode","hide: boolean","highlights: string[]","noInteraction: boolean","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/OpenGraphSimulation.ts","../src/components/OpenFormGraph.tsx"],"sourcesContent":["import { SimNode, SimLink } from \"@/_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","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 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 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 loadImage(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","const MIN_ZOOM = 0.1\nconst MAX_ZOOM = 10\nconst CLICK_THRESHOLD = 5\n\ntype Transform = { x: number; y: number; scale: number }\ntype Point = { x: number; y: number }\ntype TransformListener = (t: Transform) => void\ntype MouseListener = (x: number, y: number) => void\n\ntype Focus = () => Transform\n\nexport class TransformCanvas {\n canvas: HTMLCanvasElement\n transform: Transform = { x: 0, y: 0, scale: 1 }\n targetTransform: Transform = { x: 0, y: 0, scale: 1 }\n isAnimating = false\n animationFrame: number | null = null\n\n isDragging = false\n dragStart: Point | null = null\n moved = false\n lastMousePos: Point = { x: 0, y: 0 }\n lastMoveMousePos: Point = { x: 0, y: 0 }\n zoomFocus: Point = { x: 0, y: 0 }\n\n onUpdate?: TransformListener\n onClick?: MouseListener\n onMove?: MouseListener\n\n noInteraction: boolean = false\n\n touchStart: Point | null = null\n lastTouchPos: Point = { x: 0, y: 0 }\n pinchStartDist: number | null = null\n pinchStartScale: number = 1\n\n focus: Focus | null = null\n\n constructor(\n canvas: HTMLCanvasElement,\n options?: {\n onUpdate?: TransformListener\n onClick?: MouseListener\n onMove?: MouseListener\n }\n ) {\n this.canvas = canvas\n this.onUpdate = options?.onUpdate\n this.onClick = options?.onClick\n this.onMove = options?.onMove\n\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.handleMouseUpCanvas = this.handleMouseUpCanvas.bind(this)\n\n // Attach events\n canvas.addEventListener(\"wheel\", this.handleWheel, { passive: false })\n canvas.addEventListener(\"mousedown\", this.handleMouseDown)\n window.addEventListener(\"mousemove\", this.handleMouseMove)\n window.addEventListener(\"mouseup\", this.handleMouseUp)\n canvas.addEventListener(\"mouseup\", this.handleMouseUpCanvas)\n\n this.handleTouchStart = this.handleTouchStart.bind(this)\n this.handleTouchMove = this.handleTouchMove.bind(this)\n this.handleTouchEnd = this.handleTouchEnd.bind(this)\n\n canvas.addEventListener(\"touchstart\", this.handleTouchStart, {\n passive: false,\n })\n canvas.addEventListener(\"touchmove\", this.handleTouchMove, {\n passive: false,\n })\n canvas.addEventListener(\"touchend\", this.handleTouchEnd, { passive: false })\n canvas.addEventListener(\"touchcancel\", this.handleTouchEnd, {\n passive: false,\n })\n }\n\n lerp(a: number, b: number, t: number) {\n return a + (b - a) * t\n }\n\n animateTransform = () => {\n const speed = 0.05\n const prev = this.transform\n const target = this.focus?.() || this.targetTransform\n\n const next: Transform = {\n x: this.lerp(prev.x, target.x, speed),\n y: this.lerp(prev.y, target.y, speed),\n scale: this.lerp(prev.scale, target.scale, speed),\n }\n\n const done =\n Math.abs(next.x - target.x) < 0.5 &&\n Math.abs(next.y - target.y) < 0.5 &&\n Math.abs(next.scale - target.scale) < 0.001\n\n if (done) {\n this.transform = { ...target }\n this.isAnimating = false\n this.focus = null\n } else {\n this.transform = next\n this.isAnimating = true\n }\n\n this.onUpdate?.(this.transform)\n\n if (this.isAnimating) {\n this.animationFrame = requestAnimationFrame(this.animateTransform)\n } else {\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame)\n this.animationFrame = null\n }\n }\n }\n\n handleWheel(e: WheelEvent) {\n if (this.noInteraction) return\n if (this.isAnimating) {\n this.isAnimating = false\n this.focus = null\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame)\n this.animationFrame = null\n }\n }\n e.preventDefault()\n const rect = this.canvas.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n this.zoomFocus = { x: mouseX, y: mouseY }\n\n const scaleFactor = e.deltaY > 0 ? 0.95 : 1.05\n const newScale = Math.max(\n MIN_ZOOM,\n Math.min(MAX_ZOOM, this.targetTransform.scale * scaleFactor)\n )\n\n const { x, y, scale } = this.transform\n const dx = mouseX - x\n const dy = mouseY - y\n const scaleChange = newScale / scale\n\n const newX = mouseX - dx * scaleChange\n const newY = mouseY - dy * scaleChange\n\n this.targetTransform = { x: newX, y: newY, scale: newScale }\n\n if (!this.isAnimating) {\n this.isAnimating = true\n this.animationFrame = requestAnimationFrame(this.animateTransform)\n }\n }\n\n handleMouseDown(e: MouseEvent) {\n if (this.noInteraction) return\n if (this.isAnimating) {\n this.isAnimating = false\n this.focus = null\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame)\n this.animationFrame = null\n }\n }\n this.isDragging = true\n this.moved = false\n this.dragStart = { x: e.clientX, y: e.clientY }\n this.lastMousePos = { x: e.clientX, y: e.clientY }\n }\n\n handleMouseMove(e: MouseEvent) {\n if (this.noInteraction) return\n const rect = this.canvas.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n this.lastMoveMousePos = { x: e.clientX, y: e.clientY }\n this.onMove?.(x, 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.moved = true\n\n const deltaX = e.clientX - this.lastMousePos.x\n const deltaY = e.clientY - this.lastMousePos.y\n\n this.transform.x += deltaX\n this.transform.y += deltaY\n this.targetTransform.x += deltaX\n this.targetTransform.y += deltaY\n\n this.lastMousePos = { x: e.clientX, y: e.clientY }\n\n this.onUpdate?.(this.transform)\n }\n }\n\n handleMouseUpCanvas(e: MouseEvent) {\n if (this.noInteraction) return\n if (!this.moved && this.onClick) {\n const rect = this.canvas.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n this.onClick(x, y)\n }\n }\n\n handleMouseUp(e: MouseEvent) {\n this.isDragging = false\n this.dragStart = null\n this.moved = false\n }\n\n handleTouchStart(e: TouchEvent) {\n if (this.noInteraction) return\n if (this.isAnimating) {\n this.isAnimating = false\n this.focus = null\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame)\n this.animationFrame = null\n }\n }\n if (e.touches.length === 1) {\n const rect = this.canvas.getBoundingClientRect()\n const touch = e.touches[0]\n this.isDragging = true\n this.moved = false\n this.touchStart = { x: touch.clientX, y: touch.clientY }\n this.lastTouchPos = { x: touch.clientX, y: touch.clientY }\n this.lastMoveMousePos = { x: touch.clientX, y: touch.clientY }\n } else if (e.touches.length === 2) {\n this.isDragging = false\n const [t1, t2] = [e.touches[0], e.touches[1]]\n this.pinchStartDist = Math.hypot(\n t2.clientX - t1.clientX,\n t2.clientY - t1.clientY\n )\n this.pinchStartScale = this.targetTransform.scale\n const rect = this.canvas.getBoundingClientRect()\n this.zoomFocus = {\n x: (t1.clientX + t2.clientX) / 2 - rect.left,\n y: (t1.clientY + t2.clientY) / 2 - rect.top,\n }\n }\n }\n\n handleTouchMove(e: TouchEvent) {\n if (this.noInteraction) return\n e.preventDefault()\n const rect = this.canvas.getBoundingClientRect()\n if (e.touches.length === 1 && 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.moved = true\n\n const deltaX = touch.clientX - this.lastTouchPos.x\n const deltaY = touch.clientY - this.lastTouchPos.y\n\n this.transform.x += deltaX\n this.transform.y += deltaY\n this.targetTransform.x += deltaX\n this.targetTransform.y += deltaY\n\n this.lastTouchPos = { x: touch.clientX, y: touch.clientY }\n this.lastMoveMousePos = { x: touch.clientX, y: touch.clientY }\n this.onUpdate?.(this.transform)\n this.onMove?.(touch.clientX - rect.left, touch.clientY - rect.top)\n }\n } else if (e.touches.length === 2 && this.pinchStartDist != null) {\n const [t1, t2] = [e.touches[0], e.touches[1]]\n const dist = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY)\n let scale = (dist / this.pinchStartDist) * this.pinchStartScale\n scale = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, scale))\n\n const { x, y, scale: prevScale } = this.transform\n const dx = this.zoomFocus.x - x\n const dy = this.zoomFocus.y - y\n const scaleChange = scale / prevScale\n const newX = this.zoomFocus.x - dx * scaleChange\n const newY = this.zoomFocus.y - dy * scaleChange\n\n this.targetTransform = { x: newX, y: newY, scale }\n if (!this.isAnimating) {\n this.isAnimating = true\n this.animationFrame = requestAnimationFrame(this.animateTransform)\n }\n }\n }\n\n handleTouchEnd(e: TouchEvent) {\n if (this.noInteraction) return\n if (e.touches.length === 0) {\n if (this.isDragging && !this.moved && this.onClick && this.touchStart) {\n const rect = this.canvas.getBoundingClientRect()\n this.onClick(\n this.touchStart.x - rect.left,\n this.touchStart.y - rect.top\n )\n }\n this.isDragging = false\n this.touchStart = null\n this.moved = false\n this.pinchStartDist = null\n } else if (e.touches.length === 1) {\n const touch = e.touches[0]\n this.isDragging = true\n this.touchStart = { x: touch.clientX, y: touch.clientY }\n this.lastTouchPos = { x: touch.clientX, y: touch.clientY }\n this.pinchStartDist = null\n }\n }\n\n resetZoom() {\n this.transform = { x: 0, y: 0, scale: 1 }\n this.targetTransform = { x: 0, y: 0, scale: 1 }\n this.onUpdate?.(this.transform)\n }\n\n transformTo(update: Partial<Transform>) {\n this.targetTransform = { ...this.transform, ...update }\n if (!this.isAnimating) {\n this.isAnimating = true\n this.animationFrame = requestAnimationFrame(this.animateTransform)\n }\n }\n\n trackCursor() {\n const rect = this.canvas.getBoundingClientRect()\n const x = this.lastMoveMousePos.x - rect.left\n const y = this.lastMoveMousePos.y - rect.top\n this.onMove?.(x, y)\n }\n\n destroy() {\n this.canvas.removeEventListener(\"wheel\", this.handleWheel)\n this.canvas.removeEventListener(\"mousedown\", this.handleMouseDown)\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 this.canvas.removeEventListener(\"mouseup\", this.handleMouseUpCanvas)\n window.removeEventListener(\"mousemove\", this.handleMouseMove)\n window.removeEventListener(\"mouseup\", this.handleMouseUp)\n this.isAnimating = false\n this.focus = null\n if (this.animationFrame) {\n cancelAnimationFrame(this.animationFrame)\n this.animationFrame = null\n }\n }\n\n setNoInteraction = (noInteraction: boolean) => {\n this.noInteraction = noInteraction\n }\n\n focusOn = (focus: Focus | null) => {\n this.focus = focus\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 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) {\n ctx.save()\n ctx.fillStyle = bgColor\n ctx.globalAlpha = 1.0\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\"\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) {\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 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 visibleLinks.push(...childLinks)\n\n childLinks\n .map(link => link.target)\n .forEach(n => traverseTree(isSimNode(n) ? n : nodesById[n.toString()]))\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 {\n Simulation,\n forceSimulation,\n forceLink,\n forceManyBody,\n forceCenter,\n} from \"d3-force\"\nimport {\n GraphData,\n NodeState,\n RawGraphData,\n RGB,\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} from \"@/util/graph\"\nimport { GraphConfig } from \"@/_interfaces\"\nimport { DEFAULT_GRAPH_CONFIG } from \"@/provider\"\nimport { isSimNode } from \"@/util/types\"\nimport { loadImage } 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\"\n\ninterface OpenGraphSimulationProps {\n width: number\n height: number\n config?: GraphConfig\n rootImageSources?: RootNodeImageSources\n canvas: HTMLCanvasElement\n theme?: ThemeMode\n onHoveredNodeChange?: (node: SimNode | null) => void\n onSelectedNodeChange?: (node: SimNode | null) => void\n}\n\nexport class OpenGraphSimulation {\n width: number\n height: number\n config: GraphConfig\n rootImageSources: RootNodeImageSources\n canvas: HTMLCanvasElement\n transformCanvas: TransformCanvas\n theme: ThemeMode\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\n private imageCache: Map<string, HTMLImageElement> = new Map()\n private rootImages: HTMLImageElement[] = []\n private hideThumbnails: boolean = false\n private noInteraction: boolean = false\n\n private selectedNode: SimNode | null = null\n onSelectedNodeChange?: (node: SimNode | null) => void\n private hoveredNode: SimNode | null = null\n onHoveredNodeChange?: (node: SimNode | null) => void\n\n private highlights: string[] = []\n\n constructor(props: OpenGraphSimulationProps) {\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.onHoveredNodeChange = props.onHoveredNodeChange\n this.onSelectedNodeChange = props.onSelectedNodeChange\n\n this.transformCanvas = new TransformCanvas(this.canvas, {\n onUpdate: this.onDraw,\n onClick: this.handleClick,\n onMove: this.handleMove,\n })\n\n this.rootImageSources.forEach((src, idx) => {\n if (src && !this.imageCache.get(src)) {\n loadImage(src).then(img => {\n this.imageCache.set(src, img)\n this.rootImages[idx] = img\n })\n }\n })\n }\n\n private getNodeAtPosition = (cx: number, cy: number): SimNode | null => {\n const transform = this.transformCanvas.transform\n const { x: tx, y: ty, scale } = transform\n const x = (cx - tx) / scale\n const y = (cy - ty) / scale\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 - x\n const dy = node.y - y\n if (dx * dx + dy * dy < r * r) {\n return node\n }\n }\n return null\n }\n\n private getNodeScreenPosition = (node: SimNode): { x: number; y: number } => {\n const _x = node.x || 0\n const _y = node.y || 0\n const transform = this.transformCanvas.transform\n const x = this.width / 2 - _x * transform.scale\n const y = this.height / 2 - _y * transform.scale\n return { x, y }\n }\n\n handleClick = (x: number, y: number) => {\n const node = this.getNodeAtPosition(x, y)\n this.handleClickNode(node)\n }\n\n handleClickNode = (node: SimNode | null) => {\n if (node) {\n if (node.id === this.rootId) {\n this.selectedNode = null\n this.onSelectedNodeChange?.(null)\n this.subGraph = {\n nodes: [],\n links: [],\n }\n return\n }\n if (node.state) {\n const children = getChildren(node.id, this.data.links)\n if (children.length > 0) {\n if (this.selectedNode?.id !== node.id) {\n node.state.collapsed = false\n } else {\n node.state.collapsed = !node.state.collapsed\n }\n if (!node.state.collapsed) {\n children.forEach(childId => {\n const childNode = this.data.nodes.find(n => n.id === childId)\n if (childNode && isSimNode(childNode)) {\n if (!childNode.x || childNode.x === 0)\n childNode.x =\n (node.x || this.width / 2) + Math.random() * 50 - 5\n if (!childNode.y || childNode.y === 0)\n childNode.y =\n (node.y || this.height / 2) + Math.random() * 50 - 5\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.restart()\n this.subGraph = getNodeSubgraph(\n node.id,\n this.data.nodes,\n this.data.links,\n this.rootId\n )\n const nodePos = this.getNodeScreenPosition(node)\n this.transformCanvas.transformTo({ x: nodePos.x, y: nodePos.y })\n this.transformCanvas.focusOn(() => {\n const nodePos = this.getNodeScreenPosition(node)\n return {\n x: nodePos.x,\n y: nodePos.y,\n scale: this.transformCanvas.transform.scale,\n }\n })\n }\n if (this.selectedNode?.id !== node?.id) {\n this.selectedNode = node\n this.onSelectedNodeChange?.(node)\n }\n }\n\n handleMove = (x: number, y: number) => {\n const node = this.getNodeAtPosition(x, y)\n if (this.hoveredNode === node) return\n this.hoveredNode = node\n this.onHoveredNodeChange?.(node)\n this.canvas.style.cursor = node ? \"pointer\" : \"default\"\n this.onDraw()\n }\n\n initialize = (data: RawGraphData, rootId: string) => {\n this.rootId = rootId\n const _links = data.links.map(l => ({ ...l }))\n const _nodes = data.nodes.map(n => {\n const existingData = this.data.nodes.find(x => x.id === n.id)\n return {\n ...n,\n state: {\n collapsed:\n hasOnlyLeafs(n.id, _links) && getChildren(n.id, _links).length > 1,\n } as NodeState,\n clusterSize: getClusterSize(n.id, _links),\n // set x and y to random values around the center\n x: existingData?.x || this.width / 2 + Math.random() * 200 - 5,\n y: existingData?.y || this.height / 2 + Math.random() * 200 - 5,\n }\n })\n\n // if rootId is not in the nodes, add it\n if (!data.nodes.find(n => n.id === rootId)) {\n _nodes.push({\n id: this.rootId,\n state: { collapsed: false, image: undefined },\n clusterSize: 1,\n x: this.width / 2,\n y: this.height / 2,\n })\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: rootId,\n target: node.id,\n })\n }\n }\n this.data = { nodes: _nodes, links: _links }\n this.loadNodeImages()\n this.restart()\n }\n\n restart = () => {\n this.setSelectedNode(null)\n this.prunedData = getPrunedData(\n this.rootId,\n this.data.nodes,\n this.data.links\n )\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 this.simulation = forceSimulation<SimNode, SimLink>(this.prunedData.nodes)\n .force(\n \"link\",\n forceLink<SimNode, SimLink>(this.prunedData.links)\n .id(d => d.id)\n .distance(l => {\n if (isSimNode(l.target) && !l.target?.state?.collapsed)\n return this.config.nodeSize\n return this.config.nodeSize * 3\n })\n .strength(l => {\n return 0.6\n /* const num = Math.min(\n this.prunedData.links.filter(x => x.source.id === l.source.id)\n .length,\n this.prunedData.links.filter(x => x.source.id === l.target.id)\n .length\n )\n return 1 / Math.max(num * 0.3, 1)*/\n })\n )\n .force(\n \"charge\",\n forceManyBody().strength(() => {\n return -130\n })\n )\n .force(\n \"center\",\n forceCenter(this.width / 2, this.height / 2).strength(0.01)\n )\n this.simulation.on(\"tick\", this.onDraw)\n this.simulation.on(\"end\", this.onEnd)\n }\n\n get visiblityScale() {\n return scaleLog().domain(this.clusterSizeRange).range([3, 1.5]).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 if (nodeId === this.rootId) return nodeSize * 2\n const node = this.data.nodes.find(n => n.id === nodeId)\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 return isSelected ? nodeSize * 2 : nodeSize\n }\n\n onDraw = () => {\n const context = this.canvas?.getContext(\"2d\")\n const transform = this.transformCanvas.transform\n if (!context) return\n const dpi = devicePixelRatio || 1\n context.save()\n context.scale(dpi, dpi)\n context.clearRect(0, 0, this.width, this.height)\n context.translate(transform.x, transform.y)\n context.scale(transform.scale, transform.scale)\n context.save()\n\n const isLight = this.theme === \"light\"\n this.prunedData.links.forEach(l => {\n const _dim =\n !!this.selectedNode &&\n !this.subGraph.links.find(\n sl =>\n getNodeId(sl.source) === getNodeId(l.source) &&\n getNodeId(sl.target) === getNodeId(l.target)\n )\n\n const stroke = _dim\n ? this.color(dim(0.09, isLight))()\n : this.color(dim(0.18, isLight))()\n context.globalAlpha = 0.5\n context.strokeStyle = stroke\n context.lineWidth = _dim ? 0.3 : 0.8\n context.beginPath()\n const sx = (isSimNode(l.source) && l.source.x) || 0\n const sy = (isSimNode(l.source) && l.source.y) || 0\n context.moveTo(sx, sy)\n const tx = (isSimNode(l.target) && l.target.x) || 0\n const ty = (isSimNode(l.target) && l.target.y) || 0\n context.lineTo(tx, ty)\n context.stroke()\n context.closePath()\n })\n\n context.globalAlpha = 1\n this.prunedData.nodes.forEach(node => {\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 _dim =\n !!this.selectedNode && !this.subGraph?.nodes.some(n => n.id === node.id)\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 const stroke = this.colorContrast()\n const blue = [94, 112, 235] as RGB\n const red = [238, 125, 121] as RGB\n const highlightedStroke = _dim\n ? color(red)(dim(0.4, isLight))()\n : color(red)()\n const size = this.getNodeSize(node.id)\n const highlighted = this.highlights.includes(node.id)\n if (node.id === this.rootId) {\n circle(context, x, y, size / 2, {\n stroke: false,\n strokeStyle: stroke,\n lineWidth: isSelected ? 1 : 0.2,\n fill: true,\n fillStyle: this.color(dim(0.18, isLight))(),\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 context,\n _img,\n x - _imgSize / 2,\n y - _imgSize / 2,\n _imgSize,\n _imgSize,\n 0,\n _dim ? 0.1 : 1\n )\n }\n }\n } else {\n if (isCollapsed) {\n if (highlighted) {\n const _size = size + 4\n circle(context, x, y, _size / 2, {\n stroke: true,\n strokeStyle: highlightedStroke,\n lineWidth: 1,\n fill: false,\n fillStyle: fill,\n })\n }\n circle(context, x, y, size / 2, {\n stroke: true,\n strokeStyle: stroke,\n lineWidth: isSelected ? 1 : 0.2,\n fill: true,\n fillStyle: fill,\n })\n const showLabel =\n transform.scale >= this.visiblityScale(node.clusterSize || 1)\n ? 1\n : 0\n\n if (showLabel) {\n context.font = `${14 / transform.scale}px Sans-Serif`\n context.textAlign = \"center\"\n context.textBaseline = \"middle\"\n context.fillStyle = this.color(dim(_dim ? 0.2 : 0.5, isLight))()\n context.fillText((node.clusterSize || 1).toString(), x, y)\n }\n } else {\n if (highlighted) {\n const _size = size + 4\n rect(context, x - _size / 2, y - _size / 2, _size, _size, {\n stroke: true,\n strokeStyle: highlightedStroke,\n lineWidth: 1,\n fill: false,\n fillStyle: fill,\n borderRadius: 1,\n })\n }\n rect(context, x - size / 2, y - size / 2, size, size, {\n stroke: true,\n strokeStyle: stroke,\n lineWidth: isSelected ? 0.3 : 0.2,\n fill: true,\n fillStyle: fill,\n borderRadius: 1,\n })\n if (node.state?.image && !this.hideThumbnails) {\n const _size = size - 1\n img(\n context,\n node.state?.image,\n x - _size / 2,\n y - _size / 2,\n _size,\n _size,\n 1,\n _dim ? 0.1 : 1\n )\n }\n }\n }\n })\n\n context.restore()\n context.restore()\n this.transformCanvas.trackCursor()\n }\n\n private onEnd = () => {}\n\n private loadNodeImages = () => {\n this.data.nodes.forEach((node: any) => {\n if (node.imgSrc && !this.imageCache.get(node.imgSrc)) {\n loadImage(node.imgSrc).then(img => {\n this.imageCache.set(node.imgSrc!, img)\n node.state = node.state || {}\n node.state.image = img\n })\n }\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.onDraw()\n }\n\n setTheme = (theme: ThemeMode) => {\n this.theme = theme\n this.onDraw()\n }\n\n setHideThumbnails = (hide: boolean) => {\n this.hideThumbnails = hide\n this.onDraw()\n }\n\n setSelectedNode = (node: SimNode | null) => {\n this.selectedNode = node\n // sort the selected node to the end of the array\n this.prunedData.nodes.sort((a, b) => {\n if (a.id === this.selectedNode?.id) return 1\n if (b.id === this.selectedNode?.id) return -1\n return 0\n })\n this.onDraw()\n }\n\n setHighlights = (highlights: string[]) => {\n this.highlights = highlights\n this.onDraw()\n }\n\n setNoInteraction = (noInteraction: boolean) => {\n this.noInteraction = noInteraction\n this.transformCanvas.setNoInteraction(this.noInteraction)\n this.onDraw()\n }\n\n getNodeById = (nodeId: string): SimNode | null => {\n return this.data.nodes.find(n => n.id === nodeId) || null\n }\n}\n","import { useOpenFormGraph } from \"@/provider\"\nimport { OpenGraphSimulation } from \"@/sim/OpenGraphSimulation\"\nimport { MouseEventHandler, useEffect, useRef } from \"react\"\n\ninterface OpenFormGraphProps {\n width: number\n height: number\n highlights?: string[]\n className?: string\n noInteraction?: boolean\n onMouseEnter?: MouseEventHandler\n onMouseLeave?: MouseEventHandler\n}\n\nexport function OpenFormGraph(props: OpenFormGraphProps) {\n const {\n width,\n height,\n highlights = [],\n className,\n noInteraction = false,\n } = props\n const {\n simulation,\n data,\n rootId,\n rootImageSources,\n theme,\n hideThumbnails,\n setHoveredNode,\n setSelectedNode,\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 theme,\n onHoveredNodeChange: n => {\n setHoveredNode(n)\n },\n onSelectedNodeChange: n => {\n setSelectedNode(n)\n },\n })\n return () => {\n simulation.current?.destroy()\n }\n }, [])\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 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,242 @@
|
|
1
|
+
import { Dispatch, MutableRefObject, ReactNode } from "react";
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
3
|
+
import { SimulationLinkDatum, SimulationNodeDatum } from "d3-force";
|
4
|
+
import * as d3_scale3 from "d3-scale";
|
5
|
+
|
6
|
+
//#region src/_types.d.ts
|
7
|
+
type RootNodeImageSources = [string?, string?];
|
8
|
+
type RawNode = {
|
9
|
+
id: string;
|
10
|
+
label?: string;
|
11
|
+
imgSrc?: string;
|
12
|
+
};
|
13
|
+
type NestedRawNode<N extends RawNode> = {
|
14
|
+
children: NestedRawNode<N>[];
|
15
|
+
} & N;
|
16
|
+
type RawLink = {
|
17
|
+
source: string;
|
18
|
+
target: string;
|
19
|
+
};
|
20
|
+
type Link = {
|
21
|
+
source: Node;
|
22
|
+
target: Node;
|
23
|
+
};
|
24
|
+
type Node = {
|
25
|
+
collapsed: boolean;
|
26
|
+
hide: boolean;
|
27
|
+
clusterSize: number;
|
28
|
+
level?: number;
|
29
|
+
childLinks: Link[];
|
30
|
+
image?: HTMLImageElement;
|
31
|
+
} & RawNode;
|
32
|
+
type RawGraphData = {
|
33
|
+
nodes: RawNode[];
|
34
|
+
links: RawLink[];
|
35
|
+
};
|
36
|
+
type GraphData = {
|
37
|
+
nodes: SimNode[];
|
38
|
+
links: SimLink[];
|
39
|
+
};
|
40
|
+
type ThemeMode = "dark" | "light";
|
41
|
+
type RGB = [number, number, number];
|
42
|
+
type ColorTransform = (rgb: RGB) => RGB;
|
43
|
+
type NodeState = {
|
44
|
+
collapsed?: boolean;
|
45
|
+
image?: HTMLImageElement;
|
46
|
+
};
|
47
|
+
type SimNode = {
|
48
|
+
state?: NodeState;
|
49
|
+
clusterSize?: number;
|
50
|
+
} & RawNode & SimulationNodeDatum;
|
51
|
+
type SimLink = {} & SimulationLinkDatum<SimNode>;
|
52
|
+
//#endregion
|
53
|
+
//#region src/_interfaces.d.ts
|
54
|
+
interface GraphConfig {
|
55
|
+
debug: false;
|
56
|
+
nodeSize: number;
|
57
|
+
minClusterSize: number;
|
58
|
+
maxClusterSize: number;
|
59
|
+
minZoom: number;
|
60
|
+
maxZoom: number;
|
61
|
+
theme: {
|
62
|
+
dark: [number, number, number];
|
63
|
+
light: [number, number, number];
|
64
|
+
};
|
65
|
+
}
|
66
|
+
//#endregion
|
67
|
+
//#region src/util/color.d.ts
|
68
|
+
interface ColorHandler {
|
69
|
+
(arg?: number): string;
|
70
|
+
(arg: ColorTransform): ColorHandler;
|
71
|
+
rgb: RGB;
|
72
|
+
}
|
73
|
+
/**
|
74
|
+
* Some utility functions to handle colors
|
75
|
+
*/
|
76
|
+
declare function color(rgb: RGB): ColorHandler;
|
77
|
+
/**
|
78
|
+
* Dims a color to white or black
|
79
|
+
* @param color An array of 3 numbers representing RGB values (0-255)
|
80
|
+
* @param dimFactor A value between 0 and 1 where 0 is completely black and 1 is the original color
|
81
|
+
* @returns A new array with the dimmed RGB values
|
82
|
+
*/
|
83
|
+
declare function dim(factor?: number, white?: boolean): ColorTransform;
|
84
|
+
//#endregion
|
85
|
+
//#region src/sim/TransformCanvas.d.ts
|
86
|
+
type Transform = {
|
87
|
+
x: number;
|
88
|
+
y: number;
|
89
|
+
scale: number;
|
90
|
+
};
|
91
|
+
type Point = {
|
92
|
+
x: number;
|
93
|
+
y: number;
|
94
|
+
};
|
95
|
+
type TransformListener = (t: Transform) => void;
|
96
|
+
type MouseListener = (x: number, y: number) => void;
|
97
|
+
type Focus = () => Transform;
|
98
|
+
declare class TransformCanvas {
|
99
|
+
canvas: HTMLCanvasElement;
|
100
|
+
transform: Transform;
|
101
|
+
targetTransform: Transform;
|
102
|
+
isAnimating: boolean;
|
103
|
+
animationFrame: number | null;
|
104
|
+
isDragging: boolean;
|
105
|
+
dragStart: Point | null;
|
106
|
+
moved: boolean;
|
107
|
+
lastMousePos: Point;
|
108
|
+
lastMoveMousePos: Point;
|
109
|
+
zoomFocus: Point;
|
110
|
+
onUpdate?: TransformListener;
|
111
|
+
onClick?: MouseListener;
|
112
|
+
onMove?: MouseListener;
|
113
|
+
noInteraction: boolean;
|
114
|
+
touchStart: Point | null;
|
115
|
+
lastTouchPos: Point;
|
116
|
+
pinchStartDist: number | null;
|
117
|
+
pinchStartScale: number;
|
118
|
+
focus: Focus | null;
|
119
|
+
constructor(canvas: HTMLCanvasElement, options?: {
|
120
|
+
onUpdate?: TransformListener;
|
121
|
+
onClick?: MouseListener;
|
122
|
+
onMove?: MouseListener;
|
123
|
+
});
|
124
|
+
lerp(a: number, b: number, t: number): number;
|
125
|
+
animateTransform: () => void;
|
126
|
+
handleWheel(e: WheelEvent): void;
|
127
|
+
handleMouseDown(e: MouseEvent): void;
|
128
|
+
handleMouseMove(e: MouseEvent): void;
|
129
|
+
handleMouseUpCanvas(e: MouseEvent): void;
|
130
|
+
handleMouseUp(e: MouseEvent): void;
|
131
|
+
handleTouchStart(e: TouchEvent): void;
|
132
|
+
handleTouchMove(e: TouchEvent): void;
|
133
|
+
handleTouchEnd(e: TouchEvent): void;
|
134
|
+
resetZoom(): void;
|
135
|
+
transformTo(update: Partial<Transform>): void;
|
136
|
+
trackCursor(): void;
|
137
|
+
destroy(): void;
|
138
|
+
setNoInteraction: (noInteraction: boolean) => void;
|
139
|
+
focusOn: (focus: Focus | null) => void;
|
140
|
+
}
|
141
|
+
//#endregion
|
142
|
+
//#region src/sim/OpenGraphSimulation.d.ts
|
143
|
+
interface OpenGraphSimulationProps {
|
144
|
+
width: number;
|
145
|
+
height: number;
|
146
|
+
config?: GraphConfig;
|
147
|
+
rootImageSources?: RootNodeImageSources;
|
148
|
+
canvas: HTMLCanvasElement;
|
149
|
+
theme?: ThemeMode;
|
150
|
+
onHoveredNodeChange?: (node: SimNode | null) => void;
|
151
|
+
onSelectedNodeChange?: (node: SimNode | null) => void;
|
152
|
+
}
|
153
|
+
declare class OpenGraphSimulation {
|
154
|
+
width: number;
|
155
|
+
height: number;
|
156
|
+
config: GraphConfig;
|
157
|
+
rootImageSources: RootNodeImageSources;
|
158
|
+
canvas: HTMLCanvasElement;
|
159
|
+
transformCanvas: TransformCanvas;
|
160
|
+
theme: ThemeMode;
|
161
|
+
private data;
|
162
|
+
private prunedData;
|
163
|
+
private subGraph;
|
164
|
+
private rootId;
|
165
|
+
private simulation;
|
166
|
+
private clusterSizeRange;
|
167
|
+
private imageCache;
|
168
|
+
private rootImages;
|
169
|
+
private hideThumbnails;
|
170
|
+
private noInteraction;
|
171
|
+
private selectedNode;
|
172
|
+
onSelectedNodeChange?: (node: SimNode | null) => void;
|
173
|
+
private hoveredNode;
|
174
|
+
onHoveredNodeChange?: (node: SimNode | null) => void;
|
175
|
+
private highlights;
|
176
|
+
constructor(props: OpenGraphSimulationProps);
|
177
|
+
private getNodeAtPosition;
|
178
|
+
private getNodeScreenPosition;
|
179
|
+
handleClick: (x: number, y: number) => void;
|
180
|
+
handleClickNode: (node: SimNode | null) => void;
|
181
|
+
handleMove: (x: number, y: number) => void;
|
182
|
+
initialize: (data: RawGraphData, rootId: string) => void;
|
183
|
+
restart: () => void;
|
184
|
+
get visiblityScale(): d3_scale3.ScaleLogarithmic<number, number, never>;
|
185
|
+
get color(): ColorHandler;
|
186
|
+
get colorContrast(): ColorHandler;
|
187
|
+
getNodeSize: (nodeId: string) => number;
|
188
|
+
onDraw: () => void;
|
189
|
+
private onEnd;
|
190
|
+
private loadNodeImages;
|
191
|
+
destroy: () => void;
|
192
|
+
resize: (width: number, height: number) => void;
|
193
|
+
setTheme: (theme: ThemeMode) => void;
|
194
|
+
setHideThumbnails: (hide: boolean) => void;
|
195
|
+
setSelectedNode: (node: SimNode | null) => void;
|
196
|
+
setHighlights: (highlights: string[]) => void;
|
197
|
+
setNoInteraction: (noInteraction: boolean) => void;
|
198
|
+
getNodeById: (nodeId: string) => SimNode | null;
|
199
|
+
}
|
200
|
+
//#endregion
|
201
|
+
//#region src/context/provider.d.ts
|
202
|
+
interface OpenFormGraphProviderProps {
|
203
|
+
rootId: string;
|
204
|
+
rootImageSources: RootNodeImageSources;
|
205
|
+
theme: ThemeMode;
|
206
|
+
children: ReactNode;
|
207
|
+
config?: GraphConfig;
|
208
|
+
data: RawGraphData;
|
209
|
+
onSelectedNodeChange?: (node: SimNode | null) => void;
|
210
|
+
onHoveredNodeChange?: (node: SimNode | null) => void;
|
211
|
+
}
|
212
|
+
interface OpenFormGraphApi {
|
213
|
+
rootId: string;
|
214
|
+
rootImageSources: RootNodeImageSources;
|
215
|
+
setSelectedNode: Dispatch<SimNode | null>;
|
216
|
+
setHoveredNode: Dispatch<SimNode | null>;
|
217
|
+
theme: ThemeMode;
|
218
|
+
hideThumbnails: boolean;
|
219
|
+
setHideThumbnails: Dispatch<boolean>;
|
220
|
+
config: GraphConfig;
|
221
|
+
data: RawGraphData;
|
222
|
+
simulation: MutableRefObject<OpenGraphSimulation | null>;
|
223
|
+
selectedNode: SimNode | null;
|
224
|
+
hoveredNode: SimNode | null;
|
225
|
+
setSelectedNodeById: (nodeId: string) => void;
|
226
|
+
}
|
227
|
+
declare function OpenFormGraphProvider({
|
228
|
+
theme,
|
229
|
+
rootId,
|
230
|
+
children,
|
231
|
+
rootImageSources,
|
232
|
+
config,
|
233
|
+
data
|
234
|
+
}: OpenFormGraphProviderProps): react_jsx_runtime0.JSX.Element;
|
235
|
+
declare function useOpenFormGraph(): OpenFormGraphApi;
|
236
|
+
//#endregion
|
237
|
+
//#region src/context/constants.d.ts
|
238
|
+
declare const VOID_ROOT_ID = "void-root";
|
239
|
+
declare const DEFAULT_GRAPH_CONFIG: GraphConfig;
|
240
|
+
//#endregion
|
241
|
+
export { ColorHandler, ColorTransform, DEFAULT_GRAPH_CONFIG as DEFAULT_GRAPH_CONFIG$1, GraphConfig, GraphData, Link, NestedRawNode, Node, NodeState, OpenFormGraphApi, OpenFormGraphProvider as OpenFormGraphProvider$1, RGB, RawGraphData, RawLink, RawNode, RootNodeImageSources, SimLink, SimNode, ThemeMode, VOID_ROOT_ID as VOID_ROOT_ID$1, color as color$1, dim as dim$1, useOpenFormGraph as useOpenFormGraph$1 };
|
242
|
+
//# sourceMappingURL=constants-DU_wYtaU.d.ts.map
|