diff --git a/src/app/app.component.scss b/src/app/app.component.scss index caea437..78ff481 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -3,7 +3,7 @@ align-items: center; justify-content: center; width: 200px; - height: 200px; + height: 50px; box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3); border-radius: 5px; background-color: white; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 3928bdb..1f175fd 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -897,7 +897,7 @@ export const FLOW_LIST = [ { x: 40, y: 200, id: '5', deps: ['1'] }, { x: 200, y: 200, id: '6', deps: ['5'] }, { x: 360, y: 200, id: '7', deps: ['5'] }, - { x: 520, y: 200, id: '8', deps: ['6', '7'] }, + // { x: 520, y: 200, id: '8', deps: ['6', '7'] }, // { x: 40, y: 40, id: '1', deps: [] }, // { x: 200, y: 40, id: '2', deps: ['1'] }, diff --git a/src/app/arrangements.spec.ts b/src/app/arrangements.spec.ts index 6f5373b..b413ac7 100644 --- a/src/app/arrangements.spec.ts +++ b/src/app/arrangements.spec.ts @@ -10,7 +10,7 @@ export const FLOW_LIST = [ { x: 40, y: 200, id: '5', deps: ['1'] }, { x: 200, y: 200, id: '6', deps: ['5'] }, { x: 360, y: 200, id: '7', deps: ['5'] }, - { x: 520, y: 200, id: '8', deps: ['6', '7'] }, + // { x: 520, y: 200, id: '8', deps: ['6', '7'] }, ]; describe('Arrangements', () => { @@ -32,170 +32,49 @@ describe('Arrangements', () => { }, })); const connections = new Connections(list); - const childObj: Record = { + const childObj: Record = { '1': { - position: { - x: 40, - y: 40, - id: '1', - deps: [], - }, - elRect: { - x: 99.796875, - y: 115, - width: 150, - height: 200, - top: 115, - right: 249.796875, - bottom: 315, - left: 99.796875, - toJSON: () => {}, - }, + position: { x: 40, y: 40, id: '1', deps: [] }, + elRect: { width: 200, height: 200 }, }, '2': { - position: { - x: 200, - y: 40, - id: '2', - deps: ['1'], - }, - elRect: { - x: 259.796875, - y: 115, - width: 150, - height: 200, - top: 115, - right: 409.796875, - bottom: 315, - left: 259.796875, - toJSON: () => {}, - }, + position: { x: 200, y: 40, id: '2', deps: ['1'] }, + elRect: { width: 200, height: 200 }, }, '3': { - position: { - x: 360, - y: 40, - id: '3', - deps: ['2'], - }, - elRect: { - x: 419.796875, - y: 115, - width: 150, - height: 200, - top: 115, - right: 569.796875, - bottom: 315, - left: 419.796875, - toJSON: () => {}, - }, + position: { x: 360, y: 40, id: '3', deps: ['2'] }, + elRect: { width: 200, height: 200 }, }, '4': { - position: { - x: 520, - y: 40, - id: '4', - deps: ['2'], - }, - elRect: { - x: 579.796875, - y: 115, - width: 150, - height: 200, - top: 115, - right: 729.796875, - bottom: 315, - left: 579.796875, - toJSON: () => {}, - }, + position: { x: 520, y: 40, id: '4', deps: ['2'] }, + elRect: { width: 200, height: 200 }, }, '5': { - position: { - x: 40, - y: 200, - id: '5', - deps: ['1'], - }, - elRect: { - x: 99.796875, - y: 275, - width: 150, - height: 200, - top: 275, - right: 249.796875, - bottom: 475, - left: 99.796875, - toJSON: () => {}, - }, + position: { x: 40, y: 200, id: '5', deps: ['1'] }, + elRect: { width: 200, height: 200 }, }, '6': { - position: { - x: 200, - y: 200, - id: '6', - deps: ['5'], - }, - elRect: { - x: 259.796875, - y: 275, - width: 150, - height: 200, - top: 275, - right: 409.796875, - bottom: 475, - left: 259.796875, - toJSON: () => {}, - }, + position: { x: 200, y: 200, id: '6', deps: ['5'] }, + elRect: { width: 200, height: 200 }, }, '7': { - position: { - x: 360, - y: 200, - id: '7', - deps: ['5'], - }, - elRect: { - x: 419.796875, - y: 275, - width: 150, - height: 200, - top: 275, - right: 569.796875, - bottom: 475, - left: 419.796875, - toJSON: () => {}, - }, - }, - '8': { - position: { - x: 520, - y: 200, - id: '8', - deps: ['6', '7'], - }, - elRect: { - x: 579.796875, - y: 275, - width: 150, - height: 200, - top: 275, - right: 729.796875, - bottom: 475, - left: 579.796875, - toJSON: () => {}, - }, + position: { x: 360, y: 200, id: '7', deps: ['5'] }, + elRect: { width: 200, height: 200 }, }, + // '8': { + // position: { x: 520, y: 200, id: '8', deps: ['6', '7'] }, + // elRect: { width: 150, height: 200 }, + // }, }; - arrangements = new Arrangements(connections, childObj); + arrangements = new Arrangements(connections, childObj as any); const expected = { - '1': { x: 0, y: 0, id: '1', deps: [] }, - '2': { x: 250, y: -150, id: '2', deps: ['1'] }, - '3': { x: 500, y: -300, id: '3', deps: ['2'] }, - '4': { x: 500, y: 0, id: '4', deps: ['2'] }, - '5': { x: 250, y: 150, id: '5', deps: ['1'] }, - '6': { x: 500, y: 0, id: '6', deps: ['5'] }, - '7': { x: 500, y: 300, id: '7', deps: ['5'] }, - '8': { x: 750, y: 150, id: '8', deps: ['6', '7'] }, + '1': { x: 0, y: 315, id: '1', deps: [] }, + '2': { x: 300, y: 105, id: '2', deps: ['1'] }, + '3': { x: 600, y: 0, id: '3', deps: ['2'] }, + '4': { x: 600, y: 210, id: '4', deps: ['2'] }, + '5': { x: 300, y: 525, id: '5', deps: ['1'] }, + '6': { x: 600, y: 420, id: '6', deps: ['5'] }, + '7': { x: 600, y: 630, id: '7', deps: ['5'] }, }; expect(Object.fromEntries(arrangements.newList)).toEqual(expected); }); diff --git a/src/app/arrangements.ts b/src/app/arrangements.ts index 9e7bca6..39bbd48 100644 --- a/src/app/arrangements.ts +++ b/src/app/arrangements.ts @@ -32,13 +32,18 @@ export class Arrangements { ); for (const baseNode of baseNodes) { - const centerY = baseNode.elRect.height / 2; + const consumedHeight = this.positionDependents( + baseNode, + currentX - baseNode.elRect.width - this.horizontalPadding, + 0, + newItems + ); + const centerY = consumedHeight / 2; newItems.set(baseNode.position.id, { ...baseNode.position, x: currentX, y: centerY - baseNode.elRect.height / 2, }); - this.positionDependents(baseNode, currentX, centerY, newItems); currentX += baseNode.elRect.width + this.horizontalPadding + this.groupPadding; } @@ -77,63 +82,39 @@ export class Arrangements { baseX: number, baseY: number, newItems: Map - ) { + ): number { const dependents = Object.values(this.list).filter((child) => child.position.deps.includes(baseNode.position.id) ); - if (dependents.length === 0) return; - - // Calculate the total height required by all dependents - let totalHeight = dependents.reduce( - (sum, child) => sum + child.elRect.height, - 0 - ); - - totalHeight += this.verticalPadding * (dependents.length - 1); - - // Determine the starting Y-coordinate for the first child - let startY = baseY - totalHeight / 2; - // Sort children by their original Y-coordinate to preserve order dependents.sort((a, b) => a.position.y - b.position.y); - for (const dependent of dependents) { - const newX = baseX + baseNode.elRect.width + this.horizontalPadding; - - // If a child has multiple parents, adjust its Y position to be in the center of those parents - if (dependent.position.deps.length > 1) { - const parentYs = dependent.position.deps - .filter((depId) => newItems.has(depId)) - .map( - (depId) => - newItems.get(depId)!.y + this.list[depId].elRect.height / 2 - ); - - // Calculate the mid-point Y of all parents - if (parentYs.length > 0) { - const minY = Math.min(...parentYs); - const maxY = Math.max(...parentYs); - startY = minY + (maxY - minY) / 2 - dependent.elRect.height / 2; - } - } - - newItems.set(dependent.position.id, { - ...dependent.position, - x: newX, - y: startY, - }); + let startY = baseY; + let newX = baseX + baseNode.elRect.width + this.horizontalPadding; + const height = baseNode.elRect.height; - this.positionDependents( + for (let i = 0; i < dependents.length; i++) { + const dependent = dependents[i]; + const consumedHeight = this.positionDependents( dependent, newX, - startY + dependent.elRect.height / 2, + startY, newItems ); - - // Move to the next position - startY += dependent.elRect.height + this.verticalPadding; + startY = + consumedHeight + (i < dependents.length - 1 ? this.verticalPadding : 0); } + + const y = + baseY + (dependents.length ? (startY - baseY) / 2 - height / 2 : 0); + + newItems.set(baseNode.position.id, { + ...baseNode.position, + x: newX, + y: y, + }); + return startY + (dependents.length ? 0 : height); } public determineLevels(): Map {