mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-31 10:54:15 +01:00 
			
		
		
		
	#3358 Fix for layout where a siebling has wider siize
This commit is contained in:
		| @@ -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 | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -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")] | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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() }; | ||||
|         } | ||||
|     ; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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': | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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)) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Knut Sveidqvist
					Knut Sveidqvist