From ccdb8035012b221317d3804c54f3354c0517989d Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Tue, 5 Sep 2023 15:15:08 +0200 Subject: [PATCH] Rendering, interim --- packages/mermaid/src/dagre-wrapper/nodes.js | 28 +-- .../mermaid/src/dagre-wrapper/shapes/util.js | 3 + .../mermaid/src/diagrams/block/blockDB.ts | 3 - .../src/diagrams/block/blockRenderer.ts | 7 +- packages/mermaid/src/diagrams/block/layout.ts | 5 - .../src/diagrams/block/renderHelpers.ts | 175 ++++-------------- 6 files changed, 61 insertions(+), 160 deletions(-) diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js index e6a9d982a..e9324171b 100644 --- a/packages/mermaid/src/dagre-wrapper/nodes.js +++ b/packages/mermaid/src/dagre-wrapper/nodes.js @@ -323,8 +323,12 @@ const rect = async (parent, node) => { // const totalWidth = bbox.width + node.padding * 2; // const totalHeight = bbox.height + node.padding * 2; - const totalWidth = bbox.width + node.padding; - const totalHeight = bbox.height + node.padding; + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? node.x - node.width / 2 - halfPadding : -bbox.width / 2 - halfPadding; + const y = node.positioned + ? node.y - node.height / 2 - halfPadding + : -bbox.height / 2 - halfPadding; rect .attr('class', 'basic label-container') .attr('style', node.style) @@ -332,8 +336,8 @@ const rect = async (parent, node) => { .attr('ry', node.ry) // .attr('x', -bbox.width / 2 - node.padding) // .attr('y', -bbox.height / 2 - node.padding) - .attr('x', -bbox.width / 2 - halfPadding) - .attr('y', -bbox.height / 2 - halfPadding) + .attr('x', x) + .attr('y', y) .attr('width', totalWidth) .attr('height', totalHeight); @@ -1037,14 +1041,14 @@ export const positionNode = (node) => { const padding = 8; const diff = node.diff || 0; if (node.clusterNode) { - el.attr( - 'transform', - 'translate(' + - (node.x + diff - node.width / 2) + - ', ' + - (node.y - node.height / 2 - padding) + - ')' - ); + el.attr( + 'transform', + 'translate(' + + (node.x + diff - node.width / 2) + + ', ' + + (node.y - node.height / 2 - padding) + + ')' + ); } else { el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')'); } diff --git a/packages/mermaid/src/dagre-wrapper/shapes/util.js b/packages/mermaid/src/dagre-wrapper/shapes/util.js index 3eaedb4b9..2230547ff 100644 --- a/packages/mermaid/src/dagre-wrapper/shapes/util.js +++ b/packages/mermaid/src/dagre-wrapper/shapes/util.js @@ -113,6 +113,9 @@ export const labelHelper = async (parent, node, _classes, isNode) => { label.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')'); } label.insert('rect', ':first-child'); + // if (node.positioned) { + // shapeSvg.attr('transform', 'translate(' + node.x + ', ' + node.y + ')'); + // } return { shapeSvg, bbox, halfPadding, label }; }; diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index 039353830..84c653605 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -103,17 +103,14 @@ const getColumns = (blockid: string): number => { type IGetBlocks = () => Block[]; const getBlocks: IGetBlocks = () => { - log.info('Block in test', blocks, blocks[0].id); return blocks || []; }; type IGetBlock = (id: string) => Block | undefined; const getBlock: IGetBlock = (id: string) => { - log.info('Block in test', blocks, blocks[0].id); return blockDatabase[id]; }; type ISetBlock = (block: Block) => void; const setBlock: ISetBlock = (block: Block) => { - log.info('Block in test', blocks, blocks[0].id); blockDatabase[block.id] = block; }; diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts index 0dac714d4..932537786 100644 --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts @@ -1,6 +1,6 @@ import { Diagram } from '../../Diagram.js'; import * as configApi from '../../config.js'; -import { calculateBlockSizes } from './renderHelpers.js'; +import { calculateBlockSizes, insertBlocks } from './renderHelpers.js'; import { layout } from './layout.js'; import { setupGraphViewbox } from '../../setupGraphViewbox.js'; import { @@ -42,14 +42,15 @@ export const draw = async function ( const nodes = svg.insert('g').attr('class', 'block'); await calculateBlockSizes(nodes, bl, db); const bounds = layout(db); + await insertBlocks(nodes, bl, db); console.log('Here', bl); // Establish svg dimensions and get width and height // // const bounds = nodes.node().getBoundingClientRect(); - const height = bounds.height; - const width = bounds.width; + const height = bounds.height + 600; + const width = bounds.width + 699; const useMaxWidth = false; configureSvgSize(svg, height, width, useMaxWidth); console.log('Here Bounds', bounds); diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts index 65b99c154..2d6100229 100644 --- a/packages/mermaid/src/diagrams/block/layout.ts +++ b/packages/mermaid/src/diagrams/block/layout.ts @@ -42,13 +42,9 @@ function layoutBLock(block: Block, db: BlockDB) { } function positionBlock(block: Block, db: BlockDB) { - console.log('Here Positioning', block?.size?.node); - // const o = db.getBlock(block.id); - // const node; if (block?.size?.node) { const node = block?.size?.node; const size = block?.size; - console.log('Here as well', node); if (node) { node.attr( 'transform', @@ -70,7 +66,6 @@ let maxY = 0; function findBounds(block: Block) { if (block.size) { const { x, y, width, height } = block.size; - console.log('Here', minX, minY, x, y, width, height); if (x - width < minX) { minX = x - width; } diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts index 34d8baa05..1b29b4536 100644 --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts @@ -5,7 +5,7 @@ import { ContainerElement } from 'd3'; import type { Block } from './blockTypes.js'; import { BlockDB } from './blockDB.js'; -function getNodeFromBlock(block: Block, db: BlockDB) { +function getNodeFromBlock(block: Block, db: BlockDB, positioned: boolean = false) { const vertex = block; /** @@ -93,6 +93,7 @@ function getNodeFromBlock(block: Block, db: BlockDB) { // Use vertex id as text in the box if no text is provided by the graph definition const vertexText = vertex.label; + const bounds = vertex.size || { width: 0, height: 0, x: 0, y: 0 }; // Add the node const node = { labelStyle: styles.labelStyle, @@ -111,160 +112,60 @@ function getNodeFromBlock(block: Block, db: BlockDB) { // haveCallback: vertex.haveCallback, // width: vertex.type === 'group' ? 500 : undefined, // dir: vertex.dir, + width: bounds.width, + height: bounds.height, + x: bounds.x, + y: bounds.y, + positioned, type: vertex.type, // props: vertex.props, padding: getConfig()?.flowchart?.padding || 0, }; return node; } - +type IOperation = (elem: any, block: any, db: any) => Promise; async function calculateBlockSize(elem: any, block: any, db: any) { - console.log('Here befoire 3'); - const node = getNodeFromBlock(block, db); + const node = getNodeFromBlock(block, db, false); if (node.type === 'group') return; // Add the element to the DOM to size it const nodeEl = await insertNode(elem, node); const boundingBox = nodeEl.node().getBBox(); const obj = db.getBlock(node.id); - console.log('Here el', nodeEl); obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl }; + console.log('Here boundsíng', boundingBox.width); db.setBlock(obj); - // nodeEl.remove(); + nodeEl.remove(); +} + +export async function insertBlockPositioned(elem: any, block: any, db: any) { + console.log('Here insertBlockPositioned'); + const node = getNodeFromBlock(block, db, true); + if (node.type === 'group') return; + + // Add the element to the DOM to size it + const obj = db.getBlock(node.id); + const nodeEl = await insertNode(elem, node); +} + +export async function performOperations( + elem: ContainerElement, + blocks: Block[], + db: BlockDB, + operation: IOperation +) { + for (const block of blocks) { + await operation(elem, block, db); + if (block.children) { + await performOperations(elem, block.children, db, operation); + } + } } export async function calculateBlockSizes(elem: ContainerElement, blocks: Block[], db: BlockDB) { - console.log('Here before 2'); - for (const block of blocks) { - await calculateBlockSize(elem, block, db); - if (block.children) { - await calculateBlockSizes(elem, block.children, db); - } - } + await performOperations(elem, blocks, db, calculateBlockSize); } -export async function insertBlockPositioned(elem: any, block: any, db: any) { - const vertex = block; - /** - * Variable for storing the classes for the vertex - * - * @type {string} - */ - let classStr = 'default'; - if ((vertex?.classes?.length || []) > 0) { - classStr = vertex.classes.join(' '); - } - classStr = classStr + ' flowchart-label'; - - // We create a SVG label, either by delegating to addHtmlLabel or manually - let vertexNode; - const labelData = { width: 0, height: 0 }; - - let radious = 0; - let _shape = ''; - let layoutOptions = {}; - // Set the shape based parameters - switch (vertex.type) { - case 'round': - radious = 5; - _shape = 'rect'; - break; - case 'square': - _shape = 'rect'; - break; - case 'diamond': - _shape = 'question'; - layoutOptions = { - portConstraints: 'FIXED_SIDE', - }; - break; - case 'hexagon': - _shape = 'hexagon'; - break; - case 'odd': - _shape = 'rect_left_inv_arrow'; - break; - case 'lean_right': - _shape = 'lean_right'; - break; - case 'lean_left': - _shape = 'lean_left'; - break; - case 'trapezoid': - _shape = 'trapezoid'; - break; - case 'inv_trapezoid': - _shape = 'inv_trapezoid'; - break; - case 'odd_right': - _shape = 'rect_left_inv_arrow'; - break; - case 'circle': - _shape = 'circle'; - break; - case 'ellipse': - _shape = 'ellipse'; - break; - case 'stadium': - _shape = 'stadium'; - break; - case 'subroutine': - _shape = 'subroutine'; - break; - case 'cylinder': - _shape = 'cylinder'; - break; - case 'group': - _shape = 'rect'; - break; - case 'doublecircle': - _shape = 'doublecircle'; - break; - default: - _shape = 'rect'; - } - - // const styles = getStylesFromArray(vertex.styles); - const styles = getStylesFromArray([]); - - // Use vertex id as text in the box if no text is provided by the graph definition - const vertexText = vertex.label; - - // Add the node - const node = { - labelStyle: styles.labelStyle, - shape: _shape, - labelText: vertexText, - labelType: vertex.labelType, - rx: radious, - ry: radious, - class: classStr, - style: styles.style, - id: vertex.id, - link: vertex.link, - linkTarget: vertex.linkTarget, - // tooltip: diagObj.db.getTooltip(vertex.id) || '', - // domId: diagObj.db.lookUpDomId(vertex.id), - haveCallback: vertex.haveCallback, - width: vertex.width, - height: vertex.height, - dir: vertex.dir, - type: vertex.type, - props: vertex.props, - padding: getConfig()?.flowchart?.padding || 0, - }; - let boundingBox; - let nodeEl; - - // Add the element to the DOM - if (node.type !== 'group') { - nodeEl = await insertNode(elem, node, vertex.dir); - // nodeEl.remove(); - boundingBox = nodeEl.node().getBBox(); - if (node.id) { - const obj = db.getBlock(node.id); - obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl }; - db.setBlock(obj); - } - } +export async function insertBlocks(elem: ContainerElement, blocks: Block[], db: BlockDB) { + await performOperations(elem, blocks, db, insertBlockPositioned); }