Adding cloud and bang shapes

This commit is contained in:
Knut Sveidqvist 2022-09-02 11:08:26 +02:00
parent 2fbdfdbf6a
commit ccb16e5f5a
8 changed files with 115 additions and 26 deletions

View File

@ -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', () => { it('a root with an icon', () => {
imgSnapshotTest( imgSnapshotTest(
`mindmap `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 */ /* The end */
}); });

View File

@ -121,21 +121,29 @@ mindmap
sc2 sc2
sc3 sc3
GrandChild2 GrandChild2
%%{init: {'securityLevel': 'loose', 'theme':'neutral'}}%%
</div> </div>
<div class="mermaid" style="width: 100%;"> <div class="mermaid" style="width: 100%;">
mindmap mindmap
root[ root))TheRoot)
Child1)"Child1"(
Child2-)"Child2"(-
Child3(-"Child3"-)
</div>
<div class="mermaid2" style="width: 100%;">
mindmap
root((
The root<br> The root<br>
where<br> where<br>
things<br> things<br>
happen! happen!
] ))
::icon(mdi mdi-numeric-8-circle) ::icon(mdi mdi-numeric-8-circle)
Child2 Child2
:::disabled :::disabled
GrandChild1 GrandChild1
GrandChild2 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) ::icon(mdi mdi-alarm)
GrandChild3 GrandChild3
GrandChild4 GrandChild4
@ -143,24 +151,12 @@ mindmap
::icon(mdi mdi-alarm) ::icon(mdi mdi-alarm)
GrandChild5[With<br>icon<br>one<br>two<br>three] GrandChild5[With<br>icon<br>one<br>two<br>three]
::icon(mdi mdi-numeric-8-circle) ::icon(mdi mdi-numeric-8-circle)
GrandChild6sakdjhfkla jhklasjfh klj GrandChild6 with wrapping text
::icon(mdi mdi-numeric-8-circle) ::icon(mdi mdi-numeric-8-circle)
Child1
GrandChild1
sc1
sc2
sc3
GrandChild2
Child5((Child5))
:::disabled
GrandChild7
sc1
sc2
sc3
GrandChild7
</div> </div>
<div class="mermaid" style="width: 50%;"> <div class="mermaid2" style="width: 50%;">
flowchart TD flowchart TD
id id
</div> </div>
@ -452,6 +448,7 @@ flowchart TD
curve: 'cardinal', curve: 'cardinal',
// securityLevel: 'sandbox', // securityLevel: 'sandbox',
// themeVariables: {relationLabelColor: 'red'} // themeVariables: {relationLabelColor: 'red'}
// theme: 'dark',
wrap: true, wrap: true,
}); });
function callback() { function callback() {

View File

@ -49,10 +49,12 @@ Root
C C
``` ```
)sdlfkjlsd(
In this way we can use a text outline to generate a hierarchical mindmap. In this way we can use a text outline to generate a hierarchical mindmap.
## Different shapes ## 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: Mindmap can show the following shapes:
@ -99,7 +101,7 @@ mindmap
``` ```
## Classes ## 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 ```mermaid-example
mindmap mindmap
Root Root

View File

@ -1,5 +1,6 @@
/** Created by knut on 15-01-14. */ /** Created by knut on 15-01-14. */
import { log } from '../../logger'; import { log } from '../../logger';
import { clear } from '../../commonDb';
var message = ''; var message = '';
var info = false; var info = false;
@ -30,5 +31,6 @@ export default {
getMessage, getMessage,
setInfo, setInfo,
getInfo, getInfo,
clear,
// parseError // parseError
}; };

View File

@ -128,6 +128,29 @@ root
expect(mm.children.length).toEqual(0); expect(mm.children.length).toEqual(0);
expect(mm.type).toEqual(mindmap.yy.nodeType.CIRCLE); 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 () { describe('decorations', function () {
it('should be possible to set an icon for the node', function () { it('should be possible to set an icon for the node', function () {

View File

@ -82,14 +82,19 @@ export const nodeType = {
CIRCLE: 3, CIRCLE: 3,
}; };
export const getTypeFromStart = (str) => { export const getType = (startStr, endStr) => {
switch (str) { console.log('In get type', startStr, endStr);
switch (startStr) {
case '[': case '[':
return nodeType.RECT; return nodeType.RECT;
case '(': case '(':
return nodeType.ROUNDED_RECT; return nodeType.ROUNDED_RECT;
case '((': case '((':
return nodeType.CIRCLE; return nodeType.CIRCLE;
case ')':
return nodeType.CLOUD;
case '))':
return nodeType.BANG;
default: default:
return nodeType.DEFAULT; return nodeType.DEFAULT;
} }
@ -120,6 +125,10 @@ const type2Str = (type) => {
return 'rounded-rect'; return 'rounded-rect';
case nodeType.CIRCLE: case nodeType.CIRCLE:
return 'circle'; return 'circle';
case nodeType.CLOUD:
return 'cloud';
case nodeType.BANG:
return 'bang';
default: default:
return 'no-border'; return 'no-border';
} }
@ -130,7 +139,7 @@ export default {
addNode, addNode,
clear, clear,
nodeType, nodeType,
getTypeFromStart, getType,
decorateNode, decorateNode,
setElementForId, setElementForId,
getElementById: (id) => elements[id], getElementById: (id) => elements[id],

View File

@ -27,11 +27,16 @@
[\n]+ /* return 'NL'; */ [\n]+ /* return 'NL'; */
<ICON>[^\)]+ { return 'ICON'; } <ICON>[^\)]+ { return 'ICON'; }
<ICON>\) {this.popState();} <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'; } "(" { this.begin('NODE');return 'NODE_DSTART'; }
"[" { this.begin('NODE');return 'NODE_DSTART'; } "[" { this.begin('NODE');return 'NODE_DSTART'; }
[\s]+ return 'SPACELIST' /* skip all whitespace */ ; [\s]+ return 'SPACELIST' /* skip all whitespace */ ;
[^\(\[\n]+ return 'NODE_ID'; // !(-\() return 'NODE_ID';
[^\(\[\n\-\)]+ return 'NODE_ID';
<<EOF>> return 'EOF'; <<EOF>> return 'EOF';
<NODE>["] { console.log('Starting NSTR');this.begin("NSTR");} <NODE>["] { console.log('Starting NSTR');this.begin("NSTR");}
<NSTR>[^"]+ { console.log('description:', yytext); return "NODE_DESCR";} <NSTR>[^"]+ { console.log('description:', yytext); return "NODE_DESCR";}
@ -39,7 +44,12 @@
<NODE>[\)]\) {this.popState();console.log('node end ))');return "NODE_DEND";} <NODE>[\)]\) {this.popState();console.log('node end ))');return "NODE_DEND";}
<NODE>[\)] {this.popState();console.log('node end )');return "NODE_DEND";} <NODE>[\)] {this.popState();console.log('node end )');return "NODE_DEND";}
<NODE>[\]] {this.popState();console.log('node end ...');return "NODE_DEND";} <NODE>[\]] {this.popState();console.log('node end ...');return "NODE_DEND";}
<NODE>[^\)\]]+ { console.log('Long description:', yytext); return 'NODE_DESCR';} <NODE>"(-" {this.popState();console.log('node end (-');return "NODE_DEND";}
<NODE>"-)" {this.popState();console.log('node end (-');return "NODE_DEND";}
<NODE>"((" {this.popState();console.log('node end ((');return "NODE_DEND";}
<NODE>"(" {this.popState();console.log('node end ((');return "NODE_DEND";}
<NODE>[^\)\]\(]+ { console.log('Long description:', yytext); return 'NODE_DESCR';}
<NODE>.+(?!\(\() { console.log('Long description:', yytext); return 'NODE_DESCR';}
// [\[] return 'NODE_START'; // [\[] return 'NODE_START';
// .+ return 'TXT' ; // .+ return 'TXT' ;
@ -78,6 +88,6 @@ statement
node node
: NODE_ID { $$ = { id: $1, descr: $1, type: yy.nodeType.DEFAULT }; } : NODE_ID { $$ = { id: $1, descr: $1, type: yy.nodeType.DEFAULT }; }
| NODE_ID NODE_DSTART NODE_DESCR NODE_DEND | 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) }; }
; ;
%% %%

View File

@ -78,6 +78,26 @@ const rectBkg = function (elem, node, section, conf) {
.attr('height', node.height) .attr('height', node.height)
.attr('width', node.width); .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 circleBkg = function (elem, node, section, conf) {
const r = elem const r = elem
.append('circle') .append('circle')
@ -194,6 +214,14 @@ export const drawNode = function (elem, node, section, conf) {
bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')'); bkgElem.attr('transform', 'translate(' + node.width / 2 + ', ' + +node.height / 2 + ')');
circleBkg(bkgElem, node, section, conf); circleBkg(bkgElem, node, section, conf);
break; 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: default:
// defaultBkg(bkgElem, node, section, conf); // defaultBkg(bkgElem, node, section, conf);
} }