#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> </style>
</head> </head>
<body> <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"> <pre id="diagram" class="mermaid2">
block-beta block-beta
A["square"] A["square"]
@@ -78,7 +124,7 @@ block-beta
block-beta block-beta
A(["stadium"]) A(["stadium"])
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
block-beta block-beta
%% A[["subroutine"]] %% A[["subroutine"]]
%% B[("cylinder")] %% B[("cylinder")]

View File

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

View File

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

View File

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

View File

@@ -225,7 +225,7 @@ statement
nodeStatement nodeStatement
: nodeStatement link node { : 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) const edgeData = yy.edgeStrToEdgeData($2.edgeTypeStr)
$$ = [ $$ = [
{id: $1.id, label: $1.label, type:$1.type, directions: $1.directions}, {id: $1.id, label: $1.label, type:$1.type, directions: $1.directions},
@@ -286,7 +286,6 @@ cssClassStatement
styleStatement styleStatement
: style STYLE_ENTITY_IDS STYLE_DEFINITION_DATA { : 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() }; $$={ 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) { if ((vertex?.classes?.length || 0) > 0) {
classStr = (vertex?.classes || []).join(' '); classStr = (vertex?.classes || []).join(' ');
} }
console.log('abc88 vertex.classes styles', block.id, vertex?.styles);
classStr = classStr + ' flowchart-label'; classStr = classStr + ' flowchart-label';
// We create a SVG label, either by delegating to addHtmlLabel or manually // 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, // props: vertex.props,
padding: padding ?? (getConfig()?.flowchart?.padding || 0), padding: padding ?? (getConfig()?.flowchart?.padding || 0),
}; };
console.log('abc88 return node', vertex.id, node);
return node; return node;
} }
type IOperation = (elem: any, block: any, db: any) => Promise<void>; type IOperation = (elem: any, block: any, db: any) => Promise<void>;
@@ -210,7 +208,6 @@ export async function insertEdges(
for (const block of blocks) { for (const block of blocks) {
if (block.size) { if (block.size) {
console.log('abc88 block', block, block.id);
g.setNode(block.id, { g.setNode(block.id, {
width: block.size.width, width: block.size.width,
height: block.size.height, height: block.size.height,
@@ -219,7 +216,6 @@ export async function insertEdges(
} }
} }
console.log('abc88 edges', edges);
for (const edge of edges) { for (const edge of edges) {
// elem, e, edge, clusterDb, diagramType, graph; // elem, e, edge, clusterDb, diagramType, graph;
if (edge.start && edge.end) { if (edge.start && edge.end) {
@@ -227,8 +223,6 @@ export async function insertEdges(
const startBlock2 = g.node(edge.start); const startBlock2 = g.node(edge.start);
const endBlock = db.getBlock(edge.end); const endBlock = db.getBlock(edge.end);
const endBlock2 = g.node(edge.end); const endBlock2 = g.node(edge.end);
console.log('abc88 startBlock', startBlock2);
console.log('abc88 endBlock', endBlock2);
if (startBlock?.size && endBlock?.size) { if (startBlock?.size && endBlock?.size) {
const start = startBlock.size; const start = startBlock.size;

View File

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

View File

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

View File

@@ -204,7 +204,7 @@ export const createCssStyles = (
cssStyles += `\n:root { --mermaid-alt-font-family: ${config.altFontFamily}}`; 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 // classDefs defined in the diagram text
if (!isEmpty(classDefs) && CLASSDEF_DIAGRAMS.includes(graphType)) { if (!isEmpty(classDefs) && CLASSDEF_DIAGRAMS.includes(graphType)) {