mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-24 09:49:46 +02:00
Started block diag db development
This commit is contained in:
93
demos/block.html
Normal file
93
demos/block.html
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns="http://www.w3.org/1999/html">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<title>States Mermaid Quick Test Page</title>
|
||||||
|
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||||
|
<style>
|
||||||
|
div.mermaid {
|
||||||
|
font-family: 'Courier New', Courier, monospace !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Block diagram demos</h1>
|
||||||
|
<h2>TCI IP</h2>
|
||||||
|
<pre class="mermaid">
|
||||||
|
block-beta
|
||||||
|
|
||||||
|
block TCP_IP["TCP/IP"]
|
||||||
|
</pre>
|
||||||
|
<!--
|
||||||
|
columns H
|
||||||
|
ApplicationLayer("Application Layer")
|
||||||
|
block
|
||||||
|
columns H
|
||||||
|
UserInterface("User Interface (WPF, HTML5/CSS3, Swing)")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
block:::background
|
||||||
|
columns H
|
||||||
|
PresentationLayer["Presentation Layer"]
|
||||||
|
block("")
|
||||||
|
columns H
|
||||||
|
Smack["J2SE Mobil App (Smack)"]
|
||||||
|
JsJAC["Java Script Browser App (JsJAC)"]
|
||||||
|
babelim[".NET Windows App (Babel-im)"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
block:::background
|
||||||
|
columns H
|
||||||
|
SessionLayer("Session Layer")
|
||||||
|
block("")
|
||||||
|
columns H
|
||||||
|
XMPP["XMPP Component"]
|
||||||
|
block
|
||||||
|
Authentication
|
||||||
|
Authorization
|
||||||
|
end
|
||||||
|
LDAP["LDAP, DB, POP"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
block:::background
|
||||||
|
columns H
|
||||||
|
NetworkLayer("Network Layer")
|
||||||
|
block("")
|
||||||
|
columns H
|
||||||
|
HTTP[HTTP]:1.5
|
||||||
|
SOCK[SOCK]:1.5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
block:::background
|
||||||
|
columns H
|
||||||
|
DataLayer("Data Layer")
|
||||||
|
block("")
|
||||||
|
columns H
|
||||||
|
XMPP[XMPP]
|
||||||
|
BDB["Business DB"]
|
||||||
|
AD["Active Directory"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'default',
|
||||||
|
logLevel: 3,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
block: {
|
||||||
|
padding: 10
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -78,6 +78,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<h2><a href="./sankey.html">Sankey</a></h2>
|
<h2><a href="./sankey.html">Sankey</a></h2>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<h2><a href="./block.html">Layered Blocks</a></h2>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import type { BlockDB } from './blockTypes.js';
|
// import type { BlockDB } from './blockTypes.js';
|
||||||
|
import type { DiagramDB } from '../../diagram-api/types.js';
|
||||||
|
import { BlockConfig } from './blockTypes.js';
|
||||||
|
|
||||||
import * as configApi from '../../config.js';
|
import * as configApi from '../../config.js';
|
||||||
// import common from '../common/common.js';
|
// import common from '../common/common.js';
|
||||||
@@ -12,20 +14,54 @@ import {
|
|||||||
clear as commonClear,
|
clear as commonClear,
|
||||||
} from '../../commonDb.js';
|
} from '../../commonDb.js';
|
||||||
|
|
||||||
type Block = {
|
export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0?
|
||||||
|
|
||||||
|
interface Block {
|
||||||
ID: string;
|
ID: string;
|
||||||
};
|
label?: string;
|
||||||
|
parent?: Block;
|
||||||
|
children?: Block[];
|
||||||
|
columns: number | TBlockColumnsDefaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Link {
|
||||||
|
source: Block;
|
||||||
|
target: Block;
|
||||||
|
}
|
||||||
|
|
||||||
let blocks: Block[] = [];
|
let blocks: Block[] = [];
|
||||||
|
let links: Link[] = [];
|
||||||
|
|
||||||
const clear = (): void => {
|
const clear = (): void => {
|
||||||
blocks = [];
|
blocks = [];
|
||||||
commonClear();
|
commonClear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type IAddBlock = (block: Block) => Block;
|
||||||
|
const addBlock: IAddBlock = (block: Block): Block => {
|
||||||
|
blocks.push(block);
|
||||||
|
return block;
|
||||||
|
};
|
||||||
|
|
||||||
|
type IAddLink = (link: Link) => Link;
|
||||||
|
const addLink: IAddLink = (link: Link): Link => {
|
||||||
|
links.push(link);
|
||||||
|
return link;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface BlockDB extends DiagramDB {
|
||||||
|
clear: () => void;
|
||||||
|
getConfig: () => BlockConfig | undefined;
|
||||||
|
addBlock: IAddBlock;
|
||||||
|
addLink: IAddLink;
|
||||||
|
getLogger: () => Console;
|
||||||
|
}
|
||||||
|
|
||||||
const db: BlockDB = {
|
const db: BlockDB = {
|
||||||
getConfig: () => configApi.getConfig().block,
|
getConfig: () => configApi.getConfig().block,
|
||||||
|
addBlock: addBlock,
|
||||||
|
addLink: addLink,
|
||||||
|
getLogger: () => console, // TODO: remove
|
||||||
// getAccTitle,
|
// getAccTitle,
|
||||||
// setAccTitle,
|
// setAccTitle,
|
||||||
// getAccDescription,
|
// getAccDescription,
|
||||||
|
@@ -3,10 +3,12 @@ import { DiagramDefinition } from '../../diagram-api/types.js';
|
|||||||
import parser from './parser/block.jison';
|
import parser from './parser/block.jison';
|
||||||
import db from './blockDB.js';
|
import db from './blockDB.js';
|
||||||
import renderer from './blockRenderer.js';
|
import renderer from './blockRenderer.js';
|
||||||
import { prepareTextForParsing } from './blockUtils.js';
|
|
||||||
|
|
||||||
const originalParse = parser.parse.bind(parser);
|
// TODO: do we need this?
|
||||||
parser.parse = (text: string) => originalParse(prepareTextForParsing(text));
|
// import { prepareTextForParsing } from './blockUtils.js';
|
||||||
|
// const originalParse = parser.parse.bind(parser);
|
||||||
|
// parser.parse = (text: string) => originalParse(prepareTextForParsing(text));
|
||||||
|
// parser.yy.getLogger = () => console;
|
||||||
|
|
||||||
export const diagram: DiagramDefinition = {
|
export const diagram: DiagramDefinition = {
|
||||||
parser,
|
parser,
|
||||||
|
@@ -11,11 +11,6 @@ import { configureSvgSize } from '../../setupGraphViewbox.js';
|
|||||||
import { Uid } from '../../rendering-util/uid.js';
|
import { Uid } from '../../rendering-util/uid.js';
|
||||||
|
|
||||||
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
|
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
|
||||||
// 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
|
|
||||||
//
|
|
||||||
const { securityLevel } = configApi.getConfig();
|
const { securityLevel } = configApi.getConfig();
|
||||||
let sandboxElement: any;
|
let sandboxElement: any;
|
||||||
if (securityLevel === 'sandbox') {
|
if (securityLevel === 'sandbox') {
|
||||||
@@ -25,28 +20,27 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
|||||||
securityLevel === 'sandbox'
|
securityLevel === 'sandbox'
|
||||||
? d3select(sandboxElement.nodes()[0].contentDocument.body)
|
? d3select(sandboxElement.nodes()[0].contentDocument.body)
|
||||||
: d3select('body');
|
: d3select('body');
|
||||||
|
|
||||||
// @ts-ignore TODO root.select is not callable
|
// @ts-ignore TODO root.select is not callable
|
||||||
const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`);
|
const svg = securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : d3select(`[id="${id}"]`);
|
||||||
|
|
||||||
// Establish svg dimensions and get width and height
|
// Establish svg dimensions and get width and height
|
||||||
//
|
//
|
||||||
|
const height = 400;
|
||||||
// FIX: using max width prevents height from being set, is it intended?
|
const width = 600;
|
||||||
// to add height directly one can use `svg.attr('height', height)`
|
const useMaxWidth = false;
|
||||||
//
|
|
||||||
// @ts-ignore TODO: svg type vs selection mismatch
|
|
||||||
configureSvgSize(svg, height, width, useMaxWidth);
|
configureSvgSize(svg, height, width, useMaxWidth);
|
||||||
|
|
||||||
// Prepare data for construction based on diagObj.db
|
// Prepare data for construction based on diagObj.db
|
||||||
// This must be a mutable object with `nodes` and `links` properties:
|
// This must be a mutable object with `nodes` and `links` properties:
|
||||||
//
|
//
|
||||||
// @ts-ignore TODO: db type
|
// @ts-ignore TODO: db type
|
||||||
const graph = diagObj.db.getGraph();
|
// const graph = diagObj.db.getGraph();
|
||||||
|
|
||||||
const nodeWidth = 10;
|
// const nodeWidth = 10;
|
||||||
|
|
||||||
// Get color scheme for the graph
|
// Get color scheme for the graph
|
||||||
const colorScheme = d3scaleOrdinal(d3schemeTableau10);
|
// const colorScheme = d3scaleOrdinal(d3schemeTableau10);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@@ -1,11 +1,5 @@
|
|||||||
import type { DiagramDB } from '../../diagram-api/types.js';
|
|
||||||
import type { BaseDiagramConfig } from '../../config.type.js';
|
import type { BaseDiagramConfig } from '../../config.type.js';
|
||||||
|
|
||||||
export interface BlockConfig extends BaseDiagramConfig {
|
export interface BlockConfig extends BaseDiagramConfig {
|
||||||
padding?: number;
|
padding?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlockDB extends DiagramDB {
|
|
||||||
clear: () => void;
|
|
||||||
getConfig: () => BlockConfig | undefined;
|
|
||||||
}
|
|
||||||
|
@@ -33,10 +33,10 @@ CRLF \u000D\u000A
|
|||||||
[\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ }
|
[\n]+ {yy.getLogger().info('_', yytext); /* skip all whitespace */ }
|
||||||
// [\n] return 'NL';
|
// [\n] return 'NL';
|
||||||
<INITIAL>({CRLF}|{LF}) { return 'NL' }
|
<INITIAL>({CRLF}|{LF}) { return 'NL' }
|
||||||
["][`] { this.begin("md_string");}
|
["][`] { this.pushState("md_string");}
|
||||||
<md_string>[^`"]+ { return "MD_STR";}
|
<md_string>[^`"]+ { return "MD_STR";}
|
||||||
<md_string>[`]["] { this.popState();}
|
<md_string>[`]["] { this.popState();}
|
||||||
["] this.begin("string");
|
["] this.pushState("string");
|
||||||
<string>["] this.popState();
|
<string>["] this.popState();
|
||||||
<string>[^"]* return "STR";
|
<string>[^"]* return "STR";
|
||||||
"style" return 'STYLE';
|
"style" return 'STYLE';
|
||||||
@@ -45,11 +45,11 @@ CRLF \u000D\u000A
|
|||||||
"interpolate" return 'INTERPOLATE';
|
"interpolate" return 'INTERPOLATE';
|
||||||
"classDef" return 'CLASSDEF';
|
"classDef" return 'CLASSDEF';
|
||||||
"class" return 'CLASS';
|
"class" return 'CLASS';
|
||||||
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
|
accTitle\s*":"\s* { this.pushState("acc_title");return 'acc_title'; }
|
||||||
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
||||||
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
|
accDescr\s*":"\s* { this.pushState("acc_descr");return 'acc_descr'; }
|
||||||
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
|
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
|
||||||
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
accDescr\s*"{"\s* { this.pushState("acc_descr_multiline");}
|
||||||
<acc_descr_multiline>[\}] { this.popState(); }
|
<acc_descr_multiline>[\}] { this.popState(); }
|
||||||
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
|
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
|
||||||
"subgraph" return 'subgraph';
|
"subgraph" return 'subgraph';
|
||||||
@@ -60,32 +60,32 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
|
|||||||
.*direction\s+LR[^\n]* return 'direction_lr';
|
.*direction\s+LR[^\n]* return 'direction_lr';
|
||||||
|
|
||||||
// Start of nodes with shapes and description
|
// Start of nodes with shapes and description
|
||||||
"-)" { yy.getLogger().info('Lex: -)'); this.begin('NODE');return 'NODE_D START'; }
|
"-)" { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_D START'; }
|
||||||
"(-" { yy.getLogger().info('Lex: (-'); this.begin('NODE');return 'NODE_DSTART'; }
|
"(-" { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"))" { yy.getLogger().info('Lex: ))'); this.begin('NODE');return 'NODE_DSTART'; }
|
"))" { yy.getLogger().info('Lex: ))'); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
")" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
")" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"((" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
"((" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"{{" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
"{{" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"(" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
"(" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"[" { yy.getLogger().info('Lex: ['); this.begin('NODE');return 'NODE_DSTART'; }
|
"[" { yy.getLogger().info('Lex: ['); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"([" { yy.getLogger().info('Lex: )'); this.begin('NODE');return 'NODE_DSTART'; }
|
"([" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"[[" { this.begin('NODE');return 'NODE_DSTART'; }
|
"[[" { this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"[|" { this.begin('NODE');return 'NODE_DSTART'; }
|
"[|" { this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"[(" { this.begin('NODE');return 'NODE_DSTART'; }
|
"[(" { this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"(((" { this.begin('NODE');return 'NODE_DSTART'; }
|
"(((" { this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
")))" { this.begin('NODE');return 'NODE_DSTART'; }
|
")))" { this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"[/" { this.begin('NODE');return 'NODE_DSTART'; }
|
"[/" { this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
"[\\" { this.begin('NODE');return 'NODE_DSTART'; }
|
"[\\" { this.pushState('NODE');return 'NODE_DSTART'; }
|
||||||
|
|
||||||
|
|
||||||
[^\(\[\n\-\)\{\}]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
|
[^\(\[\n\-\)\{\}]+ { yy.getLogger().info('Lex: NODE_ID', yytext);return 'NODE_ID'; }
|
||||||
<<EOF>> { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; }
|
<<EOF>> { yy.getLogger().info('Lex: EOF', yytext);return 'EOF'; }
|
||||||
|
|
||||||
// Handling of strings in node
|
// Handling of strings in node
|
||||||
<NODE>["][`] { this.begin("md_string");}
|
<NODE>["][`] { this.pushState("md_string");}
|
||||||
<md_string>[^`"]+ { return "NODE_DESCR";}
|
<md_string>[^`"]+ { return "NODE_DESCR";}
|
||||||
<md_string>[`]["] { this.popState();}
|
<md_string>[`]["] { this.popState();}
|
||||||
<NODE>["] { yy.getLogger().info('Lex: Starting string');this.begin("string");}
|
<NODE>["] { yy.getLogger().info('Lex: Starting string');this.pushState("string");}
|
||||||
<string>[^"]+ { yy.getLogger().info('Lex: NODE_DESCR:', yytext); return "NODE_DESCR";}
|
<string>[^"]+ { yy.getLogger().info('Lex: NODE_DESCR:', yytext); return "NODE_DESCR";}
|
||||||
<string>["] {this.popState();}
|
<string>["] {this.popState();}
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@ import { prepareTextForParsing } from '../blockUtils.js';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
describe('Sankey diagram', function () {
|
describe('Block diagram', function () {
|
||||||
describe('when parsing an block diagram graph it should handle > ', function () {
|
describe('when parsing an block diagram graph it should handle > ', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
block.parser.yy = db;
|
block.parser.yy = db;
|
||||||
|
Reference in New Issue
Block a user