Skip to content

Commit

Permalink
fix: auto arrangement improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
sheikalthaf committed Oct 14, 2023
1 parent 66e64b1 commit c23e45d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 197 deletions.
2 changes: 1 addition & 1 deletion src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'] },
Expand Down
177 changes: 28 additions & 149 deletions src/app/arrangements.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -32,170 +32,49 @@ describe('Arrangements', () => {
},
}));
const connections = new Connections(list);
const childObj: Record<string, ChildInfo> = {
const childObj: Record<string, any> = {
'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);
});
Expand Down
73 changes: 27 additions & 46 deletions src/app/arrangements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -77,63 +82,39 @@ export class Arrangements {
baseX: number,
baseY: number,
newItems: Map<string, FlowOptions>
) {
): 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<string, number> {
Expand Down

0 comments on commit c23e45d

Please sign in to comment.