#3358 Fix for layout where a siebling has wider siize

This commit is contained in:
Knut Sveidqvist 2024-01-08 14:03:42 +01:00
parent 809c450164
commit 7043892e87
10 changed files with 147 additions and 56 deletions

View File

@ -301,4 +301,39 @@ describe('Block diagram', () => {
{}
);
});
it('BL22: sizing - it should be possible to make a block wider', () => {
imgSnapshotTest(
`block-beta
A("rounded):2
B:2
C
`,
{}
);
});
it('BL23: sizing - it should be possieble to make a composite block wider', () => {
imgSnapshotTest(
`block-beta
block:2
A
end
B
`,
{}
);
});
it('BL23: sizing - it should be possieble to make a composite block wider', () => {
imgSnapshotTest(
`block-beta
block:2
A
end
B
`,
{}
);
});
});

View File

@ -62,6 +62,52 @@
</style>
</head>
<body>
<pre id="diagram" class="mermaid">
block-beta
columns 3
space Browser space
space:3
A
B
C
space:3
space
db{{"This is the text in the box"}}
classDef green fill:#9f6,stroke:#333,stroke-width:2px;
style B fill:#f9F,stroke:#333,stroke-width:4px
class A green
Browser --> A
Browser --> B
Browser --> C
A --> db
B --> db
C--> db
block
D
E
end
</pre>
<pre id="diagram" class="mermaid">
block-beta
block
D
E
end
db("This is the text in the box")
</pre>
<pre id="diagram" class="mermaid">
block-beta
block
D
end
A["A: I am a wide one"]
</pre>
<pre id="diagram" class="mermaid2">
block-beta
A["square"]
@ -78,7 +124,7 @@ block-beta
block-beta
A(["stadium"])
</pre>
<pre id="diagram" class="mermaid">
<pre id="diagram" class="mermaid2">
block-beta
%% A[["subroutine"]]
%% B[("cylinder")]

View File

@ -79,7 +79,6 @@ export const addStyle2Node = function (id: string, styles = '') {
* @param {string} cssClassName CSS class name
*/
export const setCssClass = function (itemIds: string, cssClassName: string) {
console.log('abc88 setCssClass enter', itemIds, cssClassName);
itemIds.split(',').forEach(function (id: string) {
let foundBlock = blockDatabase[id];
if (foundBlock === undefined) {
@ -91,7 +90,6 @@ export const setCssClass = function (itemIds: string, cssClassName: string) {
foundBlock.classes = [];
}
foundBlock.classes.push(cssClassName);
console.log('abc88 setCssClass', foundBlock);
});
};
@ -130,21 +128,15 @@ const populateBlockDatabase = (_blockList: Block[], parent: Block): void => {
const children = [];
for (const block of blockList) {
if (block.type === 'classDef') {
// console.log('abc88 classDef', block);
addStyleClass(block.id, block.css);
continue;
}
if (block.type === 'applyClass') {
// console.log('abc88 applyClass', block);
// addStyleClass(block.id, block.css);
setCssClass(block.id, block?.styleClass || '');
continue;
}
if (block.type === 'applyStyles') {
console.log('abc88 applyStyles', block);
addStyle2Node(block.id, block.styles);
// addStyleClass(block.id, block.css);
// setCssClass(block.id, block.styles);
addStyle2Node(block.id, block?.styles);
continue;
}
if (block.type === 'column-setting') {
@ -361,7 +353,6 @@ type IGetClasses = () => Record<string, ClassDef>;
* @returns {{} | any | classes}
*/
export const getClasses = function () {
console.log('abc88 block db getClasses', classes);
return classes;
};
export interface BlockDB extends DiagramDB {

View File

@ -25,7 +25,7 @@ import { configureSvgSize } from '../../setupGraphViewbox.js';
* @returns {object} ClassDef styles
*/
export const getClasses = function (text: any, diagObj: any) {
log.info('abc88 Extracting classes', diagObj.db.getClasses());
log.info('Extracting classes', diagObj.db.getClasses());
try {
return diagObj.db.getClasses();
} catch (e) {

View File

@ -34,28 +34,38 @@ export function calculateBlockPosition(columns: number, position: number): Block
return { px, py };
}
function calcBlockSizes(block: Block, db: BlockDB) {
log.debug('calculateSize (start)', block.id, block?.size?.x, block?.size?.width);
const getMaxChildSize = (block: Block) => {
let maxWidth = 0;
let maxHeight = 0;
// 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 };
log.debug('abc88', child.id, width, height, x, y);
if (width > maxWidth) {
maxWidth = width;
}
if (height > maxHeight) {
maxHeight = height;
}
}
return { width: maxWidth, height: maxHeight };
};
function setBlockSizes(block: Block, db: BlockDB, sieblingWidth: number = 0) {
log.debug('calculateSize abc88 (start)', block.id, block?.size?.x, block?.size?.width);
const totalWidth = 0;
const totalHeight = 0;
let maxWidth = 0;
let maxHeight = 0;
if (block.children) {
if (block.children?.length > 0) {
for (const child of block.children) {
calcBlockSizes(child, db);
setBlockSizes(child, db);
}
// 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 };
// log.debug('APA', child.id, width, height, x, y);
if (width > maxWidth) {
maxWidth = width;
}
if (height > maxHeight) {
maxHeight = height;
}
}
const childSize = getMaxChildSize(block);
maxWidth = childSize.width;
maxHeight = childSize.height;
// set width of block to max width of children
for (const child of block.children) {
@ -66,22 +76,10 @@ function calcBlockSizes(block: Block, db: BlockDB) {
child.size.y = 0;
}
}
for (const child of block.children) {
setBlockSizes(child, db, maxWidth);
}
// // 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;
// }
}
if (block.children?.length > 0) {
const columns = block.columns || -1;
const numItems = block.children.length;
@ -92,6 +90,33 @@ function calcBlockSizes(block: Block, db: BlockDB) {
}
const ySize = Math.ceil(numItems / xSize);
let width = xSize * (maxWidth + padding) + padding;
// If maxWidth
if (width < sieblingWidth) {
console.log(
'Detected to small siebling: abc88',
block.id,
'sieblingWidth',
sieblingWidth,
'width',
width
);
width = sieblingWidth;
const childWidth = (sieblingWidth - xSize * padding - padding) / xSize;
log.debug('Size indata abc88', block.id, 'childWidth', childWidth, 'maxWidth', maxWidth);
log.debug('Size indata abc88 xSize', xSize, 'paddiong', padding);
// // set width of block to max width of children
for (const child of block.children) {
if (child.size) {
child.size.width = childWidth;
child.size.height = maxHeight;
child.size.x = 0;
child.size.y = 0;
}
}
}
log.debug(
'(calc)',
block.id,
@ -105,13 +130,14 @@ function calcBlockSizes(block: Block, db: BlockDB) {
);
block.size = {
width: xSize * (maxWidth + padding) + padding,
width,
height: ySize * (maxHeight + padding) + padding,
x: 0,
y: 0,
};
}
log.debug('calculateSize APA (done)', block.id, block?.size?.x, block?.size?.width);
log.debug('calculateSize abc88 (done)', block.id, block?.size?.x, block?.size?.width);
}
function layoutBlocks(block: Block, db: BlockDB) {
@ -240,7 +266,8 @@ export function layout(db: BlockDB) {
if (!root) {
return;
}
calcBlockSizes(root, db);
setBlockSizes(root, db, 0);
layoutBlocks(root, db);
// Position blocks relative to parents
// positionBlock(root, root, db);

View File

@ -225,7 +225,7 @@ statement
nodeStatement
: nodeStatement link node {
yy.getLogger().info('Rule: (nodeStatement link node) ', $1, $2, $3, 'abc88 typestr: ',$2.edgeTypeStr);
yy.getLogger().info('Rule: (nodeStatement link node) ', $1, $2, $3, ' typestr: ',$2.edgeTypeStr);
const edgeData = yy.edgeStrToEdgeData($2.edgeTypeStr)
$$ = [
{id: $1.id, label: $1.label, type:$1.type, directions: $1.directions},
@ -286,7 +286,6 @@ cssClassStatement
styleStatement
: style STYLE_ENTITY_IDS STYLE_DEFINITION_DATA {
console.log('abc88 apply class: id(s): ',$2, ' style class: ', $3);
$$={ type: 'applyStyles', id: $2.trim(), styles: $3.trim() };
}
;

View File

@ -18,7 +18,6 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
if ((vertex?.classes?.length || 0) > 0) {
classStr = (vertex?.classes || []).join(' ');
}
console.log('abc88 vertex.classes styles', block.id, vertex?.styles);
classStr = classStr + ' flowchart-label';
// We create a SVG label, either by delegating to addHtmlLabel or manually
@ -135,7 +134,6 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
// props: vertex.props,
padding: padding ?? (getConfig()?.flowchart?.padding || 0),
};
console.log('abc88 return node', vertex.id, node);
return node;
}
type IOperation = (elem: any, block: any, db: any) => Promise<void>;
@ -210,7 +208,6 @@ export async function insertEdges(
for (const block of blocks) {
if (block.size) {
console.log('abc88 block', block, block.id);
g.setNode(block.id, {
width: block.size.width,
height: block.size.height,
@ -219,7 +216,6 @@ export async function insertEdges(
}
}
console.log('abc88 edges', edges);
for (const edge of edges) {
// elem, e, edge, clusterDb, diagramType, graph;
if (edge.start && edge.end) {
@ -227,8 +223,6 @@ export async function insertEdges(
const startBlock2 = g.node(edge.start);
const endBlock = db.getBlock(edge.end);
const endBlock2 = g.node(edge.end);
console.log('abc88 startBlock', startBlock2);
console.log('abc88 endBlock', endBlock2);
if (startBlock?.size && endBlock?.size) {
const start = startBlock.size;

View File

@ -307,13 +307,12 @@ const getNextPosition = (position, edgeDirection, graphDirection) => {
},
};
portPos.TD = portPos.TB;
log.info('abc88', graphDirection, edgeDirection, position);
return portPos[graphDirection][edgeDirection][position];
// return 'south';
};
const getNextPort = (node, edgeDirection, graphDirection) => {
log.info('getNextPort abc88', { node, edgeDirection, graphDirection });
log.info('getNextPort', { node, edgeDirection, graphDirection });
if (!portPos[node]) {
switch (graphDirection) {
case 'TB':

View File

@ -169,7 +169,7 @@ export const addVertices = function (vert, g, svgId, root, doc, diagObj) {
padding: getConfig().flowchart.padding,
});
log.info('abc88 setNode', {
log.info('setNode', {
labelStyle: styles.labelStyle,
labelType: vertex.labelType,
shape: _shape,

View File

@ -204,7 +204,7 @@ export const createCssStyles = (
cssStyles += `\n:root { --mermaid-alt-font-family: ${config.altFontFamily}}`;
}
console.log('abc88 expr check', !isEmpty(classDefs), classDefs);
console.log('expr check', !isEmpty(classDefs), classDefs);
// classDefs defined in the diagram text
if (!isEmpty(classDefs) && CLASSDEF_DIAGRAMS.includes(graphType)) {