diff --git a/packages/web/src/designer/Designer.svelte b/packages/web/src/designer/Designer.svelte index df522c6b2..fce13cb31 100644 --- a/packages/web/src/designer/Designer.svelte +++ b/packages/web/src/designer/Designer.svelte @@ -20,7 +20,6 @@ import { getTableInfo, useDatabaseInfo } from '../utility/metadataLoaders'; import cleanupDesignColumns from './cleanupDesignColumns'; import _ from 'lodash'; - import createRef from '../utility/createRef'; import { writable } from 'svelte/store'; import { tick } from 'svelte'; import contextMenu from '../utility/contextMenu'; @@ -235,7 +234,7 @@ pureName: foreignKey.refTableName, schemaName: foreignKey.refSchemaName, }); - const newTableDesignerId = uuidv1(); + const newTableDesignerId = `${toTable.pureName}-${uuidv1()}`; callChange(current => { const fromTable = (current.tables || []).find(x => x.designerId == designerId); if (!fromTable) return current; @@ -303,7 +302,7 @@ ...current.tables, ...newTables.map(x => ({ ...x, - designerId: uuidv1(), + designerId: `${x.pureName}-${uuidv1()}`, needsArrange: true, })), ], @@ -391,7 +390,7 @@ var json = JSON.parse(data); const { objectTypeField } = json; if (objectTypeField != 'tables' && objectTypeField != 'views') return; - json.designerId = uuidv1(); + json.designerId = `${json.pureName}-${uuidv1()}`; json.left = e.clientX - rect.left; json.top = e.clientY - rect.top; @@ -444,7 +443,7 @@ ? [ ...((current || {}).references || []), { - designerId: uuidv1(), + designerId: `${current?.pureName}-${uuidv1()}`, sourceId: foreignKeys[0].sourceId, targetId: foreignKeys[0].targetId, joinType: 'INNER JOIN', @@ -480,7 +479,7 @@ table.designerId, rect.right - rect.left, rect.bottom - rect.top, - arrangeAll || table.needsArrange ? null : { x: rect.left + rect.right / 2, y: rect.top + rect.bottom / 2 } + arrangeAll || table.needsArrange ? null : { x: (rect.left + rect.right) / 2, y: (rect.top + rect.bottom) / 2 } ); } @@ -491,6 +490,7 @@ graph.initialize(); const layout = GraphLayout.createCircle(graph, circleMiddle).springyAlg().doMoveSteps().fixViewBox(); + // layout.print(); callChange(current => { return { @@ -502,8 +502,8 @@ ? { ...table, needsArrange: false, - left: node.x - node.node.width / 2, - top: node.y - node.node.height / 2, + left: node.left, + top: node.top, } : { ...table, diff --git a/packages/web/src/designer/GraphLayout.ts b/packages/web/src/designer/GraphLayout.ts index 1c3f4b88e..14a5f2755 100644 --- a/packages/web/src/designer/GraphLayout.ts +++ b/packages/web/src/designer/GraphLayout.ts @@ -10,7 +10,7 @@ const REPULSION = 500_000; const MAX_FORCE_SIZE = 100; const NODE_MARGIN = 20; const MOVE_STEP = 20; -const MOVE_BIG_STEP = 70; +const MOVE_BIG_STEP = 50; const MOVE_STEP_COUNT = 100; const MINIMAL_SCORE_BENEFIT = 1; const SCORE_ASPECT_RATIO = 1.6; @@ -123,8 +123,8 @@ class LayoutNode { }; } - translate(dx: number, dy: number) { - if (this.node.fixedPosition) return this; + translate(dx: number, dy: number, forceMoveFixed = false) { + if (this.node.fixedPosition && !forceMoveFixed) return this; return new LayoutNode(this.node, this.x + dx, this.y + dy); } @@ -142,10 +142,6 @@ class ForceAlgorithmStep { constructor(public layout: GraphLayout) {} applyForce(node: LayoutNode, force: Vector2D) { - // if (node.node.designerId == '7ef3dd10-6ec0-11ec-b179-6d02a7c011ad') { - // console.log('APPLY', node.node.designerId, force.x, force.y); - // } - const size = force.magnitude(); if (size > MAX_FORCE_SIZE) { force = force.normalise().multiply(MAX_FORCE_SIZE); @@ -159,8 +155,6 @@ class ForceAlgorithmStep { } applyCoulombsLaw() { - // console.log('****** COULOMB'); - for (const n1 of _.values(this.layout.nodes)) { for (const n2 of _.values(this.layout.nodes)) { if (n1.node.designerId == n2.node.designerId) { @@ -296,7 +290,7 @@ export class GraphLayout { const minX = _.min(_.values(this.nodes).map(n => n.left)); const minY = _.min(_.values(this.nodes).map(n => n.top)); - return this.changePositions(n => n.translate(-minX + 50, -minY + 50)); + return this.changePositions(n => n.translate(-minX + 50, -minY + 50, true)); } springyStep() { @@ -317,6 +311,7 @@ export class GraphLayout { score() { let res = 0; + for (const n1 of _.values(this.nodes)) { for (const n2 of _.values(this.nodes)) { if (n1.node.designerId == n2.node.designerId) { @@ -376,12 +371,31 @@ export class GraphLayout { for (let step = 0; step < MOVE_STEP_COUNT; step++) { const lastRes = res; res = res.tryMoveElement(); + if (!res) { + lastRes.fillEdges(); + return lastRes; + } const newScore = res.score(); // console.log('STEP, SCORE, NEW SCORE', step, score, newScore); - if (score - newScore < MINIMAL_SCORE_BENEFIT) return lastRes; + if (score - newScore < MINIMAL_SCORE_BENEFIT) { + lastRes.fillEdges(); + return lastRes; + } score = newScore; } res.fillEdges(); return res; } + + print() { + for (const node of _.values(this.nodes)) { + console.log({ + designerId: node.node.designerId, + left: node.left, + top: node.top, + right: node.right, + bottom: node.bottom, + }); + } + } } diff --git a/packages/web/src/designer/designerMath.ts b/packages/web/src/designer/designerMath.ts index 940be79af..bcc513182 100644 --- a/packages/web/src/designer/designerMath.ts +++ b/packages/web/src/designer/designerMath.ts @@ -92,6 +92,10 @@ export function rectangleDistance(r1: IBoxBounds, r2: IBoxBounds) { export function rectangleIntersectArea(rect1: IBoxBounds, rect2: IBoxBounds) { const x_overlap = Math.max(0, Math.min(rect1.right, rect2.right) - Math.max(rect1.left, rect2.left)); const y_overlap = Math.max(0, Math.min(rect1.bottom, rect2.bottom) - Math.max(rect1.top, rect2.top)); + // console.log('rectangleIntersectArea', rect1, rect2, x_overlap * y_overlap); + // if (rect1.left < 100 && rect2.left < 100) { + // console.log('rectangleIntersectArea', rect1, rect2, x_overlap * y_overlap); + // } return x_overlap * y_overlap; } diff --git a/packages/web/src/tabs/DiagramTab.svelte b/packages/web/src/tabs/DiagramTab.svelte index 99b7174cd..1b1d5f750 100644 --- a/packages/web/src/tabs/DiagramTab.svelte +++ b/packages/web/src/tabs/DiagramTab.svelte @@ -81,6 +81,7 @@ return [ { command: 'diagram.save' }, { command: 'diagram.saveAs' }, + { command: 'designer.arrange' }, { divider: true }, { command: 'diagram.undo' }, { command: 'diagram.redo' }, @@ -88,10 +89,4 @@ } - +