mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-21 16:29:40 +02:00
#3358 Some fixes
This commit is contained in:
@@ -65,7 +65,7 @@
|
||||
<body>
|
||||
<pre id="diagram" class="mermaid">
|
||||
block-beta
|
||||
blockArrowId<["Label"]>(right)
|
||||
blockArrowId<["`Label`"]>(right)
|
||||
blockArrowId2<["Label"]>(left)
|
||||
blockArrowId3<["Label"]>(up)
|
||||
blockArrowId4<["Label"]>(down)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||
import type { BlockConfig, BlockType, Block, Link, ClassDef } from './blockTypes.js';
|
||||
import type { BlockConfig, BlockType, Block, ClassDef } from './blockTypes.js';
|
||||
import * as configApi from '../../config.js';
|
||||
import { clear as commonClear } from '../common/commonDb.js';
|
||||
import { log } from '../../logger.js';
|
||||
@@ -240,11 +240,6 @@ const setHierarchy = (block: Block[]): void => {
|
||||
blocks = rootBlock.children;
|
||||
};
|
||||
|
||||
const addLink = (link: Link): Link => {
|
||||
links.push(link);
|
||||
return link;
|
||||
};
|
||||
|
||||
const getColumns = (blockid: string): number => {
|
||||
const block = blockDatabase[blockid];
|
||||
if (!block) {
|
||||
@@ -264,13 +259,6 @@ const getColumns = (blockid: string): number => {
|
||||
* @returns
|
||||
*/
|
||||
const getBlocksFlat = () => {
|
||||
// const result: Block[] = [];
|
||||
// // log.debug('abc88 getBlocksFlat', blockDatabase);
|
||||
// const keys = Object.keys(blockDatabase);
|
||||
// for (const key of keys) {
|
||||
// result.push(blockDatabase[key]);
|
||||
// }
|
||||
// return result;
|
||||
return [...Object.values(blockDatabase)];
|
||||
};
|
||||
/**
|
||||
@@ -292,11 +280,8 @@ const setBlock = (block: Block) => {
|
||||
blockDatabase[block.id] = block;
|
||||
};
|
||||
|
||||
const getLinks = () => links;
|
||||
|
||||
const getLogger = () => console;
|
||||
|
||||
// type IGetClasses = () => Record<string, ClassDef>;
|
||||
/**
|
||||
* Return all of the style classes
|
||||
*/
|
||||
@@ -306,15 +291,13 @@ export const getClasses = function () {
|
||||
|
||||
const db = {
|
||||
getConfig: () => configApi.getConfig().block,
|
||||
addLink: addLink,
|
||||
typeStr2Type: typeStr2Type,
|
||||
edgeTypeStr2Type: edgeTypeStr2Type,
|
||||
edgeStrToEdgeData,
|
||||
getLogger, // TODO: remove
|
||||
getLogger,
|
||||
getBlocksFlat,
|
||||
getBlocks,
|
||||
getEdges,
|
||||
getLinks,
|
||||
setHierarchy,
|
||||
getBlock,
|
||||
setBlock,
|
||||
|
@@ -2,19 +2,17 @@ import type { Diagram } from '../../Diagram.js';
|
||||
import * as configApi from '../../config.js';
|
||||
import { calculateBlockSizes, insertBlocks, insertEdges } from './renderHelpers.js';
|
||||
import { layout } from './layout.js';
|
||||
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
|
||||
import type { MermaidConfig, BaseDiagramConfig } from '../../config.type.js';
|
||||
import insertMarkers from '../../dagre-wrapper/markers.js';
|
||||
import {
|
||||
select as d3select,
|
||||
scaleOrdinal as d3scaleOrdinal,
|
||||
schemeTableau10 as d3schemeTableau10,
|
||||
} from 'd3';
|
||||
import type { ContainerElement } from 'd3';
|
||||
import { log } from '../../logger.js';
|
||||
|
||||
import type { BlockDB } from './blockDB.js';
|
||||
import type { Block } from './blockTypes.js';
|
||||
|
||||
// import { diagram as BlockDiagram } from './blockDiagram.js';
|
||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||
|
||||
/**
|
||||
@@ -34,7 +32,7 @@ export const draw = async function (
|
||||
_version: string,
|
||||
diagObj: Diagram
|
||||
): Promise<void> {
|
||||
const { securityLevel, flowchart: conf } = configApi.getConfig();
|
||||
const { securityLevel, block: conf } = configApi.getConfig();
|
||||
const db = diagObj.db as BlockDB;
|
||||
let sandboxElement: any;
|
||||
if (securityLevel === 'sandbox') {
|
||||
@@ -65,7 +63,6 @@ export const draw = async function (
|
||||
const nodes = svg.insert('g').attr('class', 'block');
|
||||
await calculateBlockSizes(nodes, bl, db);
|
||||
const bounds = layout(db);
|
||||
// log.debug('Here be blocks', bl);
|
||||
await insertBlocks(nodes, bl, db);
|
||||
await insertEdges(nodes, edges, blArr, db, id);
|
||||
|
||||
@@ -80,32 +77,14 @@ export const draw = async function (
|
||||
const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
|
||||
const height = bounds2.height + magicFactor + 10;
|
||||
const width = bounds2.width + 10;
|
||||
const useMaxWidth = false;
|
||||
configureSvgSize(svg, height, width, useMaxWidth);
|
||||
const { useMaxWidth } = conf as Exclude<MermaidConfig['block'], undefined>;
|
||||
configureSvgSize(svg, height, width, !!useMaxWidth);
|
||||
log.debug('Here Bounds', bounds, bounds2);
|
||||
svg.attr(
|
||||
'viewBox',
|
||||
`${bounds2.x - 5} ${bounds2.y - 5} ${bounds2.width + 10} ${bounds2.height + 10}`
|
||||
);
|
||||
}
|
||||
// svg.attr('viewBox', `${-200} ${-200} ${400} ${400}`);
|
||||
|
||||
// Prepare data for construction based on diagObj.db
|
||||
// This must be a mutable object with `nodes` and `links` properties:
|
||||
//
|
||||
// @ts-ignore TODO: db type
|
||||
// const graph = diagObj.db.getGraph();
|
||||
|
||||
// const nodeWidth = 10;
|
||||
|
||||
// Create rectangles for nodes
|
||||
// const db:BlockDB = diagObj.db;
|
||||
|
||||
interface LayedBlock extends Block {
|
||||
children?: LayedBlock[];
|
||||
x?: number;
|
||||
y?: number;
|
||||
}
|
||||
|
||||
// Get color scheme for the graph
|
||||
const colorScheme = d3scaleOrdinal(d3schemeTableau10);
|
||||
|
@@ -56,12 +56,7 @@ export interface Block {
|
||||
styleClass?: string;
|
||||
styles?: string[];
|
||||
stylesStr?: string;
|
||||
w?: number;
|
||||
}
|
||||
|
||||
export interface Link {
|
||||
source: Block;
|
||||
target: Block;
|
||||
widthInColumns?: number;
|
||||
}
|
||||
|
||||
export interface ClassDef {
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import type { BlockDB } from './blockDB.js';
|
||||
import type { Block } from './blockTypes.js';
|
||||
import { log } from '../../logger.js';
|
||||
const padding = 8;
|
||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
||||
const padding = getConfig()?.block?.padding || 8;
|
||||
|
||||
interface BlockPosition {
|
||||
px: number;
|
||||
@@ -59,7 +60,7 @@ const getMaxChildSize = (block: Block) => {
|
||||
continue;
|
||||
}
|
||||
if (width > maxWidth) {
|
||||
maxWidth = width / (block.w || 1);
|
||||
maxWidth = width / (block.widthInColumns || 1);
|
||||
}
|
||||
if (height > maxHeight) {
|
||||
maxHeight = height;
|
||||
@@ -68,7 +69,7 @@ const getMaxChildSize = (block: Block) => {
|
||||
return { width: maxWidth, height: maxHeight };
|
||||
};
|
||||
|
||||
function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHeight = 0) {
|
||||
function setBlockSizes(block: Block, db: BlockDB, siblingWidth = 0, siblingHeight = 0) {
|
||||
log.debug(
|
||||
'setBlockSizes abc95 (start)',
|
||||
block.id,
|
||||
@@ -76,18 +77,16 @@ function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHei
|
||||
'block width =',
|
||||
block?.size,
|
||||
'sieblingWidth',
|
||||
sieblingWidth
|
||||
siblingWidth
|
||||
);
|
||||
if (!block?.size?.width) {
|
||||
block.size = {
|
||||
width: sieblingWidth,
|
||||
height: sieblingHeight,
|
||||
width: siblingWidth,
|
||||
height: siblingHeight,
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
}
|
||||
const totalWidth = 0;
|
||||
const totalHeight = 0;
|
||||
let maxWidth = 0;
|
||||
let maxHeight = 0;
|
||||
|
||||
@@ -105,34 +104,21 @@ function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHei
|
||||
for (const child of block.children) {
|
||||
if (child.size) {
|
||||
log.debug(
|
||||
'abc95 Setting size of children of',
|
||||
block.id,
|
||||
'id=',
|
||||
child.id,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
child.size
|
||||
`abc95 Setting size of children of ${block.id} id=${child.id} ${maxWidth} ${maxHeight} ${child.size}`
|
||||
);
|
||||
child.size.width = maxWidth * (child.w || 1) + padding * ((child.w || 1) - 1);
|
||||
child.size.width =
|
||||
maxWidth * (child.widthInColumns || 1) + padding * ((child.widthInColumns || 1) - 1);
|
||||
child.size.height = maxHeight;
|
||||
child.size.x = 0;
|
||||
child.size.y = 0;
|
||||
|
||||
log.debug(
|
||||
'abc95 updating size of ',
|
||||
block.id,
|
||||
' children child:',
|
||||
child.id,
|
||||
'maxWidth:',
|
||||
maxWidth,
|
||||
'maxHeight:',
|
||||
maxHeight
|
||||
`abc95 updating size of ${block.id} children child:${child.id} maxWidth:${maxWidth} maxHeight:${maxHeight}`
|
||||
);
|
||||
}
|
||||
}
|
||||
for (const child of block.children) {
|
||||
// log.debug('abc95 fin 2 Setting size', child.id, maxWidth, maxHeight, child.size);
|
||||
setBlockSizes(child, db, maxWidth, maxHeight);
|
||||
// log.debug('abc95 fin 3 Setting size', child.id, maxWidth, maxHeight, child.size);
|
||||
}
|
||||
|
||||
const columns = block.columns || -1;
|
||||
@@ -144,28 +130,21 @@ function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHei
|
||||
xSize = columns;
|
||||
}
|
||||
|
||||
const w = block.w || 1;
|
||||
const w = block.widthInColumns || 1;
|
||||
|
||||
const ySize = Math.ceil(numItems / xSize);
|
||||
|
||||
let width = xSize * (maxWidth + padding) + padding;
|
||||
let height = ySize * (maxHeight + padding) + padding;
|
||||
// If maxWidth
|
||||
if (width < sieblingWidth) {
|
||||
if (width < siblingWidth) {
|
||||
log.debug(
|
||||
'Detected to small siebling: abc95',
|
||||
block.id,
|
||||
'sieblingWidth',
|
||||
sieblingWidth,
|
||||
'sieblingHeight',
|
||||
sieblingHeight,
|
||||
'width',
|
||||
width
|
||||
`Detected to small siebling: abc95 ${block.id} sieblingWidth ${siblingWidth} sieblingHeight ${siblingHeight} width ${width}`
|
||||
);
|
||||
width = sieblingWidth;
|
||||
height = sieblingHeight;
|
||||
const childWidth = (sieblingWidth - xSize * padding - padding) / xSize;
|
||||
const childHeight = (sieblingHeight - ySize * padding - padding) / ySize;
|
||||
width = siblingWidth;
|
||||
height = siblingHeight;
|
||||
const childWidth = (siblingWidth - xSize * padding - padding) / xSize;
|
||||
const childHeight = (siblingHeight - ySize * padding - padding) / ySize;
|
||||
log.debug('Size indata abc88', block.id, 'childWidth', childWidth, 'maxWidth', maxWidth);
|
||||
log.debug('Size indata abc88', block.id, 'childHeight', childHeight, 'maxHeight', maxHeight);
|
||||
log.debug('Size indata abc88 xSize', xSize, 'paddiong', padding);
|
||||
@@ -182,17 +161,9 @@ function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHei
|
||||
}
|
||||
|
||||
log.debug(
|
||||
'abc95 (finale calc)',
|
||||
block.id,
|
||||
'xSize',
|
||||
xSize,
|
||||
'ySize',
|
||||
ySize,
|
||||
'columns',
|
||||
columns,
|
||||
block.children.length,
|
||||
'width=',
|
||||
Math.max(width, block.size?.width || 0)
|
||||
`abc95 (finale calc) ${block.id} xSize ${xSize} ySize ${ySize} columns ${columns}${
|
||||
block.children.length
|
||||
} width=${Math.max(width, block.size?.width || 0)}`
|
||||
);
|
||||
if (width < (block?.size?.width || 0)) {
|
||||
width = block?.size?.width || 0;
|
||||
@@ -229,14 +200,7 @@ function setBlockSizes(block: Block, db: BlockDB, sieblingWidth = 0, sieblingHei
|
||||
|
||||
function layoutBlocks(block: Block, db: BlockDB) {
|
||||
log.debug(
|
||||
'abc85 layout blocks (=>layoutBlocks)',
|
||||
block.id,
|
||||
'x:',
|
||||
block?.size?.x,
|
||||
'y:',
|
||||
block?.size?.y,
|
||||
'width:',
|
||||
block?.size?.width
|
||||
`abc85 layout blocks (=>layoutBlocks) ${block.id} x: ${block?.size?.x} y: ${block?.size?.y} width: ${block?.size?.width}`
|
||||
);
|
||||
const columns = block.columns || -1;
|
||||
log.debug('layoutBlocks columns abc95', block.id, '=>', columns, block);
|
||||
@@ -268,56 +232,22 @@ function layoutBlocks(block: Block, db: BlockDB) {
|
||||
log.debug('New row in layout for block', block.id, ' and child ', child.id, rowPos);
|
||||
}
|
||||
log.debug(
|
||||
'abc89 layout blocks (child) id:',
|
||||
child.id,
|
||||
'Pos:',
|
||||
columnPos,
|
||||
' (px, py)',
|
||||
px,
|
||||
py,
|
||||
' (',
|
||||
parent?.size?.x,
|
||||
',',
|
||||
parent?.size?.y,
|
||||
')',
|
||||
'parent:',
|
||||
parent.id,
|
||||
'width:',
|
||||
width,
|
||||
padding
|
||||
`abc89 layout blocks (child) id: ${child.id} Pos: ${columnPos} (px, py) ${px},${py} (${parent?.size?.x},${parent?.size?.y}) parent: ${parent.id} width: ${width}${padding}`
|
||||
);
|
||||
if (parent.size) {
|
||||
// child.size.x =
|
||||
// block.size.x -
|
||||
// block.size.width / 2 +
|
||||
// px * (child?.w || 1) * (width + padding) +
|
||||
// width / 2 +
|
||||
// padding;
|
||||
const halfWidth = width / 2;
|
||||
child.size.x = startingPosX + padding + halfWidth;
|
||||
|
||||
log.debug(
|
||||
'abc91 layout blocks (calc) px, py',
|
||||
'id:',
|
||||
child.id,
|
||||
'startingPosX',
|
||||
startingPosX,
|
||||
'new startingPosX',
|
||||
child.size.x + halfWidth,
|
||||
'padding',
|
||||
padding,
|
||||
'width=',
|
||||
width,
|
||||
'halfWidth',
|
||||
halfWidth,
|
||||
'=>',
|
||||
'x:',
|
||||
child.size.x,
|
||||
'y:',
|
||||
child.size.y,
|
||||
child.w,
|
||||
'(width * (child?.w || 1)) / 2',
|
||||
(width * (child?.w || 1)) / 2
|
||||
`abc91 layout blocks (calc) px, pyid:${
|
||||
child.id
|
||||
} startingPos=X${startingPosX} new startingPosX${
|
||||
child.size.x
|
||||
} ${halfWidth} padding=${padding} width=${width} halfWidth=${halfWidth} => x:${
|
||||
child.size.x
|
||||
} y:${child.size.y} ${child.widthInColumns} (width * (child?.w || 1)) / 2 ${
|
||||
(width * (child?.widthInColumns || 1)) / 2
|
||||
}`
|
||||
);
|
||||
|
||||
startingPosX = child.size.x + halfWidth;
|
||||
@@ -326,21 +256,11 @@ function layoutBlocks(block: Block, db: BlockDB) {
|
||||
parent.size.y - parent.size.height / 2 + py * (height + padding) + height / 2 + padding;
|
||||
|
||||
log.debug(
|
||||
'abc88 layout blocks (calc) px, py',
|
||||
'id:',
|
||||
child.id,
|
||||
'startingPosX',
|
||||
startingPosX,
|
||||
padding,
|
||||
halfWidth,
|
||||
'=>',
|
||||
'x:',
|
||||
child.size.x,
|
||||
'y:',
|
||||
child.size.y,
|
||||
child.w,
|
||||
'(width * (child?.w || 1)) / 2',
|
||||
(width * (child?.w || 1)) / 2
|
||||
`abc88 layout blocks (calc) px, pyid:${
|
||||
child.id
|
||||
}startingPosX${startingPosX}${padding}${halfWidth}=>x:${child.size.x}y:${child.size.y}${
|
||||
child.widthInColumns
|
||||
}(width * (child?.w || 1)) / 2${(width * (child?.widthInColumns || 1)) / 2}`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -348,19 +268,12 @@ function layoutBlocks(block: Block, db: BlockDB) {
|
||||
if (child.children) {
|
||||
layoutBlocks(child, db);
|
||||
}
|
||||
columnPos += child?.w || 1;
|
||||
columnPos += child?.widthInColumns || 1;
|
||||
log.debug('abc88 columnsPos', child, columnPos);
|
||||
}
|
||||
}
|
||||
log.debug(
|
||||
'layout blocks (<==layoutBlocks)',
|
||||
block.id,
|
||||
'x:',
|
||||
block?.size?.x,
|
||||
'y:',
|
||||
block?.size?.y,
|
||||
'width:',
|
||||
block?.size?.width
|
||||
`layout blocks (<==layoutBlocks) ${block.id} x: ${block?.size?.x} y: ${block?.size?.y} width: ${block?.size?.width}`
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -79,12 +79,7 @@ accDescr\s*":"\s* { this.pushState
|
||||
accDescr\s*"{"\s* { this.pushState("acc_descr_multiline");}
|
||||
<acc_descr_multiline>[\}] { this.popState(); }
|
||||
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
|
||||
"subgraph" return 'subgraph';
|
||||
"end"\b\s* return 'end';
|
||||
.*direction\s+TB[^\n]* return 'direction_tb';
|
||||
.*direction\s+BT[^\n]* return 'direction_bt';
|
||||
.*direction\s+RL[^\n]* return 'direction_rl';
|
||||
.*direction\s+LR[^\n]* return 'direction_lr';
|
||||
|
||||
|
||||
// Node end of shape
|
||||
<NODE>"(((" { this.popState();yy.getLogger().debug('Lex: (('); return "NODE_DEND"; }
|
||||
|
@@ -353,7 +353,7 @@ describe('Block diagram', function () {
|
||||
expect(blocks.length).toBe(2);
|
||||
const one = blocks[0];
|
||||
const two = blocks[1];
|
||||
expect(two.w).toBe(2);
|
||||
expect(two.widthInColumns).toBe(2);
|
||||
});
|
||||
it('empty blocks', async () => {
|
||||
const str = `block-beta
|
||||
|
@@ -130,7 +130,11 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
|
||||
return node;
|
||||
}
|
||||
type IOperation = (elem: any, block: any, db: any) => Promise<void>;
|
||||
async function calculateBlockSize(elem: any, block: any, db: any) {
|
||||
async function calculateBlockSize(
|
||||
elem: d3.Selection<SVGGElement, unknown, HTMLElement, any>,
|
||||
block: any,
|
||||
db: any
|
||||
) {
|
||||
const node = getNodeFromBlock(block, db, false);
|
||||
if (node.type === 'group') {
|
||||
return;
|
||||
@@ -147,9 +151,6 @@ async function calculateBlockSize(elem: any, block: any, db: any) {
|
||||
|
||||
export async function insertBlockPositioned(elem: any, block: Block, db: any) {
|
||||
const node = getNodeFromBlock(block, db, true);
|
||||
// if (node.type === 'composite') {
|
||||
// return;
|
||||
// }
|
||||
// Add the element to the DOM to size it
|
||||
const obj = db.getBlock(node.id);
|
||||
if (obj.type !== 'space') {
|
||||
@@ -160,7 +161,7 @@ export async function insertBlockPositioned(elem: any, block: Block, db: any) {
|
||||
}
|
||||
|
||||
export async function performOperations(
|
||||
elem: ContainerElement,
|
||||
elem: d3.Selection<SVGGElement, unknown, HTMLElement, any>,
|
||||
blocks: Block[],
|
||||
db: BlockDB,
|
||||
operation: IOperation
|
||||
@@ -173,16 +174,20 @@ export async function performOperations(
|
||||
}
|
||||
}
|
||||
|
||||
export async function calculateBlockSizes(elem: ContainerElement, blocks: Block[], db: BlockDB) {
|
||||
export async function calculateBlockSizes(elem: any, blocks: Block[], db: BlockDB) {
|
||||
await performOperations(elem, blocks, db, calculateBlockSize);
|
||||
}
|
||||
|
||||
export async function insertBlocks(elem: ContainerElement, blocks: Block[], db: BlockDB) {
|
||||
export async function insertBlocks(
|
||||
elem: d3.Selection<SVGGElement, unknown, HTMLElement, any>,
|
||||
blocks: Block[],
|
||||
db: BlockDB
|
||||
) {
|
||||
await performOperations(elem, blocks, db, insertBlockPositioned);
|
||||
}
|
||||
|
||||
export async function insertEdges(
|
||||
elem: ContainerElement,
|
||||
elem: any,
|
||||
edges: Block[],
|
||||
blocks: Block[],
|
||||
db: BlockDB,
|
||||
@@ -214,9 +219,7 @@ export async function insertEdges(
|
||||
// elem, e, edge, clusterDb, diagramType, graph;
|
||||
if (edge.start && edge.end) {
|
||||
const startBlock = db.getBlock(edge.start);
|
||||
const startBlock2 = g.node(edge.start);
|
||||
const endBlock = db.getBlock(edge.end);
|
||||
const endBlock2 = g.node(edge.end);
|
||||
|
||||
if (startBlock?.size && endBlock?.size) {
|
||||
const start = startBlock.size;
|
||||
|
Reference in New Issue
Block a user