mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-21 06:53:17 +08:00
#3358 First commit with basic grammar and 1st test
This commit is contained in:
parent
f431bae0ba
commit
86e1bb38ee
@ -33,6 +33,7 @@ export interface MermaidConfig {
|
|||||||
gitGraph?: GitGraphDiagramConfig;
|
gitGraph?: GitGraphDiagramConfig;
|
||||||
c4?: C4DiagramConfig;
|
c4?: C4DiagramConfig;
|
||||||
sankey?: SankeyDiagramConfig;
|
sankey?: SankeyDiagramConfig;
|
||||||
|
blockDiagram?: BlockDiagramConfig;
|
||||||
dompurifyConfig?: DOMPurify.Config;
|
dompurifyConfig?: DOMPurify.Config;
|
||||||
wrap?: boolean;
|
wrap?: boolean;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
@ -421,6 +422,9 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig {
|
|||||||
linkColor?: SankeyLinkColor | string;
|
linkColor?: SankeyLinkColor | string;
|
||||||
nodeAlignment?: SankeyNodeAlignment;
|
nodeAlignment?: SankeyNodeAlignment;
|
||||||
}
|
}
|
||||||
|
export interface BlockDiagramConfig extends BaseDiagramConfig {
|
||||||
|
padding?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface FontConfig {
|
export interface FontConfig {
|
||||||
fontSize?: string | number;
|
fontSize?: string | number;
|
||||||
|
35
packages/mermaid/src/diagrams/blockDiagram/blockDB.ts
Normal file
35
packages/mermaid/src/diagrams/blockDiagram/blockDB.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import common from '../common/common.js';
|
||||||
|
import {
|
||||||
|
setAccTitle,
|
||||||
|
getAccTitle,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
|
clear as commonClear,
|
||||||
|
} from '../../commonDb.js';
|
||||||
|
|
||||||
|
type Block = {
|
||||||
|
ID: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Array of nodes guarantees their order
|
||||||
|
let blocks: Block[] = [];
|
||||||
|
|
||||||
|
const clear = (): void => {
|
||||||
|
blocks = [];
|
||||||
|
commonClear();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getConfig: () => configApi.getConfig().blockDiagram,
|
||||||
|
|
||||||
|
getAccTitle,
|
||||||
|
setAccTitle,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
|
getDiagramTitle,
|
||||||
|
setDiagramTitle,
|
||||||
|
clear,
|
||||||
|
};
|
15
packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts
Normal file
15
packages/mermaid/src/diagrams/blockDiagram/blockDiagram.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||||
|
// @ts-ignore: jison doesn't export types
|
||||||
|
import parser from './parser/sankey.jison';
|
||||||
|
import db from './blockDB.js';
|
||||||
|
import renderer from './blockDiagramRenderer.js';
|
||||||
|
import { prepareTextForParsing } from './blockDiagramUtils.js';
|
||||||
|
|
||||||
|
const originalParse = parser.parse.bind(parser);
|
||||||
|
parser.parse = (text: string) => originalParse(prepareTextForParsing(text));
|
||||||
|
|
||||||
|
export const diagram: DiagramDefinition = {
|
||||||
|
parser,
|
||||||
|
db,
|
||||||
|
renderer,
|
||||||
|
};
|
@ -0,0 +1,20 @@
|
|||||||
|
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
|
||||||
|
|
||||||
|
const id = 'sankey';
|
||||||
|
|
||||||
|
const detector: DiagramDetector = (txt) => {
|
||||||
|
return /^\s*blockDiagram-beta/.test(txt);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loader = async () => {
|
||||||
|
const { diagram } = await import('./blockDiagram.js');
|
||||||
|
return { id, diagram };
|
||||||
|
};
|
||||||
|
|
||||||
|
const plugin: ExternalDiagramDefinition = {
|
||||||
|
id,
|
||||||
|
detector,
|
||||||
|
loader,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default plugin;
|
@ -0,0 +1,63 @@
|
|||||||
|
import { Diagram } from '../../Diagram.js';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
|
||||||
|
import {
|
||||||
|
select as d3select,
|
||||||
|
scaleOrdinal as d3scaleOrdinal,
|
||||||
|
schemeTableau10 as d3schemeTableau10,
|
||||||
|
} from 'd3';
|
||||||
|
|
||||||
|
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||||
|
import { Uid } from '../../rendering-util/uid.js';
|
||||||
|
import type { SankeyLinkColor, SankeyNodeAlignment } from '../../config.type.js';
|
||||||
|
|
||||||
|
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
|
||||||
|
// Get the config
|
||||||
|
const { securityLevel, sankey: conf } = configApi.getConfig();
|
||||||
|
const defaultSankeyConfig = configApi!.defaultConfig!.blockDiagram!;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// This code repeats for every diagram
|
||||||
|
// Figure out what is happening there, probably it should be separated
|
||||||
|
// The main thing is svg object that is a d3 wrapper for svg operations
|
||||||
|
//
|
||||||
|
let sandboxElement: any;
|
||||||
|
if (securityLevel === 'sandbox') {
|
||||||
|
sandboxElement = d3select('#i' + id);
|
||||||
|
}
|
||||||
|
const root =
|
||||||
|
securityLevel === 'sandbox'
|
||||||
|
? d3select(sandboxElement.nodes()[0].contentDocument.body)
|
||||||
|
: d3select('body');
|
||||||
|
// @ts-ignore TODO root.select is not callable
|
||||||
|
const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`);
|
||||||
|
|
||||||
|
// Establish svg dimensions and get width and height
|
||||||
|
//
|
||||||
|
|
||||||
|
// FIX: using max width prevents height from being set, is it intended?
|
||||||
|
// to add height directly one can use `svg.attr('height', height)`
|
||||||
|
//
|
||||||
|
// @ts-ignore TODO: svg type vs selection mismatch
|
||||||
|
configureSvgSize(svg, height, width, useMaxWidth);
|
||||||
|
|
||||||
|
// Prepare data for construction based on diagObj.db
|
||||||
|
// This must be a mutable object with `nodes` and `links` properties:
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// "nodes": [ { "id": "Alice" }, { "id": "Bob" }, { "id": "Carol" } ],
|
||||||
|
// "links": [ { "source": "Alice", "target": "Bob", "value": 23 }, { "source": "Bob", "target": "Carol", "value": 43 } ]
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @ts-ignore TODO: db type
|
||||||
|
const graph = diagObj.db.getGraph();
|
||||||
|
|
||||||
|
const nodeWidth = 10;
|
||||||
|
|
||||||
|
// Get color scheme for the graph
|
||||||
|
const colorScheme = d3scaleOrdinal(d3schemeTableau10);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
draw,
|
||||||
|
};
|
@ -0,0 +1,8 @@
|
|||||||
|
export const prepareTextForParsing = (text: string): string => {
|
||||||
|
const textToParse = text
|
||||||
|
.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g, '') // remove all trailing spaces for each row
|
||||||
|
.replaceAll(/([\n\r])+/g, '\n') // remove empty lines duplicated
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
return textToParse;
|
||||||
|
};
|
@ -0,0 +1,195 @@
|
|||||||
|
/** mermaid */
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// We support csv format as defined here:
|
||||||
|
// https://www.ietf.org/rfc/rfc4180.txt
|
||||||
|
// There are some minor changes for compliance with jison
|
||||||
|
// We also parse only 3 columns: source,target,value
|
||||||
|
// And allow blank lines for visual purposes
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
%lex
|
||||||
|
%x acc_title
|
||||||
|
%x acc_descr
|
||||||
|
%x acc_descr_multiline
|
||||||
|
%x string
|
||||||
|
%x md_string
|
||||||
|
%x NODE
|
||||||
|
%options easy_keword_rules
|
||||||
|
|
||||||
|
|
||||||
|
// as per section 6.1 of RFC 2234 [2]
|
||||||
|
COMMA \u002C
|
||||||
|
CR \u000D
|
||||||
|
LF \u000A
|
||||||
|
CRLF \u000D\u000A
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
"blockDiagram-beta" { return 'BLOCK_DIAGRAM_KEY'; }
|
||||||
|
// \s*\%\%.* { yy.getLogger().info('Found comment',yytext); }
|
||||||
|
[\s]+ { yy.getLogger().info('.', yytext); /* skip all whitespace */ }
|
||||||
|
[\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ }
|
||||||
|
// [\n] return 'NL';
|
||||||
|
<INITIAL>({CRLF}|{LF}) { return 'NL' }
|
||||||
|
["][`] { this.begin("md_string");}
|
||||||
|
<md_string>[^`"]+ { return "MD_STR";}
|
||||||
|
<md_string>[`]["] { this.popState();}
|
||||||
|
["] this.begin("string");
|
||||||
|
<string>["] this.popState();
|
||||||
|
<string>[^"]* return "STR";
|
||||||
|
"style" return 'STYLE';
|
||||||
|
"default" return 'DEFAULT';
|
||||||
|
"linkStyle" return 'LINKSTYLE';
|
||||||
|
"interpolate" return 'INTERPOLATE';
|
||||||
|
"classDef" return 'CLASSDEF';
|
||||||
|
"class" return 'CLASS';
|
||||||
|
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
|
||||||
|
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
||||||
|
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
|
||||||
|
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
|
||||||
|
accDescr\s*"{"\s* { this.begin("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';
|
||||||
|
|
||||||
|
// Start of nodes with shapes and description
|
||||||
|
"-)" { yy.getLogger().info('Lex: -)'); this.begin('NODE');return 'NODE_D START'; }
|
||||||
|
"(-" { yy.getLogger().info('Lex: (-'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"))" { yy.getLogger().info('Lex: ))'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
")" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"((" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"{{" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"(" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"[" { yy.getLogger().info('Lex: ['); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"([" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"[[" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"[|" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"[(" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"(((" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
")))" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"[/" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
"[\\" { this.begin('NODE');return 'NODE_DSTART'; }
|
||||||
|
|
||||||
|
|
||||||
|
[^\(\[\n\-\)\{\}]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
|
||||||
|
<<EOF>> { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; }
|
||||||
|
|
||||||
|
// Handling of strings in node
|
||||||
|
<NODE>["][`] { this.begin("md_string");}
|
||||||
|
<md_string>[^`"]+ { return "NODE_DESCR";}
|
||||||
|
<md_string>[`]["] { this.popState();}
|
||||||
|
<NODE>["] { yy.getLogger().info('Lex: Starting string');this.begin("string");}
|
||||||
|
<string>[^"]+ { yy.getLogger().info('Lex: NODE_DESCR:', yytext); return "NODE_DESCR";}
|
||||||
|
<string>["] {this.popState();}
|
||||||
|
|
||||||
|
// Node end of shape
|
||||||
|
<NODE>[\)]\) { this.popState();yy.getLogger().info('Lex: ))'); return "NODE_DEND"; }
|
||||||
|
<NODE>[\)] { this.popState();yy.getLogger().info('Lex: )'); return "NODE_DEND"; }
|
||||||
|
<NODE>[\]] { this.popState();yy.getLogger().info('Lex: ]'); return "NODE_DEND"; }
|
||||||
|
<NODE>"}}" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; }
|
||||||
|
<NODE>"(-" { this.popState();yy.getLogger().info('Lex: (-'); return "NODE_DEND"; }
|
||||||
|
<NODE>"-)" { this.popState();yy.getLogger().info('Lex: -)'); return "NODE_DEND"; }
|
||||||
|
<NODE>"((" { this.popState();yy.getLogger().info('Lex: (('); return "NODE_DEND"; }
|
||||||
|
<NODE>"(" { this.popState();yy.getLogger().info('Lex: ('); return "NODE_DEND"; }
|
||||||
|
<NODE>"])" { this.popState();yy.getLogger().info('Lex: ])'); return "NODE_DEND"; }
|
||||||
|
<NODE>"]]" { this.popState();yy.getLogger().info('Lex: ]]'); return "NODE_DEND"; }
|
||||||
|
<NODE>"/]" { this.popState();yy.getLogger().info('Lex: /]'); return "NODE_DEND"; }
|
||||||
|
<NODE>")]" { this.popState();yy.getLogger().info('Lex: )]'); return "NODE_DEND"; }
|
||||||
|
|
||||||
|
// Edges
|
||||||
|
\s*[xo<]?\-\-+[-xo>]\s* { yy.getLogger().info('Lex: LINK', '#'+yytext+'#'); return 'LINK'; }
|
||||||
|
\s*[xo<]?\=\=+[=xo>]\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; }
|
||||||
|
\s*[xo<]?\-?\.+\-[xo>]?\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; }
|
||||||
|
\s*\~\~[\~]+\s* { yy.getLogger().info('Lex: LINK', yytext); return 'LINK'; }
|
||||||
|
\s*[xo<]?\-\-\s* { yy.getLogger().info('Lex: START_LINK', yytext); return 'START_LINK'; }
|
||||||
|
\s*[xo<]?\=\=\s* { yy.getLogger().info('Lex: START_LINK', yytext); return 'START_LINK'; }
|
||||||
|
\s*[xo<]?\-\.\s* { yy.getLogger().info('Lex: START_LINK', yytext); return 'START_LINK'; }
|
||||||
|
|
||||||
|
/lex
|
||||||
|
|
||||||
|
%start start
|
||||||
|
|
||||||
|
%% // language grammar
|
||||||
|
|
||||||
|
spaceLines
|
||||||
|
: SPACELINE
|
||||||
|
| spaceLines SPACELINE
|
||||||
|
| spaceLines NL
|
||||||
|
;
|
||||||
|
|
||||||
|
seperator
|
||||||
|
: NL
|
||||||
|
{yy.getLogger().info('Rule: seperator (NL) ');}
|
||||||
|
| SPACE
|
||||||
|
{yy.getLogger().info('Rule: seperator (Space) ');}
|
||||||
|
| EOF
|
||||||
|
{yy.getLogger().info('Rule: seperator (EOF) ');}
|
||||||
|
;
|
||||||
|
|
||||||
|
start: BLOCK_DIAGRAM_KEY document;
|
||||||
|
|
||||||
|
blockDiagram
|
||||||
|
: blockDiagram document { return yy; }
|
||||||
|
| blockDiagram NL document { return yy; }
|
||||||
|
;
|
||||||
|
|
||||||
|
stop
|
||||||
|
: NL {yy.getLogger().info('Stop NL ');}
|
||||||
|
| EOF {yy.getLogger().info('Stop EOF ');}
|
||||||
|
// | SPACELINE
|
||||||
|
| stop NL {yy.getLogger().info('Stop NL2 ');}
|
||||||
|
| stop EOF {yy.getLogger().info('Stop EOF2 ');}
|
||||||
|
;
|
||||||
|
|
||||||
|
document
|
||||||
|
: document statement
|
||||||
|
| statement
|
||||||
|
;
|
||||||
|
|
||||||
|
link
|
||||||
|
: LINK
|
||||||
|
{ yy.getLogger().info("Rule: link: ", $1); }
|
||||||
|
| START_LINK
|
||||||
|
{ yy.getLogger().info("Rule: link: ", $1); }
|
||||||
|
;
|
||||||
|
|
||||||
|
statement
|
||||||
|
: nodeStatement
|
||||||
|
// SPACELIST node { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); }
|
||||||
|
// | SPACELIST ICON { yy.getLogger().info('Icon: ',$2);yy.decorateNode({icon: $2}); }
|
||||||
|
// | SPACELIST CLASS { yy.decorateNode({class: $2}); }
|
||||||
|
// | SPACELINE { yy.getLogger().info('SPACELIST');}
|
||||||
|
// |
|
||||||
|
// node { yy.getLogger().info('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); }
|
||||||
|
// | ICON { yy.decorateNode({icon: $1}); }
|
||||||
|
// | CLASS { yy.decorateNode({class: $1}); }
|
||||||
|
// // | SPACELIST
|
||||||
|
| EOF
|
||||||
|
;
|
||||||
|
|
||||||
|
nodeStatement: nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');}
|
||||||
|
|node { yy.getLogger().info('Rule: nodeStatement (node) ');}
|
||||||
|
;
|
||||||
|
|
||||||
|
node
|
||||||
|
: NODE_ID
|
||||||
|
{ yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); }
|
||||||
|
|NODE_ID nodeShapeNLabel
|
||||||
|
{ yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); }
|
||||||
|
// |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 }; }
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
@ -0,0 +1,85 @@
|
|||||||
|
// @ts-ignore: jison doesn't export types
|
||||||
|
import blockDiagram from './blockDiagram.jison';
|
||||||
|
import db from '../blockDB.js';
|
||||||
|
import { cleanupComments } from '../../../diagram-api/comments.js';
|
||||||
|
import { prepareTextForParsing } from '../blockDiagramUtils.js';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
describe('Sankey diagram', function () {
|
||||||
|
describe('when parsing an block diagram graph it should handle > ', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
blockDiagram.parser.yy = db;
|
||||||
|
blockDiagram.parser.yy.clear();
|
||||||
|
blockDiagram.parser.yy.getLogger = () => console;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('a diagram with a node', async () => {
|
||||||
|
const str = `blockDiagram-beta
|
||||||
|
id
|
||||||
|
`;
|
||||||
|
|
||||||
|
blockDiagram.parse(str);
|
||||||
|
});
|
||||||
|
it('a diagram with multiple nodes', async () => {
|
||||||
|
const str = `blockDiagram-beta
|
||||||
|
id1
|
||||||
|
id2
|
||||||
|
`;
|
||||||
|
|
||||||
|
blockDiagram.parse(str);
|
||||||
|
});
|
||||||
|
it('a node with a square shape and a label', async () => {
|
||||||
|
const str = `blockDiagram-beta
|
||||||
|
id["A label"]
|
||||||
|
id2`;
|
||||||
|
|
||||||
|
blockDiagram.parse(str);
|
||||||
|
});
|
||||||
|
it('a diagram with multiple nodes with edges', async () => {
|
||||||
|
const str = `blockDiagram-beta
|
||||||
|
id1["first"] --> id2["second"]
|
||||||
|
`;
|
||||||
|
|
||||||
|
blockDiagram.parse(str);
|
||||||
|
});
|
||||||
|
// it('a diagram with column statements', async () => {
|
||||||
|
// const str = `blockDiagram-beta
|
||||||
|
// columns 1
|
||||||
|
// block1["Block 1"]
|
||||||
|
// `;
|
||||||
|
|
||||||
|
// blockDiagram.parse(str);
|
||||||
|
// });
|
||||||
|
// it('a diagram with block hierarchies', async () => {
|
||||||
|
// const str = `blockDiagram-beta
|
||||||
|
// columns 1
|
||||||
|
// block1[Block 1]
|
||||||
|
|
||||||
|
// block
|
||||||
|
// columns 2
|
||||||
|
// block2[Block 2]
|
||||||
|
// block3[Block 3]
|
||||||
|
// end %% End the compound block
|
||||||
|
// `;
|
||||||
|
|
||||||
|
// blockDiagram.parse(str);
|
||||||
|
// });
|
||||||
|
// it('a diagram with differernt column values in different blocks', async () => {
|
||||||
|
// const str = `blockDiagram-beta
|
||||||
|
// columns 1
|
||||||
|
// block1[Block 1]
|
||||||
|
|
||||||
|
// block
|
||||||
|
// columns 2
|
||||||
|
// block2[Block 2]
|
||||||
|
// block3[Block 3]
|
||||||
|
// end %% End the compound block
|
||||||
|
// `;
|
||||||
|
|
||||||
|
// blockDiagram.parse(str);
|
||||||
|
|
||||||
|
// // Todo check that the different blocks have different column values
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
});
|
33
packages/mermaid/src/docs/.vitepress/block.mmd
Normal file
33
packages/mermaid/src/docs/.vitepress/block.mmd
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
block
|
||||||
|
columns 3
|
||||||
|
Block1
|
||||||
|
Block2["Block 2"]
|
||||||
|
block
|
||||||
|
columns 2
|
||||||
|
Block2.1
|
||||||
|
Block2.2
|
||||||
|
end
|
||||||
|
Block3
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
block
|
||||||
|
columns 2
|
||||||
|
Block[Frontend]:vertical
|
||||||
|
|
||||||
|
block "Document management System"
|
||||||
|
columns 3
|
||||||
|
MO[Manager Operation]:vertical
|
||||||
|
block
|
||||||
|
columns 2
|
||||||
|
block "Security and User Manager"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
block frontend:vertical
|
||||||
|
move right
|
||||||
|
block "Document Management System"
|
||||||
|
move down
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user