Started block diag db development

This commit is contained in:
Nikolay Rozhkov
2023-07-10 23:33:11 +03:00
parent c10f76580f
commit d165e8a642
8 changed files with 174 additions and 52 deletions

93
demos/block.html Normal file
View 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>

View File

@@ -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>

View File

@@ -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,
@@ -35,4 +71,4 @@ const db: BlockDB = {
clear, clear,
}; };
export default db; export default db;

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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();}

View File

@@ -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;