From aa7f5a83879df60ff2316149ae80f179cac20d97 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Fri, 1 Sep 2023 14:06:13 +0200 Subject: [PATCH] before refactoring --- .../mermaid/src/diagrams/block/blockDB.ts | 65 +++++++++++----- .../mermaid/src/diagrams/block/blockTypes.ts | 7 +- .../src/diagrams/block/parser/block.jison | 15 ++-- .../src/diagrams/block/parser/block.spec.ts | 76 ++++++++++++++++++- 4 files changed, 132 insertions(+), 31 deletions(-) diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index bec5c33c3..2ef204430 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -21,17 +21,19 @@ import { log } from '../../logger.js'; let nodeDatabase: Record = {}; const blockDatabase: Record = {}; -// Function to get a node by its ID -export const getNodeById = (id: string): Node | undefined => { - return nodeDatabase[id]; +// Function to get a node by its id +type IGetNodeById = (id: string) => Block | undefined; +export const getNodeById = (id: string): Block | undefined => { + console.log(id, nodeDatabase); + return blockDatabase[id]; }; // TODO: Convert to generic TreeNode type? Convert to class? -let rootBlock = { ID: 'root', children: [] as Block[], columns: -1 }; +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 rootBlock = { id: 'root', children: [], columns: -1 } as Block; let currentBlock = rootBlock; const clear = (): void => { @@ -39,10 +41,10 @@ const clear = (): void => { // rootBlocks = []; blocks = [] as Block[]; commonClear(); - rootBlock = { ID: 'root', children: [], columns: -1 }; + rootBlock = { id: 'root', children: [], columns: -1 }; currentBlock = rootBlock; nodeDatabase = {}; - blockDatabase[rootBlock.ID] = rootBlock; + blockDatabase[rootBlock.id] = rootBlock; }; // type IAddBlock = (block: Block) => Block; @@ -71,22 +73,39 @@ export function typeStr2Type(typeStr: string) { } } -type IAddBlock = (id: string, label: string, type: BlockType) => Block; +let cnt = 0; +export const generateId = () => { + cnt++; + return 'id-' + Math.random().toString(36).substr(2, 12) + '-' + cnt; +}; + +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); +export const addBlock = (_id: string, _label?: string, type?: BlockType) => { + let id = _id; + if (!_id) { + id = generateId(); + } const label = _label || id; const node: Block = { - ID: id, + id: id, label, type: type || 'square', + children: [], }; - blockDatabase[node.ID] = node; - currentBlock.children ??= []; - currentBlock.children.push(node); + blockDatabase[node.id] = node; + // currentBlock.children ??= []; + // currentBlock.children.push(node); + // console.log('currentBlock', currentBlock.children, nodeDatabase); + console.log('addNode called:', id, label, type, node); return node; }; +type ISetHierarchy = (block: Block[]) => void; +const setHierarchy = (block: Block[]): void => { + blocks = block; +}; + type IAddLink = (link: Link) => Link; const addLink: IAddLink = (link: Link): Link => { links.push(link); @@ -101,7 +120,7 @@ const setColumns = (columnsStr: string): void => { const getBlock = (id: string, blocks: Block[]): Block | undefined => { for (const block of blocks) { - if (block.ID === id) { + if (block.id === id) { return block; } if (block.children) { @@ -113,9 +132,9 @@ const getBlock = (id: string, blocks: Block[]): Block | undefined => { } }; -type IGetColumns = (blockID: string) => number; -const getColumns = (blockID: string): number => { - const block = blockDatabase[blockID]; +type IGetColumns = (blockid: string) => number; +const getColumns = (blockid: string): number => { + const block = blockDatabase[blockid]; if (!block) { return -1; } @@ -129,7 +148,11 @@ const getColumns = (blockID: string): number => { }; type IGetBlocks = () => Block[]; -const getBlocks: IGetBlocks = () => rootBlock.children || []; +const getBlocks: IGetBlocks = () => { + // console.log('Block in test', rootBlock.children || []); + console.log('Block in test', blocks, blocks[0].id); + return blocks || []; +}; type IGetLinks = () => Link[]; const getLinks: IGetLinks = () => links; @@ -148,6 +171,8 @@ export interface BlockDB extends DiagramDB { setColumns: ISetColumns; getColumns: IGetColumns; typeStr2Type: ITypeStr2Type; + setHierarchy: ISetHierarchy; + getNodeById: IGetNodeById; } const db: BlockDB = { @@ -158,6 +183,8 @@ const db: BlockDB = { getLogger, // TODO: remove getBlocks, getLinks, + setHierarchy, + getNodeById, // getAccTitle, // setAccTitle, // getAccDescription, diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts index b373d6b9c..4afbe4351 100644 --- a/packages/mermaid/src/diagrams/block/blockTypes.ts +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts @@ -21,14 +21,15 @@ export type BlockType = | 'subroutine' | 'cylinder' | 'group' - | 'doublecircle'; + | 'doublecircle' + | 'composite'; export interface Block { - ID: string; + id: string; label?: string; parent?: Block; type?: BlockType; - children?: Block[]; + children: Block[]; columns?: number; // | TBlockColumnsDefaultValue; } diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison index 9422d8ee3..309dbfdea 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.jison +++ b/packages/mermaid/src/diagrams/block/parser/block.jison @@ -137,7 +137,9 @@ seperator {yy.getLogger().info('Rule: seperator (EOF) ');} ; -start: BLOCK_DIAGRAM_KEY document EOF; +start: BLOCK_DIAGRAM_KEY document EOF + {console.log('This is the hierarchy ', JSON.stringify($2, null, 2)); yy.setHierarchy($2); } + ; stop @@ -148,9 +150,10 @@ stop | stop EOF {yy.getLogger().info('Stop EOF2 ');} ; +//array of statements document - : statement { yy.getLogger().info("Rule: statement: ", $1);} - | statement document { yy.getLogger().info("Rule: document statement: ", $1);} + : statement { yy.getLogger().info("Rule: statement: ", $1); $$ = [$1]; } + | statement document { yy.getLogger().info("Rule: document statement: ", $1, $2); $$ = [$1].concat($2); } ; link @@ -177,8 +180,8 @@ statement ; nodeStatement - : 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)); } + : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id); $$ = {id: $1.id}; } + | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); $$ = {id: $1.id}; } ; columnsStatement @@ -186,7 +189,7 @@ columnsStatement ; blockStatement - : block document end { yy.getLogger().info('Rule: blockStatement : ', $1); } + : block document end { console.log('Rule: blockStatement : ', $1, $2, $3); const block = yy.addBlock(undefined, undefined, 'composite'); $$ = { id: block.id, children: $2 }; } ; diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts index ded6db468..584a817b5 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -43,7 +43,14 @@ describe('Block diagram', function () { `; block.parse(str); - // Todo: DB check that the we have two nodes and that the root block has two columns + const blocks = db.getBlocks(); + expect(blocks.length).toBe(2); + expect(blocks[0].ID).toBe('id1'); + expect(blocks[0].label).toBe('id1'); + expect(blocks[0].type).toBe('square'); + expect(blocks[1].ID).toBe('id2'); + expect(blocks[1].label).toBe('id2'); + expect(blocks[1].type).toBe('square'); }); it('a diagram with multiple nodes', async () => { const str = `block-beta @@ -53,7 +60,17 @@ describe('Block diagram', function () { `; block.parse(str); - // Todo: DB check that the we have two nodes and that the root block has three columns + const blocks = db.getBlocks(); + expect(blocks.length).toBe(3); + expect(blocks[0].ID).toBe('id1'); + expect(blocks[0].label).toBe('id1'); + expect(blocks[0].type).toBe('square'); + expect(blocks[1].ID).toBe('id2'); + expect(blocks[1].label).toBe('id2'); + expect(blocks[1].type).toBe('square'); + expect(blocks[2].ID).toBe('id3'); + expect(blocks[2].label).toBe('id3'); + expect(blocks[2].type).toBe('square'); }); it('a node with a square shape and a label', async () => { @@ -62,6 +79,14 @@ describe('Block diagram', function () { id2`; block.parse(str); + const blocks = db.getBlocks(); + expect(blocks.length).toBe(2); + expect(blocks[0].ID).toBe('id'); + expect(blocks[0].label).toBe('A label'); + expect(blocks[0].type).toBe('square'); + expect(blocks[1].ID).toBe('id2'); + expect(blocks[1].label).toBe('id2'); + expect(blocks[1].type).toBe('square'); }); it('a diagram with multiple nodes with edges', async () => { const str = `block-beta @@ -124,14 +149,59 @@ describe('Block diagram', function () { // Todo: DB check that the we have two blocks and that the root block has one column }); - it('compound blocks', async () => { + it('compound blocks 2', async () => { const str = `block-beta block aBlock["Block"] + bBlock["Block"] end `; block.parse(str); + const blocks = db.getBlocks(); + console.log('blocks', blocks); + expect(blocks.length).toBe(1); + expect(blocks[0].children.length).toBe(2); + expect(blocks[0].id).toBe('id'); + expect(blocks[0].label).toBe('A label'); + expect(blocks[0].type).toBe('square'); + // expect(blocks[1].ID).toBe('id2'); + // expect(blocks[1].label).toBe('id2'); + // expect(blocks[1].type).toBe('square'); + }); + it.only('compound blocks', async () => { + const str = `block-beta + block + aBlock["ABlock"] + block + bBlock["BBlock"] + end + end + `; + + block.parse(str); + const blocks = db.getBlocks(); + + const aBlockPos = blocks[0].children[0]; + const bBlockPos = blocks[0].children[1].children[0]; + + const root = db.getNodeById(blocks[0].id); + expect(blocks.length).toBe(1); + expect(blocks[0].id).not.toBe(undefined); + expect(root?.label).toBe(blocks[0].id); + expect(blocks[0].children.length).toBe(2); + expect(root?.type).toBe('composite'); + + const aBlock = db.getNodeById(aBlockPos.id); + console.log('aBlock', aBlock); + expect(aBlock?.label).toBe('ABlock'); + expect(aBlock?.type).toBe('square'); + + const bBlock = db.getNodeById(bBlockPos.id); + + expect(bBlock.id).toBe('bBlock'); + expect(bBlock.label).toBe('BBlock'); + expect(bBlock.type).toBe('square'); }); it.skip('compound blocks with title', async () => { const str = `block