perspective tree layout

This commit is contained in:
Jan Prochazka
2022-08-27 10:06:06 +02:00
parent 9e3a457ef5
commit fec2df9d2f
5 changed files with 73 additions and 9 deletions

View File

@@ -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();

View File

@@ -23,6 +23,7 @@
customizeStyle: true,
allowDefineVirtualReferences: true,
canCheckTables: true,
arrangeAlg: 'springy',
}}
referenceComponent={DiagramDesignerReference}
/>

View File

@@ -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();

View File

@@ -23,6 +23,7 @@
customizeStyle: false,
allowDefineVirtualReferences: false,
canCheckTables: true,
arrangeAlg: null,
}}
referenceComponent={QueryDesignerReference}
/>