mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-20 15:59:51 +02:00
#3358 Adding db calls from node statements
This commit is contained in:
@@ -58,13 +58,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<pre id="diagram" class="mermaid">
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*] </pre
|
||||
block-beta
|
||||
id</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
flowchart RL
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// import type { BlockDB } from './blockTypes.js';
|
||||
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||
import { BlockConfig } from './blockTypes.js';
|
||||
import { BlockConfig, BlockType, Block, Link } from './blockTypes.js';
|
||||
|
||||
import * as configApi from '../../config.js';
|
||||
// import common from '../common/common.js';
|
||||
@@ -13,47 +13,78 @@ import {
|
||||
// getDiagramTitle,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb.js';
|
||||
import { log } from '../../logger.js';
|
||||
|
||||
// export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0?
|
||||
|
||||
// Initialize the node database for simple lookups
|
||||
let nodeDatabase: Record<string, Node> = {};
|
||||
const blockDatabase: Record<string, Block> = {};
|
||||
|
||||
// Function to get a node by its ID
|
||||
export const getNodeById = (id: string): Node | undefined => {
|
||||
return nodeDatabase[id];
|
||||
};
|
||||
|
||||
// TODO: Convert to generic TreeNode type? Convert to class?
|
||||
export interface Block {
|
||||
ID: string;
|
||||
label?: string;
|
||||
parent?: Block;
|
||||
children?: Block[];
|
||||
columns?: number; // | TBlockColumnsDefaultValue;
|
||||
}
|
||||
|
||||
export interface Link {
|
||||
source: Block;
|
||||
target: Block;
|
||||
}
|
||||
|
||||
let rootBlocks: Block[] = [];
|
||||
let rootBlock = { ID: 'root', children: [] as Block[], columns: -1 };
|
||||
let blocks: Block[] = [];
|
||||
const links: Link[] = [];
|
||||
let rootBlock = { ID: 'root', children: [], columns: -1 } as Block;
|
||||
let currentBlock: Block | undefined;
|
||||
// let rootBlock = { ID: 'root', children: [], columns: -1 } as Block;
|
||||
let currentBlock = rootBlock;
|
||||
|
||||
const clear = (): void => {
|
||||
rootBlocks = [];
|
||||
blocks = [];
|
||||
log.info('Clear called');
|
||||
// rootBlocks = [];
|
||||
blocks = [] as Block[];
|
||||
commonClear();
|
||||
rootBlock = { ID: 'root', children: [], columns: -1 };
|
||||
currentBlock = rootBlock;
|
||||
nodeDatabase = {};
|
||||
blockDatabase[rootBlock.ID] = rootBlock;
|
||||
};
|
||||
|
||||
type IAddBlock = (block: Block) => Block;
|
||||
const addBlock: IAddBlock = (block: Block, parent?: Block): Block => {
|
||||
if (parent) {
|
||||
parent.children ??= [];
|
||||
parent.children.push(block);
|
||||
} else {
|
||||
rootBlocks.push(block);
|
||||
// type IAddBlock = (block: Block) => Block;
|
||||
// const addBlock: IAddBlock = (block: Block, parent?: Block): Block => {
|
||||
// log.info('addBlock', block, parent);
|
||||
// if (parent) {
|
||||
// parent.children ??= [];
|
||||
// parent.children.push(block);
|
||||
// } else {
|
||||
// rootBlock.children.push(block);
|
||||
// }
|
||||
// blocks.push(block);
|
||||
// return block;
|
||||
// };
|
||||
|
||||
type ITypeStr2Type = (typeStr: string) => BlockType;
|
||||
export function typeStr2Type(typeStr: string) {
|
||||
// TODO: add all types
|
||||
switch (typeStr) {
|
||||
case '[]':
|
||||
return 'square';
|
||||
case '()':
|
||||
return 'round';
|
||||
default:
|
||||
return 'square';
|
||||
}
|
||||
blocks.push(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
type IAddBlock = (id: string, label: string, type: BlockType) => Block;
|
||||
// Function to add a node to the database
|
||||
export const addBlock = (id: string, _label?: string, type?: BlockType) => {
|
||||
log.info('addNode called:', id, _label, type);
|
||||
const label = _label || id;
|
||||
const node: Block = {
|
||||
ID: id,
|
||||
label,
|
||||
type: type || 'square',
|
||||
};
|
||||
blockDatabase[node.ID] = node;
|
||||
currentBlock.children ??= [];
|
||||
currentBlock.children.push(node);
|
||||
return node;
|
||||
};
|
||||
|
||||
type IAddLink = (link: Link) => Link;
|
||||
@@ -84,16 +115,21 @@ const getBlock = (id: string, blocks: Block[]): Block | undefined => {
|
||||
|
||||
type IGetColumns = (blockID: string) => number;
|
||||
const getColumns = (blockID: string): number => {
|
||||
const blocks = [rootBlock];
|
||||
const block = getBlock(blockID, blocks);
|
||||
const block = blockDatabase[blockID];
|
||||
if (!block) {
|
||||
return -1;
|
||||
}
|
||||
return block.columns || -1;
|
||||
if (block.columns) {
|
||||
return block.columns;
|
||||
}
|
||||
if (!block.children) {
|
||||
return -1;
|
||||
}
|
||||
return block.children.length;
|
||||
};
|
||||
|
||||
type IGetBlocks = () => Block[];
|
||||
const getBlocks: IGetBlocks = () => blocks;
|
||||
const getBlocks: IGetBlocks = () => rootBlock.children || [];
|
||||
|
||||
type IGetLinks = () => Link[];
|
||||
const getLinks: IGetLinks = () => links;
|
||||
@@ -111,12 +147,14 @@ export interface BlockDB extends DiagramDB {
|
||||
getLinks: IGetLinks;
|
||||
setColumns: ISetColumns;
|
||||
getColumns: IGetColumns;
|
||||
typeStr2Type: ITypeStr2Type;
|
||||
}
|
||||
|
||||
const db: BlockDB = {
|
||||
getConfig: () => configApi.getConfig().block,
|
||||
addBlock: addBlock,
|
||||
addLink: addLink,
|
||||
typeStr2Type: typeStr2Type,
|
||||
getLogger, // TODO: remove
|
||||
getBlocks,
|
||||
getLinks,
|
||||
|
@@ -3,3 +3,36 @@ import type { BaseDiagramConfig } from '../../config.type.js';
|
||||
export interface BlockConfig extends BaseDiagramConfig {
|
||||
padding?: number;
|
||||
}
|
||||
|
||||
export type BlockType =
|
||||
| 'round'
|
||||
| 'square'
|
||||
| 'diamond'
|
||||
| 'hexagon'
|
||||
| 'odd'
|
||||
| 'lean_right'
|
||||
| 'lean_left'
|
||||
| 'trapezoid'
|
||||
| 'inv_trapezoid'
|
||||
| 'odd_right'
|
||||
| 'circle'
|
||||
| 'ellipse'
|
||||
| 'stadium'
|
||||
| 'subroutine'
|
||||
| 'cylinder'
|
||||
| 'group'
|
||||
| 'doublecircle';
|
||||
|
||||
export interface Block {
|
||||
ID: string;
|
||||
label?: string;
|
||||
parent?: Block;
|
||||
type?: BlockType;
|
||||
children?: Block[];
|
||||
columns?: number; // | TBlockColumnsDefaultValue;
|
||||
}
|
||||
|
||||
export interface Link {
|
||||
source: Block;
|
||||
target: Block;
|
||||
}
|
||||
|
@@ -177,8 +177,8 @@ statement
|
||||
;
|
||||
|
||||
nodeStatement
|
||||
: nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');}
|
||||
| node { yy.getLogger().info('Rule: nodeStatement (node) ', $1);}
|
||||
: nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id);}
|
||||
| node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); }
|
||||
;
|
||||
|
||||
columnsStatement
|
||||
@@ -192,16 +192,16 @@ blockStatement
|
||||
|
||||
node
|
||||
: NODE_ID
|
||||
{ yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); }
|
||||
{ yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; }
|
||||
|NODE_ID nodeShapeNLabel
|
||||
{ yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); }
|
||||
{ yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); $$ = { id: $1, label: $2.label, typeStr: $2.typeStr };}
|
||||
// |nodeShapeNLabel seperator
|
||||
// { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); }
|
||||
;
|
||||
|
||||
nodeShapeNLabel
|
||||
: NODE_DSTART STR NODE_DEND
|
||||
{ yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { type: $1 + $3, descr: $2 }; }
|
||||
{ yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
@@ -3,8 +3,7 @@ import block from './block.jison';
|
||||
import db from '../blockDB.js';
|
||||
import { cleanupComments } from '../../../diagram-api/comments.js';
|
||||
import { prepareTextForParsing } from '../blockUtils.js';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { setConfig } from '../../../config.js';
|
||||
|
||||
describe('Block diagram', function () {
|
||||
describe('when parsing an block diagram graph it should handle > ', function () {
|
||||
@@ -20,6 +19,22 @@ describe('Block diagram', function () {
|
||||
`;
|
||||
|
||||
block.parse(str);
|
||||
const blocks = db.getBlocks();
|
||||
expect(blocks.length).toBe(1);
|
||||
expect(blocks[0].ID).toBe('id');
|
||||
expect(blocks[0].label).toBe('id');
|
||||
});
|
||||
it('a node with a square shape and a label', async () => {
|
||||
const str = `block-beta
|
||||
id["A label"]
|
||||
`;
|
||||
|
||||
block.parse(str);
|
||||
const blocks = db.getBlocks();
|
||||
expect(blocks.length).toBe(1);
|
||||
expect(blocks[0].ID).toBe('id');
|
||||
expect(blocks[0].label).toBe('A label');
|
||||
expect(blocks[0].type).toBe('square');
|
||||
});
|
||||
it('a diagram with multiple nodes', async () => {
|
||||
const str = `block-beta
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import flowDb from '../flowDb.js';
|
||||
import flow from './flow.jison';
|
||||
import { setConfig } from '../../../config.js';
|
||||
import { cleanupComments } from '../../../diagram-api/comments.js';
|
||||
import { setConfig } from '../../../config.js';
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
|
Reference in New Issue
Block a user