Improved interface for map view

This commit is contained in:
Atharva Sawant
2024-04-12 09:31:52 +05:30
parent 5462b2e795
commit 5b8aa412fa
3 changed files with 67 additions and 36 deletions

View File

@@ -77,8 +77,9 @@
</div> </div>
</div> </div>
<Handle type="target" :position="Position.Left" class="handle-left" /> <!-- Center connection handles - no position specified for true center -->
<Handle type="source" :position="Position.Right" class="handle-right" /> <Handle type="source" class="handle-center" />
<Handle type="target" class="handle-center" />
</div> </div>
</template> </template>
@@ -190,11 +191,12 @@ function cancelContentEdit() {
box-shadow: 0 0 0 2px #3b82f6; box-shadow: 0 0 0 2px #3b82f6;
} }
.handle-left, .handle-center {
.handle-right { opacity: 0;
width: 8px; pointer-events: none;
height: 8px; position: absolute;
border: 2px solid #3b82f6; top: 50%;
background: white; left: 50%;
transform: translate(-50%, -50%);
} }
</style> </style>

View File

@@ -134,6 +134,16 @@ function exportFile() {
border: none; border: none;
} }
.vue-flow__edge.vue-flow__edge-straight {
stroke: #64748b;
stroke-width: 2;
}
.vue-flow__edge.vue-flow__edge-straight:hover {
stroke: #3b82f6;
stroke-width: 3;
}
.vue-flow__edge.vue-flow__edge-smoothstep { .vue-flow__edge.vue-flow__edge-smoothstep {
stroke: #64748b; stroke: #64748b;
stroke-width: 2; stroke-width: 2;

View File

@@ -14,7 +14,9 @@ export interface FlowEdge {
id: string id: string
source: string source: string
target: string target: string
type: 'smoothstep' sourceHandle?: string
targetHandle?: string
type: 'straight' | 'smoothstep'
} }
export function generateNodeLayout(nodes: OrgNode[]): { nodes: FlowNode[]; edges: FlowEdge[] } { export function generateNodeLayout(nodes: OrgNode[]): { nodes: FlowNode[]; edges: FlowEdge[] } {
@@ -22,63 +24,80 @@ export function generateNodeLayout(nodes: OrgNode[]): { nodes: FlowNode[]; edges
const flowEdges: FlowEdge[] = [] const flowEdges: FlowEdge[] = []
let nodeCounter = 0 let nodeCounter = 0
const levelPositions: Map<number, number> = new Map() // Track position within each level
function processNode( function processNode(
node: OrgNode, node: OrgNode,
level: number, level: number,
parentId: string | null, parentId: string | null,
angle: number, parentX: number = 400,
distance: number, parentY: number = 100
centerX: number = 400, ): string {
centerY: number = 300
) {
const nodeId = `node-${nodeCounter++}` const nodeId = `node-${nodeCounter++}`
// Calculate position in a radial/organic layout // Hierarchical positioning: levels go top to bottom
const x = centerX + Math.cos(angle) * distance const yPosition = 100 + (level - 1) * 200 // 200px between levels
const y = centerY + Math.sin(angle) * distance
// Get current position for this level
let xPosition: number
if (level === 1) {
// Root nodes: center them horizontally
const rootIndex = flowNodes.filter(n => n.data.level === 1).length
const rootSpacing = 350
const totalRootWidth = (nodes.length - 1) * rootSpacing
xPosition = 400 + rootIndex * rootSpacing - totalRootWidth / 2
} else {
// Child nodes: position relative to parent
const currentLevelCount = levelPositions.get(level) || 0
levelPositions.set(level, currentLevelCount + 1)
// Calculate children positions spread around parent
const parentNode = flowNodes.find(n => n.id === parentId)
if (parentNode) {
const siblingCount = node.children?.length || 1
const parentChildren = flowNodes.filter(n =>
flowEdges.some(e => e.source === parentId && e.target === n.id)
).length
const childSpacing = Math.max(250, 400 / Math.max(siblingCount, 1))
const totalWidth = (siblingCount - 1) * childSpacing
xPosition = parentX + (parentChildren * childSpacing) - (totalWidth / 2)
} else {
xPosition = parentX + (currentLevelCount * 300)
}
}
flowNodes.push({ flowNodes.push({
id: nodeId, id: nodeId,
type: 'orgNode', type: 'orgNode',
position: { x, y }, position: { x: xPosition, y: yPosition },
data: { data: {
node, node,
level level
} }
}) })
// Add edge from parent // Add edge from parent - center to center diagonal
if (parentId) { if (parentId) {
flowEdges.push({ flowEdges.push({
id: `edge-${parentId}-${nodeId}`, id: `edge-${parentId}-${nodeId}`,
source: parentId, source: parentId,
target: nodeId, target: nodeId,
type: 'smoothstep' type: 'straight'
}) })
} }
// Process children in a radial pattern around this node // Process children
const childCount = node.children.length node.children.forEach((child, index) => {
if (childCount > 0) { processNode(child, level + 1, nodeId, xPosition, yPosition)
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 return nodeId
} }
// Start with root nodes in a circular pattern // Process all root nodes
const rootCount = nodes.length
nodes.forEach((node, index) => { nodes.forEach((node, index) => {
const angle = (2 * Math.PI * index) / rootCount processNode(node, 1, null)
const distance = rootCount > 1 ? 200 : 0
processNode(node, 1, null, angle, distance)
}) })
return { nodes: flowNodes, edges: flowEdges } return { nodes: flowNodes, edges: flowEdges }