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