mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-09 02:27:05 +02:00
#3358 Recursive positioning
This commit is contained in:
@@ -65,8 +65,8 @@
|
||||
<body>
|
||||
<pre id="diagram" class="mermaid">
|
||||
block-beta
|
||||
%% id1("Wide 1")
|
||||
id2("2")
|
||||
id1("Wide 1")
|
||||
%%id2("2")
|
||||
block
|
||||
id3["I am a wide one"]
|
||||
block
|
||||
@@ -79,9 +79,26 @@ block-beta
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid">
|
||||
block-beta
|
||||
|
||||
id3["I am a wide one"]
|
||||
id4
|
||||
id1
|
||||
block
|
||||
id2
|
||||
end
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid">
|
||||
block-beta
|
||||
id1["Hello"]
|
||||
block
|
||||
id2["to"]
|
||||
id3["the"]
|
||||
id4["World"]
|
||||
end
|
||||
</pre>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
block-beta
|
||||
block
|
||||
id2["I am a wide one"]
|
||||
id1
|
||||
end
|
||||
|
||||
|
||||
</pre>
|
||||
|
@@ -1,12 +1,14 @@
|
||||
import { BlockDB } from './blockDB.js';
|
||||
import type { Block } from './blockTypes.js';
|
||||
|
||||
const padding = 10;
|
||||
|
||||
function calcBlockSizes(block: Block, db: BlockDB) {
|
||||
console.log('calculateSize (start)', block.id, block?.size?.x, block?.size?.width);
|
||||
const totalWidth = 0;
|
||||
const totalHeight = 0;
|
||||
let maxWidth = 0;
|
||||
let maxHeight = 0;
|
||||
const padding = 20;
|
||||
|
||||
if (block.children) {
|
||||
for (const child of block.children) {
|
||||
@@ -15,6 +17,7 @@ function calcBlockSizes(block: Block, db: BlockDB) {
|
||||
// find max width of children
|
||||
for (const child of block.children) {
|
||||
const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 };
|
||||
// console.log('APA', child.id, width, height, x, y);
|
||||
if (width > maxWidth) {
|
||||
maxWidth = width;
|
||||
}
|
||||
@@ -28,22 +31,24 @@ function calcBlockSizes(block: Block, db: BlockDB) {
|
||||
if (child.size) {
|
||||
child.size.width = maxWidth;
|
||||
child.size.height = maxHeight;
|
||||
child.size.x = 0;
|
||||
child.size.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Position items relative to self
|
||||
let x = -padding / 2;
|
||||
const y = 0;
|
||||
// // Position items relative to self
|
||||
// let x = -padding / 2;
|
||||
// const y = 0;
|
||||
|
||||
let accumulatedPaddingX = 0;
|
||||
for (const child of block.children) {
|
||||
if (child.size) {
|
||||
child.size.x = x;
|
||||
child.size.y = y;
|
||||
x += maxWidth + padding;
|
||||
}
|
||||
accumulatedPaddingX += padding;
|
||||
}
|
||||
// let accumulatedPaddingX = 0;
|
||||
// for (const child of block.children) {
|
||||
// if (child.size) {
|
||||
// child.size.x = x;
|
||||
// child.size.y = y;
|
||||
// x += maxWidth + padding;
|
||||
// }
|
||||
// accumulatedPaddingX += padding;
|
||||
// }
|
||||
}
|
||||
if (block.children?.length > 0) {
|
||||
const numChildren = block.children.length;
|
||||
@@ -54,19 +59,88 @@ function calcBlockSizes(block: Block, db: BlockDB) {
|
||||
y: 0,
|
||||
};
|
||||
}
|
||||
console.log('layoutBlock (done)', block);
|
||||
console.log('calculateSize APA (done)', block.id, block.size.x, block.size.width);
|
||||
}
|
||||
|
||||
function layoutBlocks(block: Block, db: BlockDB) {
|
||||
console.log('layout blocks (block)', block.id, 'x:', block.size.x, 'width:', block.size.width);
|
||||
if (
|
||||
block.children && // find max width of children
|
||||
block.children.length > 0
|
||||
) {
|
||||
const width = block?.children[0]?.size?.width || 0;
|
||||
const widthOfChildren = block.children.length * width + (block.children.length - 1) * padding;
|
||||
let posX = (block?.size?.x || 0) - widthOfChildren / 2;
|
||||
const posY = 0;
|
||||
const parentX = block?.size?.x || 0 - block.children.length;
|
||||
const parentWidth = block?.size?.width || 0;
|
||||
|
||||
console.log('widthOfChildren', widthOfChildren, 'posX', posX, 'parentX', parentX);
|
||||
|
||||
// let first = true;
|
||||
for (const child of block.children) {
|
||||
console.log(
|
||||
'layout blocks (child)',
|
||||
child.id,
|
||||
'x:',
|
||||
child?.size?.x,
|
||||
'width:',
|
||||
child?.size?.width,
|
||||
'posX:',
|
||||
posX,
|
||||
block?.size?.x,
|
||||
widthOfChildren / 2,
|
||||
widthOfChildren / 2
|
||||
);
|
||||
|
||||
if (!child.size) {
|
||||
continue;
|
||||
}
|
||||
const { width, height } = child.size;
|
||||
child.size.x = posX + width / 2;
|
||||
posX += width + padding;
|
||||
child.size.y = posY;
|
||||
// posY += height + padding;
|
||||
if (child.children) {
|
||||
layoutBlocks(child, db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function positionBlock(parent: Block, block: Block, db: BlockDB) {
|
||||
console.log('layout position block', parent.id, parent?.size?.x, block.id, block?.size?.x);
|
||||
console.log(
|
||||
'layout position block',
|
||||
parent.id,
|
||||
parent?.size?.x,
|
||||
block.id,
|
||||
block?.size?.x,
|
||||
'width:',
|
||||
block?.size?.width
|
||||
);
|
||||
let parentX = 0;
|
||||
let parentWidth = 0;
|
||||
let y = 0;
|
||||
if (parent) {
|
||||
if (parent.id !== 'root') {
|
||||
parentX = parent?.size?.x || 0;
|
||||
parentWidth = parent?.size?.width || 0;
|
||||
y = parent?.size?.y || 0;
|
||||
}
|
||||
if (block.size && block.id !== 'root') {
|
||||
block.size.x = parentX + block.size.x + -block.size.width / 2;
|
||||
console.log(
|
||||
'layout position block (calc)',
|
||||
'x:',
|
||||
parentX,
|
||||
parentWidth / 2,
|
||||
block.id,
|
||||
'x:',
|
||||
block.size.x,
|
||||
block.size.width
|
||||
);
|
||||
// block.size.x = parentX + block.size.x + -block.size.width / 2;
|
||||
block.size.x =
|
||||
parentX < 0 ? parentX + block.size.x : parentX + block.size.x + -block.size.width / 2;
|
||||
// block.size.x = parentX - parentWidth + Math.abs(block.size.x) / 2;
|
||||
block.size.y = block.size.y + y;
|
||||
}
|
||||
if (block.children) {
|
||||
@@ -82,10 +156,11 @@ let maxX = 0;
|
||||
let maxY = 0;
|
||||
|
||||
function findBounds(block: Block) {
|
||||
if (block.size) {
|
||||
if (block.size && block.id !== 'root') {
|
||||
const { x, y, width, height } = block.size;
|
||||
if (x - width / 2 < minX) {
|
||||
minX = x - width / 2;
|
||||
// console.log('Here APA minX', block.id, x, width, minX);
|
||||
}
|
||||
if (y - height / 2 < minY) {
|
||||
minY = y - height / 2;
|
||||
@@ -108,8 +183,9 @@ export function layout(db: BlockDB) {
|
||||
const blocks = db.getBlocks();
|
||||
const root = { id: 'root', type: 'composite', children: blocks } as Block;
|
||||
calcBlockSizes(root, db);
|
||||
layoutBlocks(root, db);
|
||||
// Position blocks relative to parents
|
||||
positionBlock(root, root, db);
|
||||
// positionBlock(root, root, db);
|
||||
console.log('getBlocks', JSON.stringify(db.getBlocks(), null, 2));
|
||||
|
||||
minX = 0;
|
||||
@@ -117,7 +193,7 @@ export function layout(db: BlockDB) {
|
||||
maxX = 0;
|
||||
maxY = 0;
|
||||
findBounds(root);
|
||||
console.log('Here maxX', maxX);
|
||||
// console.log('Here maxX', minX, '--', maxX);
|
||||
const height = maxY - minY;
|
||||
const width = maxX - minX;
|
||||
return { x: minX, y: minY, width, height };
|
||||
|
Reference in New Issue
Block a user