Implemented 2D visualization for notes using Vue Flow
This commit is contained in:
85
src/utils/nodeLayoutGenerator.ts
Normal file
85
src/utils/nodeLayoutGenerator.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import type { OrgNode } from '@/types/org'
|
||||
|
||||
export interface FlowNode {
|
||||
id: string
|
||||
type: 'orgNode'
|
||||
position: { x: number; y: number }
|
||||
data: {
|
||||
node: OrgNode
|
||||
level: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface FlowEdge {
|
||||
id: string
|
||||
source: string
|
||||
target: string
|
||||
type: 'smoothstep'
|
||||
}
|
||||
|
||||
export function generateNodeLayout(nodes: OrgNode[]): { nodes: FlowNode[]; edges: FlowEdge[] } {
|
||||
const flowNodes: FlowNode[] = []
|
||||
const flowEdges: FlowEdge[] = []
|
||||
|
||||
let nodeCounter = 0
|
||||
|
||||
function processNode(
|
||||
node: OrgNode,
|
||||
level: number,
|
||||
parentId: string | null,
|
||||
angle: number,
|
||||
distance: number,
|
||||
centerX: number = 400,
|
||||
centerY: number = 300
|
||||
) {
|
||||
const nodeId = `node-${nodeCounter++}`
|
||||
|
||||
// Calculate position in a radial/organic layout
|
||||
const x = centerX + Math.cos(angle) * distance
|
||||
const y = centerY + Math.sin(angle) * distance
|
||||
|
||||
flowNodes.push({
|
||||
id: nodeId,
|
||||
type: 'orgNode',
|
||||
position: { x, y },
|
||||
data: {
|
||||
node,
|
||||
level
|
||||
}
|
||||
})
|
||||
|
||||
// Add edge from parent
|
||||
if (parentId) {
|
||||
flowEdges.push({
|
||||
id: `edge-${parentId}-${nodeId}`,
|
||||
source: parentId,
|
||||
target: nodeId,
|
||||
type: 'smoothstep'
|
||||
})
|
||||
}
|
||||
|
||||
// Process children in a radial pattern around this node
|
||||
const childCount = node.children.length
|
||||
if (childCount > 0) {
|
||||
const angleStep = (2 * Math.PI) / Math.max(childCount, 3)
|
||||
const childDistance = Math.max(150, distance * 0.7)
|
||||
|
||||
node.children.forEach((child, index) => {
|
||||
const childAngle = angle + (index - (childCount - 1) / 2) * angleStep * 0.8
|
||||
processNode(child, level + 1, nodeId, childAngle, childDistance, x, y)
|
||||
})
|
||||
}
|
||||
|
||||
return nodeId
|
||||
}
|
||||
|
||||
// Start with root nodes in a circular pattern
|
||||
const rootCount = nodes.length
|
||||
nodes.forEach((node, index) => {
|
||||
const angle = (2 * Math.PI * index) / rootCount
|
||||
const distance = rootCount > 1 ? 200 : 0
|
||||
processNode(node, 1, null, angle, distance)
|
||||
})
|
||||
|
||||
return { nodes: flowNodes, edges: flowEdges }
|
||||
}
|
||||
Reference in New Issue
Block a user