mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 23:35:59 +00:00
perspective tree layout
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
customizeStyle: true,
|
||||
allowDefineVirtualReferences: true,
|
||||
canCheckTables: true,
|
||||
arrangeAlg: 'springy',
|
||||
}}
|
||||
referenceComponent={DiagramDesignerReference}
|
||||
/>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
customizeStyle: false,
|
||||
allowDefineVirtualReferences: false,
|
||||
canCheckTables: true,
|
||||
arrangeAlg: null,
|
||||
}}
|
||||
referenceComponent={QueryDesignerReference}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user