diff --git a/packages/web/src/designer/Designer.svelte b/packages/web/src/designer/Designer.svelte index 1b6e8e6c1..0032d3f18 100644 --- a/packages/web/src/designer/Designer.svelte +++ b/packages/web/src/designer/Designer.svelte @@ -633,6 +633,17 @@ return settings?.canExport; } + // export function arrange(skipUndoChain = false) { + // switch (settings?.arrangeAlg) { + // case 'springy': + // arrange_springy(skipUndoChain); + // break; + // case 'tree': + // arrange_tree(skipUndoChain); + // break; + // } + // } + export function arrange(skipUndoChain = false, arrangeAll = true, circleMiddle = { x: 0, y: 0 }) { const graph = new GraphDefinition(); for (const table of value?.tables || []) { @@ -653,15 +664,27 @@ graph.initialize(); - const layout = GraphLayout - // initial circle layout - .createCircle(graph, circleMiddle) - // simulation with Hook's, Coulomb's and gravity law - .springyAlg() - // move nodes to avoid overlaps - .solveOverlaps() - // view box starts with [0,0] - .fixViewBox(); + let layout: GraphLayout; + switch (settings?.arrangeAlg) { + case 'springy': + layout = GraphLayout + // initial circle layout + .createCircle(graph, circleMiddle) + // simulation with Hook's, Coulomb's and gravity law + .springyAlg() + // move nodes to avoid overlaps + .solveOverlaps() + // view box starts with [0,0] + .fixViewBox(); + break; + case 'tree': + layout = GraphLayout.createTree(graph, value?.rootDesignerId); + break; + } + + if (!layout) { + return; + } // layout.print(); diff --git a/packages/web/src/designer/DiagramDesigner.svelte b/packages/web/src/designer/DiagramDesigner.svelte index e1fee69e9..25b7d901b 100644 --- a/packages/web/src/designer/DiagramDesigner.svelte +++ b/packages/web/src/designer/DiagramDesigner.svelte @@ -23,6 +23,7 @@ customizeStyle: true, allowDefineVirtualReferences: true, canCheckTables: true, + arrangeAlg: 'springy', }} referenceComponent={DiagramDesignerReference} /> diff --git a/packages/web/src/designer/GraphLayout.ts b/packages/web/src/designer/GraphLayout.ts index 9afd7e6ae..fb1b34cc4 100644 --- a/packages/web/src/designer/GraphLayout.ts +++ b/packages/web/src/designer/GraphLayout.ts @@ -18,6 +18,7 @@ const GRAVITY_Y = 0.01; const REPULSION = 1000; const MAX_FORCE_SIZE = 100; const NODE_MARGIN = 30; +const NODE_SPACE_TREE = 60; const GRAVITY_EXPONENT = 1.05; // const MOVE_STEP = 20; @@ -299,6 +300,43 @@ export class GraphLayout { return res; } + static createTree(graph: GraphDefinition, rootId: string): GraphLayout { + const res = new GraphLayout(graph); + const root = graph.nodes[rootId]; + if (!root) return res; + + const rootLayout = new LayoutNode(root, root.width / 2 + NODE_MARGIN, root.height / 2 + NODE_MARGIN); + res.nodes[rootId] = rootLayout; + + res.createTreeLevel([root], rootLayout.right + NODE_SPACE_TREE); + + return res; + } + + createTreeLevel(parentNodes: GraphNode[], left: number) { + let currentY = NODE_MARGIN; + let maxRight = 0; + const nextLevel: GraphNode[] = []; + for (const parent of parentNodes) { + for (const child of parent.neightboors) { + if (child.designerId in this.nodes) { + continue; + } + nextLevel.push(child); + const layoutNode = new LayoutNode(child, left + child.width / 2, currentY + child.height / 2); + this.nodes[child.designerId] = layoutNode; + currentY += child.height + NODE_MARGIN; + if (layoutNode.right > maxRight) { + maxRight = layoutNode.right; + } + } + } + + if (nextLevel.length > 0) { + this.createTreeLevel(nextLevel, maxRight + NODE_SPACE_TREE); + } + } + fillEdges() { this.edges = this.graph.edges.map(edge => { const res = new LayoutEdge(); diff --git a/packages/web/src/designer/QueryDesigner.svelte b/packages/web/src/designer/QueryDesigner.svelte index e573485ec..d5c4ae5eb 100644 --- a/packages/web/src/designer/QueryDesigner.svelte +++ b/packages/web/src/designer/QueryDesigner.svelte @@ -23,6 +23,7 @@ customizeStyle: false, allowDefineVirtualReferences: false, canCheckTables: true, + arrangeAlg: null, }} referenceComponent={QueryDesignerReference} /> diff --git a/packages/web/src/perspectives/PerspectiveDesigner.svelte b/packages/web/src/perspectives/PerspectiveDesigner.svelte index 7acba5842..3c7a48f15 100644 --- a/packages/web/src/perspectives/PerspectiveDesigner.svelte +++ b/packages/web/src/perspectives/PerspectiveDesigner.svelte @@ -95,6 +95,7 @@ customizeStyle: false, allowDefineVirtualReferences: false, canCheckTables: true, + arrangeAlg: 'tree', }} referenceComponent={QueryDesignerReference} value={createDesignerModel(config, dbInfos)}