From ccb16e5f5ac5eeb9429dd2100d17affa9c19e6ce Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Fri, 2 Sep 2022 11:08:26 +0200 Subject: [PATCH] Adding cloud and bang shapes --- cypress/integration/rendering/mindmap.spec.js | 18 ++++++++++ cypress/platform/knsv.html | 33 +++++++++---------- docs/mindmap.md | 6 ++-- src/diagrams/info/infoDb.js | 2 ++ src/diagrams/mindmap/mindmap.spec.js | 23 +++++++++++++ src/diagrams/mindmap/mindmapDb.js | 15 +++++++-- src/diagrams/mindmap/parser/mindmap.jison | 16 +++++++-- src/diagrams/mindmap/svgDraw.js | 28 ++++++++++++++++ 8 files changed, 115 insertions(+), 26 deletions(-) diff --git a/cypress/integration/rendering/mindmap.spec.js b/cypress/integration/rendering/mindmap.spec.js index 14cae7f71..e161c529b 100644 --- a/cypress/integration/rendering/mindmap.spec.js +++ b/cypress/integration/rendering/mindmap.spec.js @@ -19,6 +19,15 @@ root[root] ); }); + it('a root with wrapping text and a shape', () => { + imgSnapshotTest( + `mindmap +root[A root with a long text that wraps to keep the node size in check] + `, + {} + ); + }); + it('a root with an icon', () => { imgSnapshotTest( `mindmap @@ -66,6 +75,15 @@ root {} ); }); + it('text shouhld wrap with icon', () => { + imgSnapshotTest( + `mindmap +root + Child3(A node with an icon and with a long text that wraps to keep the node size in check) + `, + {} + ); + }); /* The end */ }); diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html index fac2619aa..1c7064d99 100644 --- a/cypress/platform/knsv.html +++ b/cypress/platform/knsv.html @@ -121,21 +121,29 @@ mindmap sc2 sc3 GrandChild2 + %%{init: {'securityLevel': 'loose', 'theme':'neutral'}}%%
mindmap - root[ + root))TheRoot) + Child1)"Child1"( + Child2-)"Child2"(- + Child3(-"Child3"-) +
+
+mindmap + root(( The root
where
things
happen! - ] + )) ::icon(mdi mdi-numeric-8-circle) Child2 :::disabled GrandChild1 GrandChild2 - Child3(Child 3 has a long wrapped text as well) + Child3(Child 3 has a long text that wraps to keep the node width) ::icon(mdi mdi-alarm) GrandChild3 GrandChild4 @@ -143,24 +151,12 @@ mindmap ::icon(mdi mdi-alarm) GrandChild5[With
icon
one
two
three] ::icon(mdi mdi-numeric-8-circle) - GrandChild6sakdjhfkla jhklasjfh klj + GrandChild6 with wrapping text ::icon(mdi mdi-numeric-8-circle) - Child1 - GrandChild1 - sc1 - sc2 - sc3 - GrandChild2 - Child5((Child5)) - :::disabled - GrandChild7 - sc1 - sc2 - sc3 - GrandChild7 +
-
+
flowchart TD id
@@ -452,6 +448,7 @@ flowchart TD curve: 'cardinal', // securityLevel: 'sandbox', // themeVariables: {relationLabelColor: 'red'} + // theme: 'dark', wrap: true, }); function callback() { diff --git a/docs/mindmap.md b/docs/mindmap.md index 0b8a46ae9..c700fd453 100644 --- a/docs/mindmap.md +++ b/docs/mindmap.md @@ -49,10 +49,12 @@ Root C ``` +)sdlfkjlsd( + In this way we can use a text outline to generate a hierarchical mindmap. ## Different shapes -Mermaids mindmaps can show node using different shapes. When specifying a shape for a node the synax for the is similar to flowchart nodes, with an id followed by the shape definition and with the text within the shape delimiters. Where possible we try/will try to keep the same shapes as for flowcharts even though they are not all supported from the start. +Mermaids mindmaps can show node using different shapes. When specifying a shape for a node the syntax for the is similar to flowchart nodes, with an id followed by the shape definition and with the text within the shape delimiters. Where possible we try/will try to keep the same shapes as for flowcharts even though they are not all supported from the start. Mindmap can show the following shapes: @@ -99,7 +101,7 @@ mindmap ``` ## Classes -Again the synax for adding classes is similar to flowcharts and you can add classes using a tripple colon following a numver of css classes separated by space. In the following example one of the nodes has two custom classes attached urgent turning the background red and the text whiet and large increasing the font size: +Again the syntax for adding classes is similar to flowcharts and you can add classes using a tripple colon following a numver of css classes separated by space. In the following example one of the nodes has two custom classes attached urgent turning the background red and the text whiet and large increasing the font size: ```mermaid-example mindmap Root diff --git a/src/diagrams/info/infoDb.js b/src/diagrams/info/infoDb.js index 5a324fbb4..2a04f1633 100644 --- a/src/diagrams/info/infoDb.js +++ b/src/diagrams/info/infoDb.js @@ -1,5 +1,6 @@ /** Created by knut on 15-01-14. */ import { log } from '../../logger'; +import { clear } from '../../commonDb'; var message = ''; var info = false; @@ -30,5 +31,6 @@ export default { getMessage, setInfo, getInfo, + clear, // parseError }; diff --git a/src/diagrams/mindmap/mindmap.spec.js b/src/diagrams/mindmap/mindmap.spec.js index 4c31dc97f..b06c4674b 100644 --- a/src/diagrams/mindmap/mindmap.spec.js +++ b/src/diagrams/mindmap/mindmap.spec.js @@ -128,6 +128,29 @@ root expect(mm.children.length).toEqual(0); expect(mm.type).toEqual(mindmap.yy.nodeType.CIRCLE); }); + + it('mutiple types (cloud)', function () { + var str = `mindmap + root))the root(( +`; + + mindmap.parse(str); + const mm = mindmap.yy.getMindmap(); + expect(mm.descr).toEqual('the root'); + expect(mm.children.length).toEqual(0); + expect(mm.type).toEqual(mindmap.yy.nodeType.CLOUD); + }); + it('mutiple types (bang)', function () { + var str = `mindmap + root))the root(( +`; + + mindmap.parse(str); + const mm = mindmap.yy.getMindmap(); + expect(mm.descr).toEqual('the root'); + expect(mm.children.length).toEqual(0); + expect(mm.type).toEqual(mindmap.yy.nodeType.BANG); + }); }); describe('decorations', function () { it('should be possible to set an icon for the node', function () { diff --git a/src/diagrams/mindmap/mindmapDb.js b/src/diagrams/mindmap/mindmapDb.js index 846a9651c..86d0ca5f8 100644 --- a/src/diagrams/mindmap/mindmapDb.js +++ b/src/diagrams/mindmap/mindmapDb.js @@ -82,14 +82,19 @@ export const nodeType = { CIRCLE: 3, }; -export const getTypeFromStart = (str) => { - switch (str) { +export const getType = (startStr, endStr) => { + console.log('In get type', startStr, endStr); + switch (startStr) { case '[': return nodeType.RECT; case '(': return nodeType.ROUNDED_RECT; case '((': return nodeType.CIRCLE; + case ')': + return nodeType.CLOUD; + case '))': + return nodeType.BANG; default: return nodeType.DEFAULT; } @@ -120,6 +125,10 @@ const type2Str = (type) => { return 'rounded-rect'; case nodeType.CIRCLE: return 'circle'; + case nodeType.CLOUD: + return 'cloud'; + case nodeType.BANG: + return 'bang'; default: return 'no-border'; } @@ -130,7 +139,7 @@ export default { addNode, clear, nodeType, - getTypeFromStart, + getType, decorateNode, setElementForId, getElementById: (id) => elements[id], diff --git a/src/diagrams/mindmap/parser/mindmap.jison b/src/diagrams/mindmap/parser/mindmap.jison index 8cafd9a7d..52ec1ab11 100644 --- a/src/diagrams/mindmap/parser/mindmap.jison +++ b/src/diagrams/mindmap/parser/mindmap.jison @@ -27,11 +27,16 @@ [\n]+ /* return 'NL'; */ [^\)]+ { return 'ICON'; } \) {this.popState();} +"-)" { console.log('Exploding node'); this.begin('NODE');return 'NODE_DSTART'; } +"(-" { console.log('Cloud'); this.begin('NODE');return 'NODE_DSTART'; } +"))" { console.log('Explosion Bang'); this.begin('NODE');return 'NODE_DSTART'; } +")" { console.log('Cloud Bang'); this.begin('NODE');return 'NODE_DSTART'; } "((" { this.begin('NODE');return 'NODE_DSTART'; } "(" { this.begin('NODE');return 'NODE_DSTART'; } "[" { this.begin('NODE');return 'NODE_DSTART'; } [\s]+ return 'SPACELIST' /* skip all whitespace */ ; -[^\(\[\n]+ return 'NODE_ID'; +// !(-\() return 'NODE_ID'; +[^\(\[\n\-\)]+ return 'NODE_ID'; <> return 'EOF'; ["] { console.log('Starting NSTR');this.begin("NSTR");} [^"]+ { console.log('description:', yytext); return "NODE_DESCR";} @@ -39,7 +44,12 @@ [\)]\) {this.popState();console.log('node end ))');return "NODE_DEND";} [\)] {this.popState();console.log('node end )');return "NODE_DEND";} [\]] {this.popState();console.log('node end ...');return "NODE_DEND";} -[^\)\]]+ { console.log('Long description:', yytext); return 'NODE_DESCR';} +"(-" {this.popState();console.log('node end (-');return "NODE_DEND";} +"-)" {this.popState();console.log('node end (-');return "NODE_DEND";} +"((" {this.popState();console.log('node end ((');return "NODE_DEND";} +"(" {this.popState();console.log('node end ((');return "NODE_DEND";} +[^\)\]\(]+ { console.log('Long description:', yytext); return 'NODE_DESCR';} +.+(?!\(\() { console.log('Long description:', yytext); return 'NODE_DESCR';} // [\[] return 'NODE_START'; // .+ return 'TXT' ; @@ -78,6 +88,6 @@ statement node : NODE_ID { $$ = { id: $1, descr: $1, type: yy.nodeType.DEFAULT }; } | NODE_ID NODE_DSTART NODE_DESCR NODE_DEND - { console.log("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getTypeFromStart($2) }; } + { console.log("node found ..", $1); $$ = { id: $1, descr: $3, type: yy.getType($2, $4) }; } ; %% diff --git a/src/diagrams/mindmap/svgDraw.js b/src/diagrams/mindmap/svgDraw.js index 9eb7afd8e..04db87b7e 100644 --- a/src/diagrams/mindmap/svgDraw.js +++ b/src/diagrams/mindmap/svgDraw.js @@ -78,6 +78,26 @@ const rectBkg = function (elem, node, section, conf) { .attr('height', node.height) .attr('width', node.width); }; +const cloudBkg = function (elem, node, section, conf) { + const r = elem + .append('rect') + .attr('id', 'node-' + node.id) + .attr('class', 'node-bkg node-' + db.type2Str(node.type)) + .attr('height', node.height) + .attr('rx', node.padding) + .attr('ry', node.padding) + .attr('width', node.width); +}; +const bangBkg = function (elem, node, section, conf) { + const r = elem + .append('rect') + .attr('id', 'node-' + node.id) + .attr('class', 'node-bkg node-' + db.type2Str(node.type)) + .attr('height', node.height) + .attr('rx', node.padding) + .attr('ry', node.padding) + .attr('width', node.width); +}; const circleBkg = function (elem, node, section, conf) { const r = elem .append('circle') @@ -194,6 +214,14 @@ export const drawNode = function (elem, node, section, conf) { bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')'); circleBkg(bkgElem, node, section, conf); break; + case db.nodeType.CLOUD: + // bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')'); + cloudBkg(bkgElem, node, section, conf); + break; + case db.nodeType.BANG: + // bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')'); + bangBkg(bkgElem, node, section, conf); + break; default: // defaultBkg(bkgElem, node, section, conf); }