Merge from upstream newShapes branch

This commit is contained in:
Ashish Jain
2024-09-16 14:59:46 +02:00
31 changed files with 871 additions and 684 deletions

View File

@@ -0,0 +1,5 @@
---
'mermaid': minor
---
Fix for issue with calculation of label width when using in firefox

View File

@@ -26,6 +26,7 @@ concat
controlx controlx
controly controly
CSSCLASS CSSCLASS
curv
CYLINDEREND CYLINDEREND
CYLINDERSTART CYLINDERSTART
DAGA DAGA

View File

@@ -5,6 +5,7 @@ bmatrix
braintree braintree
catmull catmull
compositTitleSize compositTitleSize
curv
doublecircle doublecircle
elems elems
gantt gantt
@@ -24,6 +25,7 @@ multigraph
nodesep nodesep
NOTEGROUP NOTEGROUP
Pinterest Pinterest
procs
rankdir rankdir
ranksep ranksep
rect rect

View File

@@ -4,79 +4,87 @@ const aliasSet1 = ['process', 'rect', 'proc', 'rectangle'] as const;
const aliasSet2 = ['event', 'rounded'] as const; const aliasSet2 = ['event', 'rounded'] as const;
const aliasSet3 = ['stadium', 'pill', 'term'] as const; const aliasSet3 = ['stadium', 'pill', 'terminal'] as const;
const aliasSet4 = ['fr', 'subproc', 'framed-rectangle', 'subroutine'] as const; const aliasSet4 = ['fr-rect', 'subproc', 'subprocess', 'framed-rectangle', 'subroutine'] as const;
const aliasSet5 = ['db', 'cylinder', 'cyl'] as const; const aliasSet5 = ['db', 'database', 'cylinder', 'cyl'] as const;
const aliasSet6 = ['diam', 'decision', 'diamond'] as const; const aliasSet6 = ['diam', 'decision', 'diamond'] as const;
const aliasSet7 = ['hex', 'hexagon', 'prepare'] as const; const aliasSet7 = ['hex', 'hexagon', 'prepare'] as const;
const aliasSet8 = ['l-r', 'lean-right', 'in-out'] as const; const aliasSet8 = ['lean-r', 'lean-right', 'in-out'] as const;
const aliasSet9 = ['l-l', 'lean-left', 'out-in'] as const; const aliasSet9 = ['lean-l', 'lean-left', 'out-in'] as const;
const aliasSet10 = ['trap-b', 'trapezoid-bottom', 'priority', 'trapezoid'] as const; const aliasSet10 = ['trap-b', 'trapezoid-bottom', 'priority'] as const;
const aliasSet11 = ['trap-t', 'trapezoid-top', 'manual', 'inv-trapezoid'] as const; const aliasSet11 = ['trap-t', 'trapezoid-top', 'manual'] as const;
const aliasSet12 = ['dc', 'double-circle'] as const; const aliasSet12 = ['dbl-circ', 'double-circle'] as const;
const aliasSet13 = ['notched-rect', 'card', 'notch-rect'] as const; const aliasSet13 = ['notched-rectangle', 'card', 'notch-rect'] as const;
const aliasSet14 = ['lined-rect', 'lined-proc', 'shaded-proc'] as const; const aliasSet14 = [
'lin-rect',
'lined-rectangle',
'lin-proc',
'lined-process',
'shaded-process',
] as const;
const aliasSet15 = ['sm-circ', 'small-circle', 'start'] as const; const aliasSet15 = ['sm-circ', 'small-circle', 'start'] as const;
const aliasSet16 = ['framed-circle', 'stop'] as const; const aliasSet16 = ['fr-circ', 'framed-circle', 'stop'] as const;
const aliasSet17 = ['fork', 'join', 'long-rect'] as const; const aliasSet17 = ['fork', 'join'] as const;
// brace-r', 'braces'
const aliasSet18 = ['brace', 'comment', 'brace-l'] as const; const aliasSet18 = ['comment', 'brace-l'] as const;
const aliasSet19 = ['bolt', 'com-link', 'lightning-bolt'] as const; const aliasSet19 = ['bolt', 'com-link', 'lightning-bolt'] as const;
const aliasSet20 = ['we-rect', 'doc', 'wave-edge-rect', 'wave-edged-rectangle'] as const; const aliasSet20 = ['doc', 'document'] as const;
const aliasSet21 = ['delay', 'half-rounded-rect'] as const; const aliasSet21 = ['delay', 'half-rounded-rectangle'] as const;
const aliasSet22 = ['t-cyl', 'das', 'tilted-cylinder'] as const; const aliasSet22 = ['h-cyl', 'das', 'horizontal-cylinder'] as const;
const aliasSet23 = ['l-cyl', 'disk', 'lined-cylinder'] as const; const aliasSet23 = ['lin-cyl', 'disk', 'lined-cylinder'] as const;
const aliasSet24 = ['cur-trap', 'disp', 'display', 'curved-trapezoid'] as const; const aliasSet24 = ['curv-trap', 'display', 'curved-trapezoid'] as const;
const aliasSet25 = ['div-rect', 'div-proc', 'divided-rectangle'] as const; const aliasSet25 = ['div-rect', 'div-proc', 'divided-rectangle', 'divided-process'] as const;
const aliasSet26 = ['sm-tri', 'extract', 'small-triangle', 'triangle'] as const; const aliasSet26 = ['extract', 'tri', 'triangle'] as const;
const aliasSet27 = ['win-pane', 'internal-storage', 'window-pane'] as const; const aliasSet27 = ['win-pane', 'internal-storage', 'window-pane'] as const;
const aliasSet28 = ['fc', 'junction', 'filled-circle'] as const; const aliasSet28 = ['f-circ', 'junction', 'filled-circle'] as const;
const aliasSet29 = ['lin-we-rect', 'lin-doc', 'lined-wave-edged-rect'] as const; const aliasSet29 = ['lin-doc', 'lined-document'] as const;
const aliasSet30 = ['notch-pent', 'loop-limit', 'notched-pentagon'] as const; const aliasSet30 = ['notch-pent', 'loop-limit', 'notched-pentagon'] as const;
const aliasSet31 = ['flip-tri', 'manual-file', 'flipped-triangle'] as const; const aliasSet31 = ['flip-tri', 'manual-file', 'flipped-triangle'] as const;
const aliasSet32 = ['sloped-rect', 'manual-input', 'sloped-rectangle'] as const; const aliasSet32 = ['sl-rect', 'manual-input', 'sloped-rectangle'] as const;
const aliasSet33 = ['mul-we-rect', 'mul-doc', 'multi-wave-edged-rectangle'] as const; const aliasSet33 = ['docs', 'documents', 'st-doc', 'stacked-document'] as const;
const aliasSet34 = ['mul-rect', 'mul-proc', 'multi-rect'] as const; const aliasSet34 = ['procs', 'processes', 'st-rect', 'stacked-rectangle'] as const;
const aliasSet35 = ['flag', 'paper-tape'] as const; const aliasSet35 = ['flag', 'paper-tape'] as const;
const aliasSet36 = ['bt-rect', 'stored-data', 'bow-tie-rect'] as const; const aliasSet36 = ['bow-rect', 'stored-data', 'bow-tie-rectangle'] as const;
const aliasSet37 = ['cross-circle', 'summary', 'crossed-circle'] as const; const aliasSet37 = ['cross-circ', 'summary', 'crossed-circle'] as const;
const aliasSet38 = ['tag-we-rect', 'tag-doc', 'tagged-wave-edged-rectangle'] as const; const aliasSet38 = ['tag-doc', 'tagged-document'] as const;
const aliasSet39 = ['tag-rect', 'tag-proc', 'tagged-rect'] as const; const aliasSet39 = ['tag-rect', 'tag-proc', 'tagged-rectangle', 'tagged-process'] as const;
const aliasSet40 = ['collate', 'hourglass'] as const;
// Aggregate all alias sets into a single array // Aggregate all alias sets into a single array
const aliasSets = [ const aliasSets = [
@@ -126,7 +134,7 @@ aliasSets.forEach((aliasSet) => {
it(`All ${aliasSet.join(',')} should render same shape`, () => { it(`All ${aliasSet.join(',')} should render same shape`, () => {
let flowchartCode = `flowchart \n`; let flowchartCode = `flowchart \n`;
aliasSet.forEach((alias, index) => { aliasSet.forEach((alias, index) => {
flowchartCode += ` n${index}@{ shape: ${alias}, label: "${alias}" }@\n`; flowchartCode += ` n${index}@{ shape: ${alias}, label: "${alias}" }\n`;
}); });
imgSnapshotTest(flowchartCode); imgSnapshotTest(flowchartCode);
}); });

View File

@@ -16,7 +16,7 @@ looks.forEach((look) => {
if (form) { if (form) {
flowchartCode += `, form: '${form}'`; flowchartCode += `, form: '${form}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -29,7 +29,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -42,7 +42,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -55,7 +55,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -68,7 +68,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { imgSnapshotTest(flowchartCode, {
look, look,
htmlLabels: false, htmlLabels: false,
@@ -85,7 +85,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
flowchartCode += ` style nAA fill:#f9f,stroke:#333,stroke-width:4px \n`; flowchartCode += ` style nAA fill:#f9f,stroke:#333,stroke-width:4px \n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -100,7 +100,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
flowchartCode += ` nAA:::customClazz\n`; flowchartCode += ` nAA:::customClazz\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -115,7 +115,7 @@ describe('Test iconShape with different h', () => {
let flowchartCode = `flowchart TB\n`; let flowchartCode = `flowchart TB\n`;
const icon = 'fa:bell'; const icon = 'fa:bell';
const iconHeight = 64; const iconHeight = 64;
flowchartCode += ` nA --> nAA@{ icon: '${icon}', label: 'icon with different h', h: ${iconHeight} }@\n`; flowchartCode += ` nA --> nAA@{ icon: '${icon}', label: 'icon with different h', h: ${iconHeight} }\n`;
imgSnapshotTest(flowchartCode); imgSnapshotTest(flowchartCode);
}); });
}); });

View File

@@ -10,7 +10,7 @@ looks.forEach((look) => {
describe(`Test imageShape in ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => { describe(`Test imageShape in ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => {
it(`without label`, () => { it(`without label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', w: '100', h: '100' }@\n`; flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', w: '100', h: '100' }\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -22,7 +22,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -34,7 +34,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -46,7 +46,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { look, htmlLabels: true }); imgSnapshotTest(flowchartCode, { look, htmlLabels: true });
}); });
@@ -58,7 +58,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
imgSnapshotTest(flowchartCode, { imgSnapshotTest(flowchartCode, {
look, look,
htmlLabels: false, htmlLabels: false,
@@ -74,7 +74,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
flowchartCode += ` style A fill:#f9f,stroke:#333,stroke-width:4px \n`; flowchartCode += ` style A fill:#f9f,stroke:#333,stroke-width:4px \n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -88,7 +88,7 @@ looks.forEach((look) => {
if (pos) { if (pos) {
flowchartCode += `, pos: '${pos}'`; flowchartCode += `, pos: '${pos}'`;
} }
flowchartCode += ` }@\n`; flowchartCode += ` }\n`;
flowchartCode += ` A:::customClazz\n`; flowchartCode += ` A:::customClazz\n`;
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });

View File

@@ -4,14 +4,14 @@ const looks = ['classic'] as const;
const directions = ['TB'] as const; const directions = ['TB'] as const;
const newShapesSet1 = [ const newShapesSet1 = [
'triangle', 'triangle',
'sloped-rect', 'sloped-rectangle',
'tilted-cylinder', 'horizontal-cylinder',
'flipped-triangle', 'flipped-triangle',
'hourglass', 'hourglass',
] as const; ] as const;
const newShapesSet2 = [ const newShapesSet2 = [
'tagged-rect', 'tagged-rectangle',
'multi-rect', 'documents',
'lightning-bolt', 'lightning-bolt',
'filled-circle', 'filled-circle',
'window-pane', 'window-pane',
@@ -19,26 +19,27 @@ const newShapesSet2 = [
const newShapesSet3 = [ const newShapesSet3 = [
'curved-trapezoid', 'curved-trapezoid',
'bow-tie-rect', 'bow-rect',
'wave-edge-rect', 'tagged-document',
'divided-rectangle', 'divided-rectangle',
'crossed-circle', 'crossed-circle',
] as const; ] as const;
const newShapesSet4 = [ const newShapesSet4 = [
'wave-rectangle', 'document',
'notched-pentagon', 'notched-pentagon',
'lined-cylinder', 'lined-cylinder',
'multi-wave-edged-rectangle', 'stacked-document',
'half-rounded-rect', 'half-rounded-rectangle',
] as const; ] as const;
const newShapesSet5 = [ const newShapesSet5 = [
'lined-wave-edged-rect', 'lined-document',
'tagged-wave-edged-rectangle', 'tagged-document',
'brace-l', 'brace-l',
'curved-trapezoid', 'comment',
'wave-rectangle', 'braces',
'brace-r',
] as const; ] as const;
const newShapesSet6 = ['brace-r', 'braces'] as const; const newShapesSet6 = ['brace-r', 'braces'] as const;
@@ -59,7 +60,7 @@ looks.forEach((look) => {
it(`without label`, () => { it(`without label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape} }@\n`; flowchartCode += ` n${index} --> n${index}${index}{ shape: ${newShape} }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -67,7 +68,7 @@ looks.forEach((look) => {
it(`with label`, () => { it(`with label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -75,7 +76,7 @@ looks.forEach((look) => {
it(`connect all shapes with each other`, () => { it(`connect all shapes with each other`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`; flowchartCode += ` n${index}${index}{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`;
}); });
for (let i = 0; i < newShapesSet.length; i++) { for (let i = 0; i < newShapesSet.length; i++) {
for (let j = i + 1; j < newShapesSet.length; j++) { for (let j = i + 1; j < newShapesSet.length; j++) {
@@ -88,7 +89,7 @@ looks.forEach((look) => {
it(`with very long label`, () => { it(`with very long label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -96,7 +97,7 @@ looks.forEach((look) => {
it(`with markdown htmlLabels:true`, () => { it(`with markdown htmlLabels:true`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -104,7 +105,7 @@ looks.forEach((look) => {
it(`with markdown htmlLabels:false`, () => { it(`with markdown htmlLabels:false`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { imgSnapshotTest(flowchartCode, {
look, look,
@@ -116,7 +117,7 @@ looks.forEach((look) => {
it(`with styles`, () => { it(`with styles`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`;
flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
@@ -126,7 +127,7 @@ looks.forEach((look) => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`;
flowchartCode += ` n${index}${index}:::customClazz\n`; flowchartCode += ` n${index}${index}:::customClazz\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });

View File

@@ -23,7 +23,7 @@ looks.forEach((look) => {
it(`without label`, () => { it(`without label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape} }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape} }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -31,7 +31,7 @@ looks.forEach((look) => {
it(`with label`, () => { it(`with label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -39,7 +39,7 @@ looks.forEach((look) => {
it(`connect all shapes with each other`, () => { it(`connect all shapes with each other`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`; flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }\n`;
}); });
for (let i = 0; i < shapesSet.length; i++) { for (let i = 0; i < shapesSet.length; i++) {
for (let j = i + 1; j < shapesSet.length; j++) { for (let j = i + 1; j < shapesSet.length; j++) {
@@ -52,7 +52,7 @@ looks.forEach((look) => {
it(`with very long label`, () => { it(`with very long label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -60,7 +60,7 @@ looks.forEach((look) => {
it(`with markdown htmlLabels:true`, () => { it(`with markdown htmlLabels:true`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -68,7 +68,7 @@ looks.forEach((look) => {
it(`with markdown htmlLabels:false`, () => { it(`with markdown htmlLabels:false`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }\n`;
}); });
imgSnapshotTest(flowchartCode, { imgSnapshotTest(flowchartCode, {
look, look,
@@ -80,7 +80,7 @@ looks.forEach((look) => {
it(`with styles`, () => { it(`with styles`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`;
flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
@@ -90,7 +90,7 @@ looks.forEach((look) => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`;
shapesSet.forEach((newShape, index) => { shapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }\n`;
flowchartCode += ` n${index}${index}:::customClazz\n`; flowchartCode += ` n${index}${index}:::customClazz\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });

View File

@@ -254,40 +254,40 @@ config:
--- ---
flowchart RL flowchart RL
subgraph " " subgraph " "
A5@{ shape: manual-file, label: "a label"}@ A5@{ shape: manual-file, label: "a label"}
B5@{ shape: manual-input, label: "a label" }@ B5@{ shape: manual-input, label: "a label" }
C5@{ shape: mul-doc, label: "a label" }@ C5@{ shape: mul-doc, label: "a label" }
D5@{ shape: mul-proc, label: "a label" }@ D5@{ shape: mul-proc, label: "a label" }
E5@{ shape: paper-tape, label: "a label" }@ E5@{ shape: paper-tape, label: "a label" }
B3@{ shape: das, label: "a label" }@ B3@{ shape: das, label: "a label" }
C3@{ shape: disk, label: "a label" }@ C3@{ shape: disk, label: "a label" }
D4@{ shape: lin-doc, label: "a label" }@ D4@{ shape: lin-doc, label: "a label" }
E4@{ shape: loop-limit, label: "a label" }@ E4@{ shape: loop-limit, label: "a label" }
end end
subgraph " " subgraph " "
B6@{ shape: summary, label: "a label" }@ B6@{ shape: summary, label: "a label" }
C6@{ shape: tag-we-rect, label: "a label" }@ C6@{ shape: tag-we-rect, label: "a label" }
D6@{ shape: tag-rect, label: "a label" }@ D6@{ shape: tag-rect, label: "a label" }
A2@{ shape: fork}@ A2@{ shape: fork}
B2@{ shape: hourglass }@ B2@{ shape: hourglass }
C2@{ shape: comment, label: "I am a comment" }@ C2@{ shape: comment, label: "I am a comment" }
D2@{ shape: bolt }@ D2@{ shape: bolt }
D3@{ shape: disp, label: "a label" }@ D3@{ shape: disp, label: "a label" }
C4@{ shape: junction, label: "a label" }@ C4@{ shape: junction, label: "a label" }
A4@{ shape: extract, label: "a label"}@ A4@{ shape: extract, label: "a label"}
B52[a fr]@{ shape: fr }@ B52[a fr]@{ shape: fr }
end end
subgraph " " subgraph " "
A1@{ shape: text, label: This is a textblock}@ A1@{ shape: text, label: This is a textblock}
B1@{ shape: card, label: "a label" }@ B1@{ shape: card, label: "a label" }
C1@{ shape: lined-proc, label: "a label" }@ C1@{ shape: lined-proc, label: "a label" }
D1@{ shape: start, label: "a label" }@ D1@{ shape: start, label: "a label" }
E1@{ shape: stop, label: "a label" }@ E1@{ shape: stop, label: "a label" }
E2@{ shape: doc, label: "a label" }@ E2@{ shape: doc, label: "a label" }
A6@{ shape: stored-data, label: "a label"}@ A6@{ shape: stored-data, label: "a label"}
A3@{ shape: delay, label: "a label" }@ A3@{ shape: delay, label: "a label" }
E3@{ shape: div-proc, label: "a label" }@ E3@{ shape: div-proc, label: "a label" }
B4[a label]@{ shape: win-pane }@ B4[a label]@{ shape: win-pane }
end end
</pre> </pre>
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">
@@ -461,6 +461,12 @@ flowchart TB
> >
</div> </div>
<pre id="diagram4" class="mermaid">
flowchart TB
A@{
label: "aksljhf kasjdh"
}
</pre>
<script type="module"> <script type="module">
import mermaid from './mermaid.esm.mjs'; import mermaid from './mermaid.esm.mjs';
import layouts from './mermaid-layout-elk.esm.mjs'; import layouts from './mermaid-layout-elk.esm.mjs';

View File

@@ -307,7 +307,7 @@ New Syntax for Shape Definition
Mermaid now supports a general syntax for defining shape types to accommodate the growing number of shapes. This syntax allows you to assign specific shapes to nodes using a clear and flexible format: Mermaid now supports a general syntax for defining shape types to accommodate the growing number of shapes. This syntax allows you to assign specific shapes to nodes using a clear and flexible format:
``` ```
A@{ shape: rect }@ A@{ shape: rect }
``` ```
This syntax creates a node A as a rectangle. It renders in the same way as `A["A"]`, or `A`. This syntax creates a node A as a rectangle. It renders in the same way as `A["A"]`, or `A`.
@@ -316,53 +316,53 @@ This syntax creates a node A as a rectangle. It renders in the same way as `A["A
Below is a comprehensive list of the newly introduced shapes and their corresponding semantic meanings, short names, and aliases: Below is a comprehensive list of the newly introduced shapes and their corresponding semantic meanings, short names, and aliases:
| **Semantic Name** | **Shape Name** | **Short Name** | **Description** | **Alias Supported** | | **Semantic Name** | **Shape Name** | **Short Name** | **Description** | **Alias Supported** |
| ------------------------------------- | --------------------------- | --------------- | ------------------------------ | ------------------------------------------- | | ------------------------------------- | ---------------------- | -------------- | ------------------------------ | ----------------------------------------------------------- |
| **Process** | Rectangle | `rect` | Standard process shape | `proc`, `process`, `rectangle` | | **Process** | Rectangle | `rect` | Standard process shape | `proc`, `process`, `rectangle` |
| **Event** | Rounded Rectangle | `rounded` | Represents an event | `event` | | **Event** | Rounded Rectangle | `rounded` | Represents an event | `event` |
| **Terminal Point** | Stadium | `stadium` | Terminal point | `term`, `pill` | | **Terminal Point** | Stadium | `stadium` | Terminal point | `terminal`, `pill` |
| **Subprocess** | Framed Rectangle | `fr` | Subprocess | `subproc`, `framed-rectangle`, `subroutine` | | **Subprocess** | Framed Rectangle | `fr-rect` | Subprocess | `subprocess`,`subproc`, `framed-rectangle`, `subroutine` |
| **Database** | Cylinder | `cyl` | Database storage | `db`, `cylinder` | | **Database** | Cylinder | `cyl` | Database storage | `db`, `database`, `cylinder` |
| **Start** | Circle | `circle` | Starting point | | | **Start** | Circle | `circle` | Starting point | `circ` |
| **Odd** | Odd | `odd` | Odd shape | | | **Odd** | Odd | `odd` | Odd shape | |
| **Decision** | Diamond | `diam` | Decision-making step | `decision`, `diamond` | | **Decision** | Diamond | `diam` | Decision-making step | `decision`, `diamond` |
| **Prepare Conditional** | Hexagon | `hex` | Preparation or condition step | `hexagon`, `prepare` | | **Prepare Conditional** | Hexagon | `hex` | Preparation or condition step | `hexagon`, `prepare` |
| **Data Input/Output** | Lean Right | `l-r` | Represents input or output | `lean-right`, `in-out` | | **Data Input/Output** | Lean Right | `lean-r` | Represents input or output | `lean-right`, `in-out` |
| **Data Input/Output** | Lean Left | `l-l` | Represents output or input | `lean-left`, `out-in` | | **Data Input/Output** | Lean Left | `lean-l` | Represents output or input | `lean-left`, `out-in` |
| **Priority Action** | Trapezoid Base Bottom | `trap-b` | Priority action | `priority`, `trapezoid-bottom`, `trapezoid` | | **Priority Action** | Trapezoid Base Bottom | `trap-b` | Priority action | `priority`, `trapezoid-bottom` |
| **Manual Operation** | Trapezoid Base Top | `trap-t` | Represents a manual task | `manual`, `trapezoid-top`, `inv-trapezoid` | | **Manual Operation** | Trapezoid Base Top | `trap-t` | Represents a manual task | `manual`, `trapezoid-top` |
| **Stop** | Double Circle | `dc` | Represents a stop point | `double-circle` | | **Stop** | Double Circle | `dbl-circ` | Represents a stop point | `double-circle` |
| **Text Block** | Text Block | `text` | Text block | - | | **Text Block** | Text Block | `text` | Text block | - |
| **Card** | Notched Rectangle | `notched-rect` | Represents a card | `card`, `notch-rect`, `notched-rect` | | **Card** | Notched Rectangle | `notch-rect` | Represents a card | `card`, `notched-rectangle` |
| **Lined/Shaded Process** | Lined Rectangle | `lined-rect` | Lined process shape | `lined-proc`, `shaded-proc` | | **Lined/Shaded Process** | Lined Rectangle | `lin-rect` | Lined process shape | `lined-rectangle`,`lined-proc`, `lin-proc`,`shaded-process` |
| **Start** | Small Circle | `sm-circ` | Small starting point | `start`, `small-circle` | | **Start** | Small Circle | `sm-circ` | Small starting point | `start`, `small-circle` |
| **Stop** | Framed Circle | `framed-circle` | Stop point | `stop`, `framed-circle` | | **Stop** | Framed Circle | `fr-circ` | Stop point | `stop`, `framed-circle` |
| **Fork/Join** | Long Rectangle | `fork` | Fork or join in process flow | `join`, `long-rect` | | **Fork/Join** | Filled Rectangle | `fork` | Fork or join in process flow | `join` |
| **Collate** | Hourglass | `hourglass` | Represents a collate operation | - | | **Collate** | Hourglass | `hourglass` | Represents a collate operation | `hourglass` |
| **Comment** | Curly Brace | `brace` | Adds a comment | `comment`, `brace-l` | | **Comment** | Curly Brace | `brace` | Adds a comment | `comment`, `brace-l` |
| **Comment Right** | Curly Brace | `brace-r` | Adds a comment | - | | **Comment Right** | Curly Brace | `brace-r` | Adds a comment | - |
| **Comment with braces on both sides** | Curly Braces | `braces` | Adds a comment | - | | **Comment with braces on both sides** | Curly Braces | `braces` | Adds a comment | - |
| **Com Link** | Lightning Bolt | `bolt` | Communication link | `com-link`, `lightning-bolt` | | **Com Link** | Lightning Bolt | `bolt` | Communication link | `com-link`, `lightning-bolt` |
| **Document** | Wave-Edged Rectangle | `we-rect` | Represents a document | `doc`, `wave-edge-rect` | | **Document** | Document | `doc` | Represents a document | `doc`, `document` |
| **Delay** | Half-Rounded Rectangle | `delay` | Represents a delay | `half-rounded-rect` | | **Delay** | Half-Rounded Rectangle | `delay` | Represents a delay | `half-rounded-rectangle` |
| **Direct Access Storage** | Tilted Cylinder | `t-cyl` | Direct access storage | `das`, `tilted-cylinder` | | **Direct Access Storage** | Horizontal Cylinder | `h-cyl` | Direct access storage | `das`, `horizontal-cylinder` |
| **Disk Storage** | Lined Cylinder | `l-cyl` | Disk storage | `disk`, `lined-cylinder` | | **Disk Storage** | Lined Cylinder | `lin-cyl` | Disk storage | `disk`, `lined-cylinder` |
| **Display** | Curved Trapezoid | `cur-trap` | Represents a display | `disp`, `curved-trapezoid`, `display` | | **Display** | Curved Trapezoid | `curv-trap` | Represents a display | `curved-trapezoid`, `display` |
| **Divided Process** | Divided Rectangle | `div-rect` | Divided process shape | `div-proc`, `divided-rectangle` | | **Divided Process** | Divided Rectangle | `div-rect` | Divided process shape | `div-proc`, `divided-rectangle`, `divided-process` |
| **Extract** | Small Triangle | `sm-tri` | Extraction process | `extract`, `small-triangle` | | **Extract** | Triangle | `tri` | Extraction process | `extract`, `triangle` |
| **Internal Storage** | Window Pane | `win-pane` | Internal storage | `internal-storage`, `window-pane` | | **Internal Storage** | Window Pane | `win-pane` | Internal storage | `internal-storage`, `window-pane` |
| **Junction** | Filled Circle | `fc` | Junction point | `junction`, `filled-circle` | | **Junction** | Filled Circle | `f-circ` | Junction point | `junction`, `filled-circle` |
| **Lined Document** | Lined Wave-Edged Rectangle | `lin-we-rect` | Lined document | `lin-doc`, `lined-wave-edged-rect` | | **Lined Document** | Lined Document | `lin-doc` | Lined document | `lined-document` |
| **Loop Limit** | Trapezoidal Pentagon | `notch-pent` | Loop limit step | `loop-limit`, `notched-pentagon` | | **Loop Limit** | Trapezoidal Pentagon | `notch-pent` | Loop limit step | `loop-limit`, `notched-pentagon` |
| **Manual File** | Flipped Triangle | `flip-tri` | Manual file operation | `manual-file`, `flipped-triangle` | | **Manual File** | Flipped Triangle | `flip-tri` | Manual file operation | `manual-file`, `flipped-triangle` |
| **Manual Input** | Sloped Rectangle | `sloped-rect` | Manual input step | `manual-input`, `sloped-rectangle` | | **Manual Input** | Sloped Rectangle | `sl-rect` | Manual input step | `manual-input`, `sloped-rectangle` |
| **Multi-Document** | Multi-Wave-Edged Rectangle | `mul-we-rect` | Multiple documents | `mul-doc`, `multi-wave-edged-rectangle` | | **Multi-Document** | Stacked Document | `docs` | Multiple documents | `documents`, `st-doc`, `stacked-document` |
| **Multi-Process** | Multi-Rect | `mul-rect` | Multiple processes | `mul-proc`, `multi-rect` | | **Multi-Process** | Stacked Rectangle | `st-rect` | Multiple processes | `procs`, `processes`, `stacked-rect` |
| **Paper Tape** | Flag | `flag` | Paper tape | `paper-tape` | | **Paper Tape** | Flag | `flag` | Paper tape | `paper-tape` |
| **Stored Data** | Bow Tie Rectangle | `bt-rect` | Stored data | `stored-data`, `bow-tie-rect` | | **Stored Data** | Bow Tie Rectangle | `bow-rect` | Stored data | `stored-data`, `bow-tie-rectangle` |
| **Summary** | Crossed Circle | `cross-circle` | Summary | `summary`, `crossed-circle` | | **Summary** | Crossed Circle | `cross-circ` | Summary | `summary`, `crossed-circle` |
| **Tagged Document** | Tagged Wave-Edged Rectangle | `tag-we-rect` | Tagged document | `tag-doc`, `tagged-wave-edged-rectangle` | | **Tagged Document** | Tagged Document | `tag-doc` | Tagged document | `tag-doc`, `tagged-document` |
| **Tagged Process** | Tagged Rectangle | `tag-rect` | Tagged process | `tag-proc`, `tagged-rect` | | **Tagged Process** | Tagged Rectangle | `tag-rect` | Tagged process | `tagged-rectangle`,`tag-proc`, `tagged-process` |
### Example Flowchart with New Shapes ### Example Flowchart with New Shapes
@@ -370,560 +370,560 @@ Heres an example flowchart that utilizes some of the newly introduced shapes:
```mermaid-example ```mermaid-example
flowchart RL flowchart RL
A5@{ shape: manual-file, label: "File Handling"}@ A@{ shape: manual-file, label: "File Handling"}
B5@{ shape: manual-input, label: "User Input"}@ B@{ shape: manual-input, label: "User Input"}
C5@{ shape: mul-doc, label: "Multiple Documents"}@ C@{ shape: docs, label: "Multiple Documents"}
D5@{ shape: mul-proc, label: "Process Automation"}@ D@{ shape: procs, label: "Process Automation"}
E5@{ shape: paper-tape, label: "Paper Records"}@ E@{ shape: paper-tape, label: "Paper Records"}
``` ```
```mermaid ```mermaid
flowchart RL flowchart RL
A5@{ shape: manual-file, label: "File Handling"}@ A@{ shape: manual-file, label: "File Handling"}
B5@{ shape: manual-input, label: "User Input"}@ B@{ shape: manual-input, label: "User Input"}
C5@{ shape: mul-doc, label: "Multiple Documents"}@ C@{ shape: docs, label: "Multiple Documents"}
D5@{ shape: mul-proc, label: "Process Automation"}@ D@{ shape: procs, label: "Process Automation"}
E5@{ shape: paper-tape, label: "Paper Records"}@ E@{ shape: paper-tape, label: "Paper Records"}
``` ```
### Process ### Process
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: rect, label: "This is a process" }@ A@{ shape: rect, label: "This is a process" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: rect, label: "This is a process" }@ A@{ shape: rect, label: "This is a process" }
``` ```
### Event ### Event
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: rounded, label: "This is an event" }@ A@{ shape: rounded, label: "This is an event" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: rounded, label: "This is an event" }@ A@{ shape: rounded, label: "This is an event" }
``` ```
### Terminal Point (Stadium) ### Terminal Point (Stadium)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: stadium, label: "Terminal point" }@ A@{ shape: stadium, label: "Terminal point" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: stadium, label: "Terminal point" }@ A@{ shape: stadium, label: "Terminal point" }
``` ```
### Subprocess ### Subprocess
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: fr, label: "This is a subprocess" }@ A@{ shape: fr, label: "This is a subprocess" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: fr, label: "This is a subprocess" }@ A@{ shape: fr, label: "This is a subprocess" }
``` ```
### Database (Cylinder) ### Database (Cylinder)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: cyl, label: "Database" }@ A@{ shape: cyl, label: "Database" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: cyl, label: "Database" }@ A@{ shape: cyl, label: "Database" }
``` ```
### Start (Circle) ### Start (Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: circle, label: "Start" }@ A@{ shape: circle, label: "Start" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: circle, label: "Start" }@ A@{ shape: circle, label: "Start" }
``` ```
### Odd ### Odd
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: odd, label: "Odd shape" }@ A@{ shape: odd, label: "Odd shape" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: odd, label: "Odd shape" }@ A@{ shape: odd, label: "Odd shape" }
``` ```
### Decision (Diamond) ### Decision (Diamond)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: diamond, label: "Decision" }@ A@{ shape: diamond, label: "Decision" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: diamond, label: "Decision" }@ A@{ shape: diamond, label: "Decision" }
``` ```
### Prepare Conditional (Hexagon) ### Prepare Conditional (Hexagon)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: hex, label: "Prepare conditional" }@ A@{ shape: hex, label: "Prepare conditional" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: hex, label: "Prepare conditional" }@ A@{ shape: hex, label: "Prepare conditional" }
``` ```
### Data Input/Output (Lean Right) ### Data Input/Output (Lean Right)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: l-r, label: "Input/Output" }@ A@{ shape: lean-r, label: "Input/Output" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: l-r, label: "Input/Output" }@ A@{ shape: lean-r, label: "Input/Output" }
``` ```
### Data Input/Output (Lean Left) ### Data Input/Output (Lean Left)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: l-l, label: "Output/Input" }@ A@{ shape: lean-l, label: "Output/Input" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: l-l, label: "Output/Input" }@ A@{ shape: lean-l, label: "Output/Input" }
``` ```
### Priority Action (Trapezoid Base Bottom) ### Priority Action (Trapezoid Base Bottom)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: trap-b, label: "Priority action" }@ A@{ shape: trap-b, label: "Priority action" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: trap-b, label: "Priority action" }@ A@{ shape: trap-b, label: "Priority action" }
``` ```
### Manual Operation (Trapezoid Base Top) ### Manual Operation (Trapezoid Base Top)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: trap-t, label: "Manual operation" }@ A@{ shape: trap-t, label: "Manual operation" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: trap-t, label: "Manual operation" }@ A@{ shape: trap-t, label: "Manual operation" }
``` ```
### Stop (Double Circle) ### Stop (Double Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: dc, label: "Stop" }@ A@{ shape: dbl-circ, label: "Stop" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: dc, label: "Stop" }@ A@{ shape: dbl-circ, label: "Stop" }
``` ```
### Text Block ### Text Block
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: text, label: "This is a text block" }@ A@{ shape: text, label: "This is a text block" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: text, label: "This is a text block" }@ A@{ shape: text, label: "This is a text block" }
``` ```
### Card (Notched Rectangle) ### Card (Notched Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: notched-rect, label: "Card" }@ A@{ shape: notch-rect, label: "Card" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: notched-rect, label: "Card" }@ A@{ shape: notch-rect, label: "Card" }
``` ```
### Lined/Shaded Process ### Lined/Shaded Process
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: lined-rect, label: "Lined process" }@ A@{ shape: lin-rect, label: "Lined process" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: lined-rect, label: "Lined process" }@ A@{ shape: lin-rect, label: "Lined process" }
``` ```
### Start (Small Circle) ### Start (Small Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: sm-circ, label: "Small start" }@ A@{ shape: sm-circ, label: "Small start" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: sm-circ, label: "Small start" }@ A@{ shape: sm-circ, label: "Small start" }
``` ```
### Stop (Framed Circle) ### Stop (Framed Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: framed-circle, label: "Stop" }@ A@{ shape: framed-circle, label: "Stop" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: framed-circle, label: "Stop" }@ A@{ shape: framed-circle, label: "Stop" }
``` ```
### Fork/Join (Long Rectangle) ### Fork/Join (Long Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: fork, label: "Fork or Join" }@ A@{ shape: fork, label: "Fork or Join" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: fork, label: "Fork or Join" }@ A@{ shape: fork, label: "Fork or Join" }
``` ```
### Collate (Hourglass) ### Collate (Hourglass)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: hourglass, label: "Collate" }@ A@{ shape: hourglass, label: "Collate" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: hourglass, label: "Collate" }@ A@{ shape: hourglass, label: "Collate" }
``` ```
### Comment (Curly Brace) ### Comment (Curly Brace)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: comment, label: "Comment" }@ A@{ shape: comment, label: "Comment" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: comment, label: "Comment" }@ A@{ shape: comment, label: "Comment" }
``` ```
### Comment Right (Curly Brace Right) ### Comment Right (Curly Brace Right)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: brace-r, label: "Comment" }@ A@{ shape: brace-r, label: "Comment" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: brace-r, label: "Comment" }@ A@{ shape: brace-r, label: "Comment" }
``` ```
### Comment with braces on both sides ### Comment with braces on both sides
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: braces, label: "Comment" }@ A@{ shape: braces, label: "Comment" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: braces, label: "Comment" }@ A@{ shape: braces, label: "Comment" }
``` ```
### Com Link (Lightning Bolt) ### Com Link (Lightning Bolt)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: bolt, label: "Communication link" }@ A@{ shape: bolt, label: "Communication link" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: bolt, label: "Communication link" }@ A@{ shape: bolt, label: "Communication link" }
``` ```
### Document (Wave-Edged Rectangle) ### Document
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: we-rect, label: "Document" }@ A@{ shape: doc, label: "Document" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: we-rect, label: "Document" }@ A@{ shape: doc, label: "Document" }
``` ```
### Delay (Half-Rounded Rectangle) ### Delay (Half-Rounded Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: delay, label: "Delay" }@ A@{ shape: delay, label: "Delay" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: delay, label: "Delay" }@ A@{ shape: delay, label: "Delay" }
``` ```
### Direct Access Storage (Tilted Cylinder) ### Direct Access Storage (Horizontal Cylinder)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: t-cyl, label: "Direct access storage" }@ A@{ shape: das, label: "Direct access storage" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: t-cyl, label: "Direct access storage" }@ A@{ shape: das, label: "Direct access storage" }
``` ```
### Disk Storage (Lined Cylinder) ### Disk Storage (Lined Cylinder)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: l-cyl, label: "Disk storage" }@ A@{ shape: lin-cyl, label: "Disk storage" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: l-cyl, label: "Disk storage" }@ A@{ shape: lin-cyl, label: "Disk storage" }
``` ```
### Display (Curved Trapezoid) ### Display (Curved Trapezoid)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: cur-trap, label: "Display" }@ A@{ shape: curv-trap, label: "Display" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: cur-trap, label: "Display" }@ A@{ shape: curv-trap, label: "Display" }
``` ```
### Divided Process (Divided Rectangle) ### Divided Process (Divided Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: div-rect, label: "Divided process" }@ A@{ shape: div-rect, label: "Divided process" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: div-rect, label: "Divided process" }@ A@{ shape: div-rect, label: "Divided process" }
``` ```
### Extract (Small Triangle) ### Extract (Small Triangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: sm-tri, label: "Extract" }@ A@{ shape: tri, label: "Extract" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: sm-tri, label: "Extract" }@ A@{ shape: tri, label: "Extract" }
``` ```
### Internal Storage (Window Pane) ### Internal Storage (Window Pane)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: win-pane, label: "Internal storage" }@ A@{ shape: win-pane, label: "Internal storage" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: win-pane, label: "Internal storage" }@ A@{ shape: win-pane, label: "Internal storage" }
``` ```
### Junction (Filled Circle) ### Junction (Filled Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: fc, label: "Junction" }@ A@{ shape: f-circ, label: "Junction" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: fc, label: "Junction" }@ A@{ shape: f-circ, label: "Junction" }
``` ```
### Lined Document (Lined Wave-Edged Rectangle) ### Lined Document
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: lin-we-rect, label: "Lined document" }@ A@{ shape: lin-doc, label: "Lined document" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: lin-we-rect, label: "Lined document" }@ A@{ shape: lin-doc, label: "Lined document" }
``` ```
### Loop Limit (Trapezoidal Pentagon) ### Loop Limit (Notched Pentagon)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: not-pent, label: "Loop limit" }@ A@{ shape: notch-pent, label: "Loop limit" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: not-pent, label: "Loop limit" }@ A@{ shape: notch-pent, label: "Loop limit" }
``` ```
### Manual File (Flipped Triangle) ### Manual File (Flipped Triangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: flip-tria, label: "Manual file" }@ A@{ shape: flip-tri, label: "Manual file" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: flip-tria, label: "Manual file" }@ A@{ shape: flip-tri, label: "Manual file" }
``` ```
### Manual Input (Sloped Rectangle) ### Manual Input (Sloped Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: sloped-rect, label: "Manual input" }@ A@{ shape: sl-rect, label: "Manual input" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: sloped-rect, label: "Manual input" }@ A@{ shape: sl-rect, label: "Manual input" }
``` ```
### Multi-Document (Multi-Wave-Edged Rectangle) ### Multi-Document (Stacked Document)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: mul-we-rect, label: "Multiple documents" }@ A@{ shape: docs, label: "Multiple documents" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: mul-we-rect, label: "Multiple documents" }@ A@{ shape: docs, label: "Multiple documents" }
``` ```
### Multi-Process (Multi-Rect) ### Multi-Process (Stacked Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: mul-rect, label: "Multiple processes" }@ A@{ shape: processes, label: "Multiple processes" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: mul-rect, label: "Multiple processes" }@ A@{ shape: processes, label: "Multiple processes" }
``` ```
### Paper Tape (Flag) ### Paper Tape (Flag)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: flag, label: "Paper tape" }@ A@{ shape: flag, label: "Paper tape" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: flag, label: "Paper tape" }@ A@{ shape: flag, label: "Paper tape" }
``` ```
### Stored Data (Bow Tie Rectangle) ### Stored Data (Bow Tie Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: bt-rect, label: "Stored data" }@ A@{ shape: bow-rect, label: "Stored data" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: bt-rect, label: "Stored data" }@ A@{ shape: bow-rect, label: "Stored data" }
``` ```
### Summary (Crossed Circle) ### Summary (Crossed Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: cross-circle, label: "Summary" }@ A@{ shape: cross-circ, label: "Summary" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: cross-circle, label: "Summary" }@ A@{ shape: cross-circ, label: "Summary" }
``` ```
### Tagged Document (Tagged Wave-Edged Rectangle) ### Tagged Document
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: tag-we-rect, label: "Tagged document" }@ A@{ shape: tag-doc, label: "Tagged document" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: tag-we-rect, label: "Tagged document" }@ A@{ shape: tag-doc, label: "Tagged document" }
``` ```
### Tagged Process (Tagged Rectangle) ### Tagged Process (Tagged Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: tag-rect, label: "Tagged process" }@ A@{ shape: tag-rect, label: "Tagged process" }
``` ```
```mermaid ```mermaid
flowchart TD flowchart TD
A@{ shape: tag-rect, label: "Tagged process" }@ A@{ shape: tag-rect, label: "Tagged process" }
``` ```
## Links between nodes ## Links between nodes

View File

@@ -39,10 +39,11 @@ export const render = async (
}; };
graph.children.push(child); graph.children.push(child);
nodeDb[node.id] = child; nodeDb[node.id] = child;
const config = getConfig();
// Add the element to the DOM // Add the element to the DOM
if (!node.isGroup) { if (!node.isGroup) {
const childNodeEl = await insertNode(nodeEl, node, node.dir); const childNodeEl = await insertNode(nodeEl, node, { config });
boundingBox = childNodeEl.node().getBBox(); boundingBox = childNodeEl.node().getBBox();
child.domId = childNodeEl; child.domId = childNodeEl;
child.width = boundingBox.width; child.width = boundingBox.width;
@@ -56,7 +57,7 @@ export const render = async (
// @ts-ignore TODO: fix this // @ts-ignore TODO: fix this
const { shapeSvg, bbox } = await labelHelper(nodeEl, node, undefined, true); const { shapeSvg, bbox } = await labelHelper(nodeEl, node, undefined, true);
labelData.width = bbox.width; labelData.width = bbox.width;
labelData.wrappingWidth = getConfig().flowchart!.wrappingWidth; labelData.wrappingWidth = config.flowchart!.wrappingWidth;
// Give some padding for elk // Give some padding for elk
labelData.height = bbox.height - 2; labelData.height = bbox.height - 2;
labelData.labelNode = shapeSvg.node(); labelData.labelNode = shapeSvg.node();

View File

@@ -87,7 +87,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
// insertCluster(clusters, graph.node(v)); // insertCluster(clusters, graph.node(v));
} else { } else {
log.info('Node - the non recursive path', v, node.id, node); log.info('Node - the non recursive path', v, node.id, node);
await insertNode(nodes, graph.node(v), dir); await insertNode(nodes, graph.node(v), { config: siteConfig });
} }
} }
}) })

View File

@@ -1131,7 +1131,7 @@ const shapes = {
let nodeElems = {}; let nodeElems = {};
export const insertNode = async (elem, node, dir) => { export const insertNode = async (elem, node, renderOptions) => {
let newEl; let newEl;
let el; let el;
@@ -1144,9 +1144,9 @@ export const insertNode = async (elem, node, dir) => {
target = node.linkTarget || '_blank'; target = node.linkTarget || '_blank';
} }
newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target); newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target);
el = await shapes[node.shape](newEl, node, dir); el = await shapes[node.shape](newEl, node, renderOptions);
} else { } else {
el = await shapes[node.shape](elem, node, dir); el = await shapes[node.shape](elem, node, renderOptions);
newEl = el; newEl = el;
} }
if (node.tooltip) { if (node.tooltip) {

View File

@@ -124,7 +124,8 @@ async function calculateBlockSize(
} }
// Add the element to the DOM to size it // Add the element to the DOM to size it
const nodeEl = await insertNode(elem, node); const config = getConfig();
const nodeEl = await insertNode(elem, node, { config });
const boundingBox = nodeEl.node().getBBox(); const boundingBox = nodeEl.node().getBBox();
const obj = db.getBlock(node.id); const obj = db.getBlock(node.id);
obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl }; obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };
@@ -138,7 +139,8 @@ export async function insertBlockPositioned(elem: any, block: Block, db: any) {
// Add the element to the DOM to size it // Add the element to the DOM to size it
const obj = db.getBlock(node.id); const obj = db.getBlock(node.id);
if (obj.type !== 'space') { if (obj.type !== 'space') {
await insertNode(elem, node); const config = getConfig();
await insertNode(elem, node, { config });
block.intersect = node?.intersect; block.intersect = node?.intersect;
positionNode(node); positionNode(node);
} }

View File

@@ -123,23 +123,18 @@ export const addVertex = function (
if (shapeData !== undefined) { if (shapeData !== undefined) {
let yamlData; let yamlData;
// detect if shapeData contains a newline character // detect if shapeData contains a newline character
// console.log('shapeData', shapeData);
if (!shapeData.includes('\n')) { if (!shapeData.includes('\n')) {
// console.log('yamlData shapeData has no new lines', shapeData); // console.log('yamlData shapeData has no new lines', shapeData);
yamlData = '{\n' + shapeData + '\n'; yamlData = '{\n' + shapeData + '\n}';
} else { } else {
// console.log('yamlData shapeData has new lines', shapeData); // console.log('yamlData shapeData has new lines', shapeData);
yamlData = shapeData + '\n'; yamlData = shapeData + '\n';
// Find the position of the last } and replace it with a newline
const lastPos = yamlData.lastIndexOf('}');
if (lastPos !== -1) {
yamlData = yamlData.substring(0, lastPos) + '\n';
}
} }
// console.log('yamlData', yamlData);
const doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as NodeMetaData; const doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA }) as NodeMetaData;
if (doc.shape && doc.shape !== doc.shape.toLowerCase()) { if (doc.shape && doc.shape !== doc.shape.toLowerCase()) {
throw new Error(`No such shape: ${node.shape}. Shape names should be lowercase.`); throw new Error(`No such shape: ${doc.shape}. Shape names should be lowercase.`);
} }
// console.log('yamlData doc', doc); // console.log('yamlData doc', doc);
@@ -825,13 +820,13 @@ const getTypeFromVertex = (vertex: FlowVertex) => {
return 'imageSquare'; return 'imageSquare';
} }
if (vertex?.icon) { if (vertex?.icon) {
if (vertex.form === 'circle') { if (vertex?.form === 'circle') {
return 'iconCircle'; return 'iconCircle';
} }
if (vertex.form === 'square') { if (vertex?.form === 'square') {
return 'iconSquare'; return 'iconSquare';
} }
if (vertex.form === 'rounded') { if (vertex?.form === 'rounded') {
return 'iconRounded'; return 'iconRounded';
} }
return 'icon'; return 'icon';

View File

@@ -15,7 +15,16 @@ describe('when parsing directions', function () {
it('should handle basic shape data statements', function () { it('should handle basic shape data statements', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded }@`); D@{ shape: rounded}`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(1);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
});
it('should handle basic shape data statements', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded }`);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(1); expect(data4Layout.nodes.length).toBe(1);
@@ -23,9 +32,79 @@ describe('when parsing directions', function () {
expect(data4Layout.nodes[0].label).toEqual('D'); expect(data4Layout.nodes[0].label).toEqual('D');
}); });
it('should handle basic shape data statements with &', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded } & E`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(2);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
expect(data4Layout.nodes[1].label).toEqual('E');
});
it('should handle shape data statements with edges', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded } --> E`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(2);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
expect(data4Layout.nodes[1].label).toEqual('E');
});
it('should handle basic shape data statements with amp and edges 1', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded } & E --> F`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(3);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
expect(data4Layout.nodes[1].label).toEqual('E');
});
it('should handle basic shape data statements with amp and edges 2', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded } & E@{ shape: rounded } --> F`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(3);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
expect(data4Layout.nodes[1].label).toEqual('E');
});
it('should handle basic shape data statements with amp and edges 3', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded } & E@{ shape: rounded } --> F & G@{ shape: rounded }`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(4);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
expect(data4Layout.nodes[1].label).toEqual('E');
});
it('should handle basic shape data statements with amp and edges 4', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded } & E@{ shape: rounded } --> F@{ shape: rounded } & G@{ shape: rounded }`);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(4);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
expect(data4Layout.nodes[1].label).toEqual('E');
});
it('should handle basic shape data statements with amp and edges 5, trailing space', function () {
const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded } & E@{ shape: rounded } --> F{ shape: rounded } & G{ shape: rounded } `);
const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(4);
expect(data4Layout.nodes[0].shape).toEqual('rounded');
expect(data4Layout.nodes[0].label).toEqual('D');
expect(data4Layout.nodes[1].label).toEqual('E');
});
it('should no matter of there are no leading spaces', function () { it('should no matter of there are no leading spaces', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
D@{shape: rounded }@`); D@{shape: rounded}`);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -36,7 +115,7 @@ describe('when parsing directions', function () {
it('should no matter of there are many leading spaces', function () { it('should no matter of there are many leading spaces', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded }@`); D@{ shape: rounded}`);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -47,7 +126,7 @@ describe('when parsing directions', function () {
it('should be forgiving with many spaces before teh end', function () { it('should be forgiving with many spaces before teh end', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded }@`); D@{ shape: rounded }`);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -57,7 +136,7 @@ describe('when parsing directions', function () {
}); });
it('should be possible to add multiple properties on the same line', function () { it('should be possible to add multiple properties on the same line', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
D@{ shape: rounded , label: "DD" }@`); D@{ shape: rounded , label: "DD"}`);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -69,8 +148,8 @@ describe('when parsing directions', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
A --> D@{ A --> D@{
shape: circle shape: circle
icon: "clock" other: "clock"
}@ }
`); `);
@@ -88,12 +167,12 @@ describe('when parsing directions', function () {
A[hello] A[hello]
B@{ B@{
shape: circle shape: circle
icon: "clock" other: "clock"
}@ }
C[Hello]@{ C[Hello]@{
shape: circle shape: circle
icon: "clock" other: "clock"
}@ }
`); `);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -109,8 +188,8 @@ describe('when parsing directions', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
A@{ A@{
label: "This is }" label: "This is }"
icon: "clock" other: "clock"
}@ }
`); `);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -134,8 +213,8 @@ describe('when parsing directions', function () {
label: | label: |
This is a This is a
multiline string multiline string
icon: "clock" other: "clock"
}@ }
`); `);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -148,8 +227,8 @@ describe('when parsing directions', function () {
A@{ A@{
label: "This is a label: "This is a
multiline string" multiline string"
icon: "clock" other: "clock"
}@ }
`); `);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -161,8 +240,8 @@ describe('when parsing directions', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
A@{ A@{
label: "This is a string with }" label: "This is a string with }"
icon: "clock" other: "clock"
}@ }
`); `);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -174,8 +253,8 @@ describe('when parsing directions', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
A@{ A@{
label: "This is a string with @" label: "This is a string with @"
icon: "clock" other: "clock"
}@ }
`); `);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
@@ -186,14 +265,14 @@ describe('when parsing directions', function () {
it(' should be possible to use @ in strings', function () { it(' should be possible to use @ in strings', function () {
const res = flow.parser.parse(`flowchart TB const res = flow.parser.parse(`flowchart TB
A@{ A@{
label: "This is a string with }@" label: "This is a string with}"
icon: "clock" other: "clock"
}@ }
`); `);
const data4Layout = flow.parser.yy.getData(); const data4Layout = flow.parser.yy.getData();
expect(data4Layout.nodes.length).toBe(1); expect(data4Layout.nodes.length).toBe(1);
expect(data4Layout.nodes[0].shape).toEqual('squareRect'); expect(data4Layout.nodes[0].shape).toEqual('squareRect');
expect(data4Layout.nodes[0].label).toEqual('This is a string with }@'); expect(data4Layout.nodes[0].label).toEqual('This is a string with}');
}); });
}); });

View File

@@ -38,20 +38,28 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multilin
// <acc_descr_multiline>.*[^\n]* { return "acc_descr_line"} // <acc_descr_multiline>.*[^\n]* { return "acc_descr_line"}
\@\{ { this.pushState("shapeData"); yytext=""; return 'SHAPE_DATA' } \@\{ {
<shapeData>["] { // console.log('=> shapeData', yytext);
this.pushState("shapeData"); yytext=""; return 'SHAPE_DATA' }
<shapeData>["] {
// console.log('=> shapeDataStr', yytext);
this.pushState("shapeDataStr"); this.pushState("shapeDataStr");
return 'SHAPE_DATA'; return 'SHAPE_DATA';
} }
<shapeDataStr>["] { this.popState(); return 'SHAPE_DATA'} <shapeDataStr>["] {
<shapeDataStr>[^\"]+ { // console.log('shapeData <==', yytext);
this.popState(); return 'SHAPE_DATA'}
<shapeDataStr>[^\"]+ {
// console.log('shapeData', yytext);
const re = /\n\s*/g; const re = /\n\s*/g;
yytext = yytext.replace(re,"<br/>"); yytext = yytext.replace(re,"<br/>");
return 'SHAPE_DATA'} return 'SHAPE_DATA'}
<shapeData>[^@^"]+ { <shapeData>[^}^"]+ {
// console.log('shapeData', yytext);
return 'SHAPE_DATA'; return 'SHAPE_DATA';
} }
<shapeData>\@+ { <shapeData>"}" {
// console.log('<== root', yytext)
this.popState(); this.popState();
} }
@@ -404,8 +412,10 @@ vertexStatement: vertexStatement link node shapeData
node: styledVertex node: styledVertex
{ /*console.warn('nod', $styledVertex);*/ $$ = [$styledVertex];} { /*console.warn('nod', $styledVertex);*/ $$ = [$styledVertex];}
| node shapeData spaceList AMP spaceList styledVertex
{ yy.addVertex($node[0],undefined,undefined,undefined, undefined,undefined, undefined,$shapeData); $$ = $node.concat($styledVertex); /*console.warn('pip2', $node[0], $styledVertex, $$);*/ }
| node spaceList AMP spaceList styledVertex | node spaceList AMP spaceList styledVertex
{ $$ = $node.concat($styledVertex); /* console.warn('pip', $node[0], $styledVertex, $$); */ } { $$ = $node.concat($styledVertex); /*console.warn('pip', $node[0], $styledVertex, $$);*/ }
; ;
styledVertex: vertex styledVertex: vertex

View File

@@ -203,7 +203,7 @@ New Syntax for Shape Definition
Mermaid now supports a general syntax for defining shape types to accommodate the growing number of shapes. This syntax allows you to assign specific shapes to nodes using a clear and flexible format: Mermaid now supports a general syntax for defining shape types to accommodate the growing number of shapes. This syntax allows you to assign specific shapes to nodes using a clear and flexible format:
``` ```
A@{ shape: rect }@ A@{ shape: rect }
``` ```
This syntax creates a node A as a rectangle. It renders in the same way as `A["A"]`, or `A`. This syntax creates a node A as a rectangle. It renders in the same way as `A["A"]`, or `A`.
@@ -212,53 +212,53 @@ This syntax creates a node A as a rectangle. It renders in the same way as `A["A
Below is a comprehensive list of the newly introduced shapes and their corresponding semantic meanings, short names, and aliases: Below is a comprehensive list of the newly introduced shapes and their corresponding semantic meanings, short names, and aliases:
| **Semantic Name** | **Shape Name** | **Short Name** | **Description** | **Alias Supported** | | **Semantic Name** | **Shape Name** | **Short Name** | **Description** | **Alias Supported** |
| ------------------------------------- | --------------------------- | --------------- | ------------------------------ | ------------------------------------------- | | ------------------------------------- | ---------------------- | -------------- | ------------------------------ | ----------------------------------------------------------- |
| **Process** | Rectangle | `rect` | Standard process shape | `proc`, `process`, `rectangle` | | **Process** | Rectangle | `rect` | Standard process shape | `proc`, `process`, `rectangle` |
| **Event** | Rounded Rectangle | `rounded` | Represents an event | `event` | | **Event** | Rounded Rectangle | `rounded` | Represents an event | `event` |
| **Terminal Point** | Stadium | `stadium` | Terminal point | `term`, `pill` | | **Terminal Point** | Stadium | `stadium` | Terminal point | `terminal`, `pill` |
| **Subprocess** | Framed Rectangle | `fr` | Subprocess | `subproc`, `framed-rectangle`, `subroutine` | | **Subprocess** | Framed Rectangle | `fr-rect` | Subprocess | `subprocess`,`subproc`, `framed-rectangle`, `subroutine` |
| **Database** | Cylinder | `cyl` | Database storage | `db`, `cylinder` | | **Database** | Cylinder | `cyl` | Database storage | `db`, `database`, `cylinder` |
| **Start** | Circle | `circle` | Starting point | | | **Start** | Circle | `circle` | Starting point | `circ` |
| **Odd** | Odd | `odd` | Odd shape | | | **Odd** | Odd | `odd` | Odd shape | |
| **Decision** | Diamond | `diam` | Decision-making step | `decision`, `diamond` | | **Decision** | Diamond | `diam` | Decision-making step | `decision`, `diamond` |
| **Prepare Conditional** | Hexagon | `hex` | Preparation or condition step | `hexagon`, `prepare` | | **Prepare Conditional** | Hexagon | `hex` | Preparation or condition step | `hexagon`, `prepare` |
| **Data Input/Output** | Lean Right | `l-r` | Represents input or output | `lean-right`, `in-out` | | **Data Input/Output** | Lean Right | `lean-r` | Represents input or output | `lean-right`, `in-out` |
| **Data Input/Output** | Lean Left | `l-l` | Represents output or input | `lean-left`, `out-in` | | **Data Input/Output** | Lean Left | `lean-l` | Represents output or input | `lean-left`, `out-in` |
| **Priority Action** | Trapezoid Base Bottom | `trap-b` | Priority action | `priority`, `trapezoid-bottom`, `trapezoid` | | **Priority Action** | Trapezoid Base Bottom | `trap-b` | Priority action | `priority`, `trapezoid-bottom` |
| **Manual Operation** | Trapezoid Base Top | `trap-t` | Represents a manual task | `manual`, `trapezoid-top`, `inv-trapezoid` | | **Manual Operation** | Trapezoid Base Top | `trap-t` | Represents a manual task | `manual`, `trapezoid-top` |
| **Stop** | Double Circle | `dc` | Represents a stop point | `double-circle` | | **Stop** | Double Circle | `dbl-circ` | Represents a stop point | `double-circle` |
| **Text Block** | Text Block | `text` | Text block | - | | **Text Block** | Text Block | `text` | Text block | - |
| **Card** | Notched Rectangle | `notched-rect` | Represents a card | `card`, `notch-rect`, `notched-rect` | | **Card** | Notched Rectangle | `notch-rect` | Represents a card | `card`, `notched-rectangle` |
| **Lined/Shaded Process** | Lined Rectangle | `lined-rect` | Lined process shape | `lined-proc`, `shaded-proc` | | **Lined/Shaded Process** | Lined Rectangle | `lin-rect` | Lined process shape | `lined-rectangle`,`lined-proc`, `lin-proc`,`shaded-process` |
| **Start** | Small Circle | `sm-circ` | Small starting point | `start`, `small-circle` | | **Start** | Small Circle | `sm-circ` | Small starting point | `start`, `small-circle` |
| **Stop** | Framed Circle | `framed-circle` | Stop point | `stop`, `framed-circle` | | **Stop** | Framed Circle | `fr-circ` | Stop point | `stop`, `framed-circle` |
| **Fork/Join** | Long Rectangle | `fork` | Fork or join in process flow | `join`, `long-rect` | | **Fork/Join** | Filled Rectangle | `fork` | Fork or join in process flow | `join` |
| **Collate** | Hourglass | `hourglass` | Represents a collate operation | - | | **Collate** | Hourglass | `hourglass` | Represents a collate operation | `hourglass` |
| **Comment** | Curly Brace | `brace` | Adds a comment | `comment`, `brace-l` | | **Comment** | Curly Brace | `brace` | Adds a comment | `comment`, `brace-l` |
| **Comment Right** | Curly Brace | `brace-r` | Adds a comment | - | | **Comment Right** | Curly Brace | `brace-r` | Adds a comment | - |
| **Comment with braces on both sides** | Curly Braces | `braces` | Adds a comment | - | | **Comment with braces on both sides** | Curly Braces | `braces` | Adds a comment | - |
| **Com Link** | Lightning Bolt | `bolt` | Communication link | `com-link`, `lightning-bolt` | | **Com Link** | Lightning Bolt | `bolt` | Communication link | `com-link`, `lightning-bolt` |
| **Document** | Wave-Edged Rectangle | `we-rect` | Represents a document | `doc`, `wave-edge-rect` | | **Document** | Document | `doc` | Represents a document | `doc`, `document` |
| **Delay** | Half-Rounded Rectangle | `delay` | Represents a delay | `half-rounded-rect` | | **Delay** | Half-Rounded Rectangle | `delay` | Represents a delay | `half-rounded-rectangle` |
| **Direct Access Storage** | Tilted Cylinder | `t-cyl` | Direct access storage | `das`, `tilted-cylinder` | | **Direct Access Storage** | Horizontal Cylinder | `h-cyl` | Direct access storage | `das`, `horizontal-cylinder` |
| **Disk Storage** | Lined Cylinder | `l-cyl` | Disk storage | `disk`, `lined-cylinder` | | **Disk Storage** | Lined Cylinder | `lin-cyl` | Disk storage | `disk`, `lined-cylinder` |
| **Display** | Curved Trapezoid | `cur-trap` | Represents a display | `disp`, `curved-trapezoid`, `display` | | **Display** | Curved Trapezoid | `curv-trap` | Represents a display | `curved-trapezoid`, `display` |
| **Divided Process** | Divided Rectangle | `div-rect` | Divided process shape | `div-proc`, `divided-rectangle` | | **Divided Process** | Divided Rectangle | `div-rect` | Divided process shape | `div-proc`, `divided-rectangle`, `divided-process` |
| **Extract** | Small Triangle | `sm-tri` | Extraction process | `extract`, `small-triangle` | | **Extract** | Triangle | `tri` | Extraction process | `extract`, `triangle` |
| **Internal Storage** | Window Pane | `win-pane` | Internal storage | `internal-storage`, `window-pane` | | **Internal Storage** | Window Pane | `win-pane` | Internal storage | `internal-storage`, `window-pane` |
| **Junction** | Filled Circle | `fc` | Junction point | `junction`, `filled-circle` | | **Junction** | Filled Circle | `f-circ` | Junction point | `junction`, `filled-circle` |
| **Lined Document** | Lined Wave-Edged Rectangle | `lin-we-rect` | Lined document | `lin-doc`, `lined-wave-edged-rect` | | **Lined Document** | Lined Document | `lin-doc` | Lined document | `lined-document` |
| **Loop Limit** | Trapezoidal Pentagon | `notch-pent` | Loop limit step | `loop-limit`, `notched-pentagon` | | **Loop Limit** | Trapezoidal Pentagon | `notch-pent` | Loop limit step | `loop-limit`, `notched-pentagon` |
| **Manual File** | Flipped Triangle | `flip-tri` | Manual file operation | `manual-file`, `flipped-triangle` | | **Manual File** | Flipped Triangle | `flip-tri` | Manual file operation | `manual-file`, `flipped-triangle` |
| **Manual Input** | Sloped Rectangle | `sloped-rect` | Manual input step | `manual-input`, `sloped-rectangle` | | **Manual Input** | Sloped Rectangle | `sl-rect` | Manual input step | `manual-input`, `sloped-rectangle` |
| **Multi-Document** | Multi-Wave-Edged Rectangle | `mul-we-rect` | Multiple documents | `mul-doc`, `multi-wave-edged-rectangle` | | **Multi-Document** | Stacked Document | `docs` | Multiple documents | `documents`, `st-doc`, `stacked-document` |
| **Multi-Process** | Multi-Rect | `mul-rect` | Multiple processes | `mul-proc`, `multi-rect` | | **Multi-Process** | Stacked Rectangle | `st-rect` | Multiple processes | `procs`, `processes`, `stacked-rect` |
| **Paper Tape** | Flag | `flag` | Paper tape | `paper-tape` | | **Paper Tape** | Flag | `flag` | Paper tape | `paper-tape` |
| **Stored Data** | Bow Tie Rectangle | `bt-rect` | Stored data | `stored-data`, `bow-tie-rect` | | **Stored Data** | Bow Tie Rectangle | `bow-rect` | Stored data | `stored-data`, `bow-tie-rectangle` |
| **Summary** | Crossed Circle | `cross-circle` | Summary | `summary`, `crossed-circle` | | **Summary** | Crossed Circle | `cross-circ` | Summary | `summary`, `crossed-circle` |
| **Tagged Document** | Tagged Wave-Edged Rectangle | `tag-we-rect` | Tagged document | `tag-doc`, `tagged-wave-edged-rectangle` | | **Tagged Document** | Tagged Document | `tag-doc` | Tagged document | `tag-doc`, `tagged-document` |
| **Tagged Process** | Tagged Rectangle | `tag-rect` | Tagged process | `tag-proc`, `tagged-rect` | | **Tagged Process** | Tagged Rectangle | `tag-rect` | Tagged process | `tagged-rectangle`,`tag-proc`, `tagged-process` |
### Example Flowchart with New Shapes ### Example Flowchart with New Shapes
@@ -266,326 +266,326 @@ Heres an example flowchart that utilizes some of the newly introduced shapes:
```mermaid-example ```mermaid-example
flowchart RL flowchart RL
A5@{ shape: manual-file, label: "File Handling"}@ A@{ shape: manual-file, label: "File Handling"}
B5@{ shape: manual-input, label: "User Input"}@ B@{ shape: manual-input, label: "User Input"}
C5@{ shape: mul-doc, label: "Multiple Documents"}@ C@{ shape: docs, label: "Multiple Documents"}
D5@{ shape: mul-proc, label: "Process Automation"}@ D@{ shape: procs, label: "Process Automation"}
E5@{ shape: paper-tape, label: "Paper Records"}@ E@{ shape: paper-tape, label: "Paper Records"}
``` ```
### Process ### Process
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: rect, label: "This is a process" }@ A@{ shape: rect, label: "This is a process" }
``` ```
### Event ### Event
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: rounded, label: "This is an event" }@ A@{ shape: rounded, label: "This is an event" }
``` ```
### Terminal Point (Stadium) ### Terminal Point (Stadium)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: stadium, label: "Terminal point" }@ A@{ shape: stadium, label: "Terminal point" }
``` ```
### Subprocess ### Subprocess
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: fr, label: "This is a subprocess" }@ A@{ shape: fr, label: "This is a subprocess" }
``` ```
### Database (Cylinder) ### Database (Cylinder)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: cyl, label: "Database" }@ A@{ shape: cyl, label: "Database" }
``` ```
### Start (Circle) ### Start (Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: circle, label: "Start" }@ A@{ shape: circle, label: "Start" }
``` ```
### Odd ### Odd
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: odd, label: "Odd shape" }@ A@{ shape: odd, label: "Odd shape" }
``` ```
### Decision (Diamond) ### Decision (Diamond)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: diamond, label: "Decision" }@ A@{ shape: diamond, label: "Decision" }
``` ```
### Prepare Conditional (Hexagon) ### Prepare Conditional (Hexagon)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: hex, label: "Prepare conditional" }@ A@{ shape: hex, label: "Prepare conditional" }
``` ```
### Data Input/Output (Lean Right) ### Data Input/Output (Lean Right)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: l-r, label: "Input/Output" }@ A@{ shape: lean-r, label: "Input/Output" }
``` ```
### Data Input/Output (Lean Left) ### Data Input/Output (Lean Left)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: l-l, label: "Output/Input" }@ A@{ shape: lean-l, label: "Output/Input" }
``` ```
### Priority Action (Trapezoid Base Bottom) ### Priority Action (Trapezoid Base Bottom)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: trap-b, label: "Priority action" }@ A@{ shape: trap-b, label: "Priority action" }
``` ```
### Manual Operation (Trapezoid Base Top) ### Manual Operation (Trapezoid Base Top)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: trap-t, label: "Manual operation" }@ A@{ shape: trap-t, label: "Manual operation" }
``` ```
### Stop (Double Circle) ### Stop (Double Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: dc, label: "Stop" }@ A@{ shape: dbl-circ, label: "Stop" }
``` ```
### Text Block ### Text Block
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: text, label: "This is a text block" }@ A@{ shape: text, label: "This is a text block" }
``` ```
### Card (Notched Rectangle) ### Card (Notched Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: notched-rect, label: "Card" }@ A@{ shape: notch-rect, label: "Card" }
``` ```
### Lined/Shaded Process ### Lined/Shaded Process
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: lined-rect, label: "Lined process" }@ A@{ shape: lin-rect, label: "Lined process" }
``` ```
### Start (Small Circle) ### Start (Small Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: sm-circ, label: "Small start" }@ A@{ shape: sm-circ, label: "Small start" }
``` ```
### Stop (Framed Circle) ### Stop (Framed Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: framed-circle, label: "Stop" }@ A@{ shape: framed-circle, label: "Stop" }
``` ```
### Fork/Join (Long Rectangle) ### Fork/Join (Long Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: fork, label: "Fork or Join" }@ A@{ shape: fork, label: "Fork or Join" }
``` ```
### Collate (Hourglass) ### Collate (Hourglass)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: hourglass, label: "Collate" }@ A@{ shape: hourglass, label: "Collate" }
``` ```
### Comment (Curly Brace) ### Comment (Curly Brace)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: comment, label: "Comment" }@ A@{ shape: comment, label: "Comment" }
``` ```
### Comment Right (Curly Brace Right) ### Comment Right (Curly Brace Right)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: brace-r, label: "Comment" }@ A@{ shape: brace-r, label: "Comment" }
``` ```
### Comment with braces on both sides ### Comment with braces on both sides
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: braces, label: "Comment" }@ A@{ shape: braces, label: "Comment" }
``` ```
### Com Link (Lightning Bolt) ### Com Link (Lightning Bolt)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: bolt, label: "Communication link" }@ A@{ shape: bolt, label: "Communication link" }
``` ```
### Document (Wave-Edged Rectangle) ### Document
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: we-rect, label: "Document" }@ A@{ shape: doc, label: "Document" }
``` ```
### Delay (Half-Rounded Rectangle) ### Delay (Half-Rounded Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: delay, label: "Delay" }@ A@{ shape: delay, label: "Delay" }
``` ```
### Direct Access Storage (Tilted Cylinder) ### Direct Access Storage (Horizontal Cylinder)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: t-cyl, label: "Direct access storage" }@ A@{ shape: das, label: "Direct access storage" }
``` ```
### Disk Storage (Lined Cylinder) ### Disk Storage (Lined Cylinder)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: l-cyl, label: "Disk storage" }@ A@{ shape: lin-cyl, label: "Disk storage" }
``` ```
### Display (Curved Trapezoid) ### Display (Curved Trapezoid)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: cur-trap, label: "Display" }@ A@{ shape: curv-trap, label: "Display" }
``` ```
### Divided Process (Divided Rectangle) ### Divided Process (Divided Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: div-rect, label: "Divided process" }@ A@{ shape: div-rect, label: "Divided process" }
``` ```
### Extract (Small Triangle) ### Extract (Small Triangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: sm-tri, label: "Extract" }@ A@{ shape: tri, label: "Extract" }
``` ```
### Internal Storage (Window Pane) ### Internal Storage (Window Pane)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: win-pane, label: "Internal storage" }@ A@{ shape: win-pane, label: "Internal storage" }
``` ```
### Junction (Filled Circle) ### Junction (Filled Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: fc, label: "Junction" }@ A@{ shape: f-circ, label: "Junction" }
``` ```
### Lined Document (Lined Wave-Edged Rectangle) ### Lined Document
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: lin-we-rect, label: "Lined document" }@ A@{ shape: lin-doc, label: "Lined document" }
``` ```
### Loop Limit (Trapezoidal Pentagon) ### Loop Limit (Notched Pentagon)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: not-pent, label: "Loop limit" }@ A@{ shape: notch-pent, label: "Loop limit" }
``` ```
### Manual File (Flipped Triangle) ### Manual File (Flipped Triangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: flip-tria, label: "Manual file" }@ A@{ shape: flip-tri, label: "Manual file" }
``` ```
### Manual Input (Sloped Rectangle) ### Manual Input (Sloped Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: sloped-rect, label: "Manual input" }@ A@{ shape: sl-rect, label: "Manual input" }
``` ```
### Multi-Document (Multi-Wave-Edged Rectangle) ### Multi-Document (Stacked Document)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: mul-we-rect, label: "Multiple documents" }@ A@{ shape: docs, label: "Multiple documents" }
``` ```
### Multi-Process (Multi-Rect) ### Multi-Process (Stacked Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: mul-rect, label: "Multiple processes" }@ A@{ shape: processes, label: "Multiple processes" }
``` ```
### Paper Tape (Flag) ### Paper Tape (Flag)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: flag, label: "Paper tape" }@ A@{ shape: flag, label: "Paper tape" }
``` ```
### Stored Data (Bow Tie Rectangle) ### Stored Data (Bow Tie Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: bt-rect, label: "Stored data" }@ A@{ shape: bow-rect, label: "Stored data" }
``` ```
### Summary (Crossed Circle) ### Summary (Crossed Circle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: cross-circle, label: "Summary" }@ A@{ shape: cross-circ, label: "Summary" }
``` ```
### Tagged Document (Tagged Wave-Edged Rectangle) ### Tagged Document
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: tag-we-rect, label: "Tagged document" }@ A@{ shape: tag-doc, label: "Tagged document" }
``` ```
### Tagged Process (Tagged Rectangle) ### Tagged Process (Tagged Rectangle)
```mermaid-example ```mermaid-example
flowchart TD flowchart TD
A@{ shape: tag-rect, label: "Tagged process" }@ A@{ shape: tag-rect, label: "Tagged process" }
``` ```
## Links between nodes ## Links between nodes

View File

@@ -20,6 +20,11 @@ function applyStyle(dom, styleFn) {
async function addHtmlSpan(element, node, width, classes, addBackground = false) { async function addHtmlSpan(element, node, width, classes, addBackground = false) {
const fo = element.append('foreignObject'); const fo = element.append('foreignObject');
// This is not the final width but used in order to make sure the foreign
// object in firefox gets a width at all. The final width is fetched from the div
fo.attr('width', `${10 * width}px`);
fo.attr('height', `${10 * width}px`);
const div = fo.append('xhtml:div'); const div = fo.append('xhtml:div');
let label = node.label; let label = node.label;
if (node.label && hasKatex(node.label)) { if (node.label && hasKatex(node.label)) {
@@ -201,7 +206,7 @@ export const createText = async (
} = {}, } = {},
config: MermaidConfig config: MermaidConfig
) => { ) => {
log.info( log.debug(
'XYZ createText', 'XYZ createText',
text, text,
style, style,

View File

@@ -1,5 +1,6 @@
import { select } from 'd3'; import { select } from 'd3';
import { insertNode } from '../dagre-wrapper/nodes.js'; import { insertNode } from '../dagre-wrapper/nodes.js';
import { getConfig } from '../diagram-api/diagramAPI.js';
export const getDiagramElement = (id, securityLevel) => { export const getDiagramElement = (id, securityLevel) => {
let sandboxElement; let sandboxElement;
@@ -21,21 +22,26 @@ export const getDiagramElement = (id, securityLevel) => {
export function insertElementsForSize(el, data) { export function insertElementsForSize(el, data) {
const nodesElem = el.insert('g').attr('class', 'nodes'); const nodesElem = el.insert('g').attr('class', 'nodes');
el.insert('g').attr('class', 'edges'); el.insert('g').attr('class', 'edges');
const config = getConfig();
data.nodes.forEach(async (item) => { data.nodes.forEach(async (item) => {
item.shape = 'rect'; item.shape = 'rect';
await insertNode(nodesElem, { await insertNode(
...item, nodesElem,
class: 'default flowchart-label', {
labelStyle: '', ...item,
x: 0, class: 'default flowchart-label',
y: 0, labelStyle: '',
width: 100, x: 0,
rx: 0, y: 0,
ry: 0, width: 100,
height: 100, rx: 0,
shape: 'rect', ry: 0,
padding: 8, height: 100,
}); shape: 'rect',
padding: 8,
},
{ config }
);
// Create a new DOM element // Create a new DOM element
// const element = document.createElement('div'); // const element = document.createElement('div');

View File

@@ -125,7 +125,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
// insertCluster(clusters, graph.node(v)); // insertCluster(clusters, graph.node(v));
} else { } else {
log.trace('Node - the non recursive path XAX', v, nodes, graph.node(v), dir); log.trace('Node - the non recursive path XAX', v, nodes, graph.node(v), dir);
await insertNode(nodes, graph.node(v), dir); await insertNode(nodes, graph.node(v), { config: siteConfig });
} }
} }
}) })

View File

@@ -9,7 +9,6 @@ import { choice } from './shapes/choice.ts';
import { note } from './shapes/note.ts'; import { note } from './shapes/note.ts';
import { stadium } from './shapes/stadium.js'; import { stadium } from './shapes/stadium.js';
import { rectWithTitle } from './shapes/rectWithTitle.js'; import { rectWithTitle } from './shapes/rectWithTitle.js';
import { getConfig } from '../../diagram-api/diagramAPI.js';
import { subroutine } from './shapes/subroutine.js'; import { subroutine } from './shapes/subroutine.js';
import { cylinder } from './shapes/cylinder.js'; import { cylinder } from './shapes/cylinder.js';
import { circle } from './shapes/circle.js'; import { circle } from './shapes/circle.js';
@@ -62,161 +61,236 @@ export const shapes = {
// States // States
state, state,
stateStart, stateStart,
'small-circle': stateStart,
'sm-circ': stateStart,
start: stateStart,
stateEnd, stateEnd,
'framed-circle': stateEnd, forkJoin,
stop: stateEnd, choice,
note,
// Rectangles // Rectangles
rectWithTitle, rectWithTitle,
roundedRect, roundedRect,
rounded: roundedRect,
event: roundedRect,
squareRect, squareRect,
// Rectangle with alias: 'process', 'rect', 'proc', 'rectangle'
rectangle: squareRect, rectangle: squareRect,
rect: squareRect, rect: squareRect,
process: squareRect, process: squareRect,
proc: squareRect, proc: squareRect,
// Rounded Rectangle with alias: 'event', 'rounded'
rounded: roundedRect,
event: roundedRect,
// Stadium with alias: 'terminal','pill', 'stadium'
stadium, stadium,
pill: stadium, pill: stadium,
term: stadium, terminal: stadium,
'window-pane': windowPane,
'win-pane': windowPane,
'internal-storage': windowPane,
'divided-rectangle': dividedRectangle,
'div-rect': dividedRectangle,
'div-proc': dividedRectangle,
'tagged-rect': taggedRect,
'tag-rect': taggedRect,
'tag-proc': taggedRect,
'multi-rect': multiRect,
'mul-rect': multiRect,
'mul-proc': multiRect,
// Subroutine // Subprocess with alias: 'fr-rect', 'subproc', 'subprocess', 'framed-rectangle', 'subroutine'
subroutine, subroutine,
'framed-rectangle': subroutine, 'framed-rectangle': subroutine,
fr: subroutine, 'fr-rect': subroutine,
subprocess: subroutine,
subproc: subroutine, subproc: subroutine,
// Cylinders // Cylinder with alias: 'db', 'database', 'cylinder', 'cyl'
cylinder, cylinder,
cyl: cylinder,
db: cylinder, db: cylinder,
'tilted-cylinder': tiltedCylinder, cyl: cylinder,
't-cyl': tiltedCylinder, database: cylinder,
das: tiltedCylinder,
'lined-cylinder': linedCylinder,
'l-cyl': linedCylinder,
disk: linedCylinder,
// Circles // Diamond with alias: 'diam', 'decision', 'diamond'
circle, question,
'double-circle': doublecircle, diam: question,
dc: doublecircle, diamond: question,
'crossed-circle': crossedCircle, decision: question,
'cross-circle': crossedCircle,
summary: crossedCircle,
'filled-circle': filledCircle,
fc: filledCircle,
junction: filledCircle,
'lined-proc': shadedProcess,
'lined-rect': shadedProcess,
'shaded-proc': shadedProcess,
// Trapezoids // Hexagon with alias: 'hex', 'hexagon', 'prepare'
trapezoid, hexagon,
'trapezoid-bottom': trapezoid, hex: hexagon,
prepare: hexagon,
// Lean Right with alias: 'lean-r', 'lean-right', 'in-out'
lean_right, // used in old syntax for flowchart
'lean-r': lean_right,
'lean-right': lean_right,
'in-out': lean_right,
// Lean Left with alias: 'lean-l', 'lean-left', 'out-in'
lean_left, // used in old syntax for flowchart
'lean-l': lean_left,
'lean-left': lean_left,
'out-in': lean_left,
// Trapezoid with alias: 'trap-b', 'trapezoid-bottom', 'priority'
trapezoid, // used in old syntax for flowchart
'trap-b': trapezoid, 'trap-b': trapezoid,
'trapezoid-bottom': trapezoid,
priority: trapezoid, priority: trapezoid,
inv_trapezoid,
// Inverted Trapezoid with alias: 'inv-trapezoid', 'trapezoid-top', 'trap-t', 'manual'
inv_trapezoid, // used in old syntax for flowchart
'inv-trapezoid': inv_trapezoid, 'inv-trapezoid': inv_trapezoid,
'trapezoid-top': inv_trapezoid, 'trapezoid-top': inv_trapezoid,
'trap-t': inv_trapezoid, 'trap-t': inv_trapezoid,
manual: inv_trapezoid, manual: inv_trapezoid,
// Double Circle with alias: 'dbl-circ', 'double-circle'
doublecircle, // used in old syntax for flowchart
'dbl-circ': doublecircle,
'double-circle': doublecircle,
// circle with alias: 'circ', 'circle'
circle,
circ: circle,
// Rect Left Inv Arrow with alias: 'odd', 'rect-left-inv-arrow'
rect_left_inv_arrow,
odd: rect_left_inv_arrow,
// Notched Rectangle with alias: 'notched-rectangle', 'notch-rect', 'card'
card,
'notched-rectangle': card,
'notch-rect': card,
// Lined rectangle with alias: 'lin-rect', 'lined-rectangle', 'lin-proc', lined-process', 'shaded-process'
'lined-rectangle': shadedProcess,
'lin-rect': shadedProcess,
'lin-proc': shadedProcess,
'lined-process': shadedProcess,
'shaded-process': shadedProcess,
// Small circle with alias: 'sm-circ', 'small-circle', 'start'
'small-circle': stateStart,
'sm-circ': stateStart,
start: stateStart,
// framed circle with alias: 'stop', 'framed-circle', 'fr-circ'
stop: stateEnd,
'framed-circle': stateEnd,
'fr-circ': stateEnd,
// fork with alias: 'join', 'fork'
join: forkJoin,
fork: forkJoin,
// comment with alias: 'comment', 'brace-l'
comment: curlyBraceLeft,
'brace-l': curlyBraceLeft,
// lightening bolt with alias: 'bolt', 'com-link', 'lightning-bolt'
bolt: lightningBolt,
'com-link': lightningBolt,
'lightning-bolt': lightningBolt,
// document with alias: 'doc', 'document'
doc: waveEdgedRectangle,
document: waveEdgedRectangle,
// delay with alias: 'delay', 'half-rounded-rectangle'
delay: halfRoundedRectangle,
'half-rounded-rectangle': halfRoundedRectangle,
// horizontal cylinder with alias: 'h-cyl', 'das', 'horizontal-cylinder'
'horizontal-cylinder': tiltedCylinder,
'h-cyl': tiltedCylinder,
das: tiltedCylinder,
// lined cylinder with alias: 'lin-cyl', 'lined-cylinder', 'disk'
'lined-cylinder': linedCylinder,
'lin-cyl': linedCylinder,
disk: linedCylinder,
// curved trapezoid with alias: 'curv-trap', 'curved-trapezoid', 'display'
'curved-trapezoid': curvedTrapezoid, 'curved-trapezoid': curvedTrapezoid,
'cur-trap': curvedTrapezoid, 'curv-trap': curvedTrapezoid,
disp: curvedTrapezoid,
display: curvedTrapezoid, display: curvedTrapezoid,
// Hexagons & Misc Geometric // divided rectangle with alias: 'div-rect', 'divided-rectangle', 'div-proc', 'divided-process'
hexagon, 'divided-rectangle': dividedRectangle,
hex: hexagon, 'div-rect': dividedRectangle,
prepare: hexagon, 'div-proc': dividedRectangle,
'divided-process': dividedRectangle,
// triangle with alias: 'tri', 'triangle', 'extract'
triangle, triangle,
'small-triangle': triangle, tri: triangle,
'sm-tri': triangle,
extract: triangle, extract: triangle,
'flipped-triangle': flippedTriangle,
'flip-tri': flippedTriangle, // window pane with alias: 'window-pane', 'win-pane', 'internal-storage'
'manual-file': flippedTriangle, 'window-pane': windowPane,
'win-pane': windowPane,
'internal-storage': windowPane,
// filled circle with alias: 'f-circ', 'filled-circle', 'junction'
'f-circ': filledCircle,
junction: filledCircle,
'filled-circle': filledCircle,
// lined document with alias: 'lin-doc', 'lined-document'
'lin-doc': linedWaveEdgedRect,
'lined-document': linedWaveEdgedRect,
// notched pentagon with alias: 'notch-pent', 'notched-pentagon', 'loop-limit'
'notched-pentagon': trapezoidalPentagon, 'notched-pentagon': trapezoidalPentagon,
'notch-pent': trapezoidalPentagon, 'notch-pent': trapezoidalPentagon,
'loop-limit': trapezoidalPentagon, 'loop-limit': trapezoidalPentagon,
//wave Edged Rectangles // flipped triangle with alias: 'flip-tri', 'flipped-triangle', 'manual-file'
'wave-rectangle': waveRectangle, 'flipped-triangle': flippedTriangle,
'w-rect': waveRectangle, 'flip-tri': flippedTriangle,
'manual-file': flippedTriangle,
// sloped rectangle with alias: 'sl-rect', 'sloped-rectangle', 'manual-input'
'sloped-rectangle': slopedRect,
'sl-rect': slopedRect,
'manual-input': slopedRect,
// documents with alias: 'docs', 'documents', 'st-doc', 'stacked-document'
docs: multiWaveEdgedRectangle,
documents: multiWaveEdgedRectangle,
'st-doc': multiWaveEdgedRectangle,
'stacked-document': multiWaveEdgedRectangle,
// 'processes' with alias: 'procs', 'processes', 'st-rect', 'stacked-rectangle'
processes: multiRect,
procs: multiRect,
'stacked-rectangle': multiRect,
'st-rect': multiRect,
// flag with alias: 'flag', 'paper-tape'
flag: waveRectangle, flag: waveRectangle,
'paper-tape': waveRectangle, 'paper-tape': waveRectangle,
'wave-edge-rect': waveEdgedRectangle,
'wave-edged-rectangle': waveEdgedRectangle,
'wave-rect': waveEdgedRectangle,
'we-rect': waveEdgedRectangle,
doc: waveEdgedRectangle,
'multi-wave-edged-rectangle': multiWaveEdgedRectangle,
'mul-we-rect': multiWaveEdgedRectangle,
'mul-doc': multiWaveEdgedRectangle,
'lined-wave-edged-rect': linedWaveEdgedRect,
'lin-we-rect': linedWaveEdgedRect,
'lin-doc': linedWaveEdgedRect,
'tagged-wave-edged-rectangle': taggedWaveEdgedRectangle,
'tag-we-rect': taggedWaveEdgedRectangle,
'tag-doc': taggedWaveEdgedRectangle,
// Custom Rectangles // bow tie rectangle with alias: 'bow-rect', 'bow-tie-rectangle', 'stored-data'
'bow-tie-rect': bowTieRect, 'bow-tie-rectangle': bowTieRect,
'bt-rect': bowTieRect, 'bow-rect': bowTieRect,
'stored-data': bowTieRect, 'stored-data': bowTieRect,
'sloped-rectangle': slopedRect,
'sloped-rect': slopedRect,
'manual-input': slopedRect,
'half-rounded-rect': halfRoundedRectangle,
delay: halfRoundedRectangle,
card,
'notched-rect': card,
'notch-rect': card,
'lean-right': lean_right,
lean_right: lean_right,
'l-r': lean_right,
'in-out': lean_right,
'lean-left': lean_left,
lean_left: lean_left,
'l-l': lean_left,
'out-in': lean_left,
// Miscellaneous // crossed circle with alias: 'cross-circ', 'crossed-circle', 'summary'
forkJoin, 'crossed-circle': crossedCircle,
'long-rect': forkJoin, 'cross-circ': crossedCircle,
fork: forkJoin, summary: crossedCircle,
join: forkJoin,
choice, // tagged document with alias: 'tag-doc', 'tagged-document'
note, 'tag-doc': taggedWaveEdgedRectangle,
'tagged-document': taggedWaveEdgedRectangle,
// tagged rectangle with alias: 'tag-rect', 'tagged-rectangle', 'tag-proc', 'tagged-process'
'tag-rect': taggedRect,
'tagged-rectangle': taggedRect,
'tag-proc': taggedRect,
'tagged-process': taggedRect,
// hourglass with alias: 'hourglass', 'collate'
hourglass,
collate: hourglass,
text, text,
anchor, anchor,
diamond: question,
diam: question,
decision: question,
'lightning-bolt': lightningBolt,
bolt: lightningBolt,
'com-link': lightningBolt,
'brace-l': curlyBraceLeft,
brace: curlyBraceLeft, brace: curlyBraceLeft,
comment: curlyBraceLeft,
hourglass,
odd: rect_left_inv_arrow,
labelRect, labelRect,
'brace-r': curlyBraceRight, 'brace-r': curlyBraceRight,
braces: curlyBraces, braces: curlyBraces,
@@ -229,7 +303,7 @@ export const shapes = {
const nodeElems = new Map(); const nodeElems = new Map();
export const insertNode = async (elem, node, dir) => { export const insertNode = async (elem, node, renderOptions) => {
let newEl; let newEl;
let el; let el;
@@ -244,18 +318,22 @@ export const insertNode = async (elem, node, dir) => {
} }
} }
// Add link when appropriate if (!shapes[node.shape]) {
throw new Error(`No such shape: ${node.shape}. Please check your syntax.`);
}
if (node.link) { if (node.link) {
// Add link when appropriate
let target; let target;
if (getConfig().securityLevel === 'sandbox') { if (renderOptions.config.securityLevel === 'sandbox') {
target = '_top'; target = '_top';
} else if (node.linkTarget) { } else if (node.linkTarget) {
target = node.linkTarget || '_blank'; target = node.linkTarget || '_blank';
} }
newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target); newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target);
el = await shapes[node.shape](newEl, node, dir); el = await shapes[node.shape](newEl, node, renderOptions);
} else { } else {
el = await shapes[node.shape](elem, node, dir); el = await shapes[node.shape](elem, node, renderOptions);
newEl = el; newEl = el;
} }
// MC Special // MC Special

View File

@@ -18,14 +18,14 @@ describe('Test Alias for shapes', function () {
// stadium | pill | term // stadium | pill | term
it('should support alias for stadium shape ', function () { it('should support alias for stadium shape ', function () {
expect(shapes.pill).toBe(shapes.stadium); expect(shapes.pill).toBe(shapes.stadium);
expect(shapes.term).toBe(shapes.stadium); expect(shapes.terminal).toBe(shapes.stadium);
}); });
// fr | subproc | framed-rectangle | subroutine // fr-rect | subproc | framed-rectangle | subroutine
it('should support alias for subroutine shape ', function () { it('should support alias for subroutine shape ', function () {
expect(shapes['framed-rectangle']).toBe(shapes.fr); expect(shapes['framed-rectangle']).toBe(shapes['fr-rect']);
expect(shapes.subproc).toBe(shapes.fr); expect(shapes.subproc).toBe(shapes['fr-rect']);
expect(shapes.subroutine).toBe(shapes.fr); expect(shapes.subroutine).toBe(shapes['fr-rect']);
}); });
// cyl | db | cylinder // cyl | db | cylinder
@@ -48,13 +48,13 @@ describe('Test Alias for shapes', function () {
// l-r | lean-right | in-out // l-r | lean-right | in-out
it('should support alias for lean-right shape ', function () { it('should support alias for lean-right shape ', function () {
expect(shapes['l-r']).toBe(shapes['lean-right']); expect(shapes['lean-r']).toBe(shapes['lean-right']);
expect(shapes['in-out']).toBe(shapes['lean-right']); expect(shapes['in-out']).toBe(shapes['lean-right']);
}); });
// l-l | lean-left | out-in // l-l | lean-left | out-in
it('should support alias for lean-left shape ', function () { it('should support alias for lean-left shape ', function () {
expect(shapes['l-l']).toBe(shapes['lean-left']); expect(shapes['lean-l']).toBe(shapes['lean-left']);
expect(shapes['out-in']).toBe(shapes['lean-left']); expect(shapes['out-in']).toBe(shapes['lean-left']);
}); });
@@ -72,15 +72,15 @@ describe('Test Alias for shapes', function () {
expect(shapes['inv-trapezoid']).toBe(shapes['trap-t']); expect(shapes['inv-trapezoid']).toBe(shapes['trap-t']);
}); });
// dc | double-circle // dbl-circ| double-circle
it('should support alias for doublecircle shape ', function () { it('should support alias for doublecircle shape ', function () {
expect(shapes['double-circle']).toBe(shapes.dc); expect(shapes['double-circle']).toBe(shapes['dbl-circ']);
}); });
// notched-rect | card | notch-rect // notched-rectangle | card | notch-rect
it('should support alias for notched-rectangle shape ', function () { it('should support alias for notched-rectangle shape ', function () {
expect(shapes.card).toBe(shapes['notched-rect']); expect(shapes.card).toBe(shapes['notched-rectangle']);
expect(shapes['notch-rect']).toBe(shapes['notched-rect']); expect(shapes['notch-rect']).toBe(shapes['notched-rectangle']);
}); });
// lined-rect | lined-proc | shaded-proc // lined-rect | lined-proc | shaded-proc
@@ -100,10 +100,9 @@ describe('Test Alias for shapes', function () {
expect(shapes.stop).toBe(shapes['framed-circle']); expect(shapes.stop).toBe(shapes['framed-circle']);
}); });
// fork | join | long-rect // fork | join
it('should support alias for fork shape ', function () { it('should support alias for fork shape ', function () {
expect(shapes.join).toBe(shapes.fork); expect(shapes.join).toBe(shapes.fork);
expect(shapes['long-rect']).toBe(shapes.fork);
}); });
// brace | comment | brace-l // brace | comment | brace-l
@@ -118,35 +117,32 @@ describe('Test Alias for shapes', function () {
expect(shapes['lightning-bolt']).toBe(shapes.bolt); expect(shapes['lightning-bolt']).toBe(shapes.bolt);
}); });
// we-rect | doc | wave-edge-rect | wave-edged-rectangle // document | doc
it('should support alias for waveEdgedRectangle shape ', function () { it('should support alias for waveEdgedRectangle shape ', function () {
expect(shapes.doc).toBe(shapes['we-rect']); expect(shapes.doc).toBe(shapes.document);
expect(shapes['wave-edge-rect']).toBe(shapes['we-rect']);
expect(shapes['wave-edged-rectangle']).toBe(shapes['we-rect']);
}); });
// delay | half-rounded-rect // delay | half-rounded-rectangle
it('should support alias for halfRoundedRectangle shape ', function () { it('should support alias for halfRoundedRectangle shape ', function () {
expect(shapes.delay).toBe(shapes['half-rounded-rect']); expect(shapes.delay).toBe(shapes['half-rounded-rectangle']);
}); });
// t-cyl | das | titled-cylinder // h-cyl | das | horizontal-cylinder
it('should support alias for tilted-cylinder shape ', function () { it('should support alias for horizontal-cylinder shape ', function () {
expect(shapes.das).toBe(shapes['t-cyl']); expect(shapes.das).toBe(shapes['h-cyl']);
expect(shapes['tilted-cylinder']).toBe(shapes['t-cyl']); expect(shapes['horizontal-cylinder']).toBe(shapes['h-cyl']);
}); });
// l-cyl | disk | lined-cylinder // lin-cyl | disk | lined-cylinder
it('should support alias for linedCylinder shape ', function () { it('should support alias for linedCylinder shape ', function () {
expect(shapes.disk).toBe(shapes['l-cyl']); expect(shapes.disk).toBe(shapes['lin-cyl']);
expect(shapes['lined-cylinder']).toBe(shapes['l-cyl']); expect(shapes['lined-cylinder']).toBe(shapes['lin-cyl']);
}); });
// cur-trap | disp | display | curved-trapezoid // curv-trap | display | curved-trapezoid
it('should support alias for curvedTrapezoid shape ', function () { it('should support alias for curvedTrapezoid shape ', function () {
expect(shapes.disp).toBe(shapes['cur-trap']); expect(shapes.display).toBe(shapes['curv-trap']);
expect(shapes['curved-trapezoid']).toBe(shapes['cur-trap']); expect(shapes['curved-trapezoid']).toBe(shapes['curv-trap']);
expect(shapes.display).toBe(shapes['cur-trap']);
}); });
// div-rect | div-proc | divided-rectangle // div-rect | div-proc | divided-rectangle
@@ -157,9 +153,8 @@ describe('Test Alias for shapes', function () {
// sm-tri | extract | small-triangle | triangle // sm-tri | extract | small-triangle | triangle
it('should support alias for smallTriangle shape ', function () { it('should support alias for smallTriangle shape ', function () {
expect(shapes.extract).toBe(shapes['sm-tri']); expect(shapes.extract).toBe(shapes.tri);
expect(shapes['small-triangle']).toBe(shapes['sm-tri']); expect(shapes.triangle).toBe(shapes.tri);
expect(shapes.triangle).toBe(shapes['sm-tri']);
}); });
// win-pane | internal-storage | window-pane // win-pane | internal-storage | window-pane
@@ -170,14 +165,13 @@ describe('Test Alias for shapes', function () {
// fc | junction | filled-circle // fc | junction | filled-circle
it('should support alias for filledCircle shape ', function () { it('should support alias for filledCircle shape ', function () {
expect(shapes.junction).toBe(shapes.fc); expect(shapes.junction).toBe(shapes['f-circ']);
expect(shapes['filled-circle']).toBe(shapes.fc); expect(shapes['filled-circle']).toBe(shapes['f-circ']);
}); });
//lin-we-rect | lin-doc | lined-wave-edged-rect // | lin-doc | lined-document
it('should support alias for linedWaveEdgedRectangle shape ', function () { it('should support alias for linedWaveEdgedRectangle shape ', function () {
expect(shapes['lin-doc']).toBe(shapes['lin-we-rect']); expect(shapes['lin-doc']).toBe(shapes['lined-document']);
expect(shapes['lined-wave-edged-rect']).toBe(shapes['lin-we-rect']);
}); });
// notch-pent | loop-limit | notched-pentagon // notch-pent | loop-limit | notched-pentagon
@@ -192,22 +186,22 @@ describe('Test Alias for shapes', function () {
expect(shapes['flipped-triangle']).toBe(shapes['flip-tri']); expect(shapes['flipped-triangle']).toBe(shapes['flip-tri']);
}); });
//sloped-rect | manual-input | sloped-rectangle //sl-rect | manual-input | sloped-rectangle
it('should support alias for slopedRectangle shape ', function () { it('should support alias for slopedRectangle shape ', function () {
expect(shapes['manual-input']).toBe(shapes['sloped-rect']); expect(shapes['manual-input']).toBe(shapes['sl-rect']);
expect(shapes['sloped-rectangle']).toBe(shapes['sloped-rect']); expect(shapes['sloped-rectangle']).toBe(shapes['sl-rect']);
}); });
// mul-we-rect | mul-doc | multi-wave-edged-rectangle // docs | documents | st-doc | stacked-document
it('should support alias for multiWaveEdgedRectangle shape ', function () { it('should support alias for multiWaveEdgedRectangle shape ', function () {
expect(shapes['mul-doc']).toBe(shapes['mul-we-rect']); expect(shapes.docs).toBe(shapes.documents);
expect(shapes['multi-wave-edged-rectangle']).toBe(shapes['mul-we-rect']); expect(shapes['st-doc']).toBe(shapes['stacked-document']);
}); });
// mul-rect | mul-proc | multi-rect // procs | processes | st-rect | stacked-rectangle
it('should support alias for multiRect shape ', function () { it('should support alias for multiRect shape ', function () {
expect(shapes['mul-proc']).toBe(shapes['mul-rect']); expect(shapes.procs).toBe(shapes.processes);
expect(shapes['multi-rect']).toBe(shapes['mul-rect']); expect(shapes['st-rect']).toBe(shapes['stacked-rectangle']);
}); });
// flag | paper-tape // flag | paper-tape
@@ -215,27 +209,27 @@ describe('Test Alias for shapes', function () {
expect(shapes['paper-tape']).toBe(shapes.flag); expect(shapes['paper-tape']).toBe(shapes.flag);
}); });
// bt-rect| stored-data | bow-tie-rect // bow-rect| stored-data | bow-tie-rectangle
it('should support alias for bowTieRect shape ', function () { it('should support alias for bowTieRect shape ', function () {
expect(shapes['stored-data']).toBe(shapes['bt-rect']); expect(shapes['stored-data']).toBe(shapes['bow-rect']);
expect(shapes['bow-tie-rect']).toBe(shapes['bt-rect']); expect(shapes['bow-tie-rectangle']).toBe(shapes['bow-rect']);
}); });
// cross-circle | summary | crossed-circle // cross-circ | summary | crossed-circle
it('should support alias for crossedCircle shape ', function () { it('should support alias for crossedCircle shape ', function () {
expect(shapes.summary).toBe(shapes['cross-circle']); expect(shapes.summary).toBe(shapes['cross-circ']);
expect(shapes['crossed-circle']).toBe(shapes['cross-circle']); expect(shapes['crossed-circle']).toBe(shapes['cross-circ']);
}); });
// tag-we-rect | tag-doc | tagged-wave-edged-rectangle // tag-doc| tag-document
it('should support alias for taggedWaveEdgedRectangle shape ', function () { it('should support alias for taggedDocument shape ', function () {
expect(shapes['tag-doc']).toBe(shapes['tag-we-rect']); expect(shapes['tag-doc']).toBe(shapes['tagged-document']);
expect(shapes['tagged-wave-edged-rectangle']).toBe(shapes['tag-we-rect']);
}); });
// tag-rect | tag-proc | tagged-rect // tag-rect | tag-proc | tagged-rectangle | tagged-process
it('should support alias for taggedRect shape ', function () { it('should support alias for taggedRect shape ', function () {
expect(shapes['tag-proc']).toBe(shapes['tag-rect']); expect(shapes['tag-proc']).toBe(shapes['tag-rect']);
expect(shapes['tagged-rect']).toBe(shapes['tag-rect']); expect(shapes['tagged-rectangle']).toBe(shapes['tag-rect']);
expect(shapes['tagged-process']).toBe(shapes['tag-rect']);
}); });
}); });

View File

@@ -1,13 +1,17 @@
import { log } from '../../../logger.js'; import { log } from '../../../logger.js';
import { getNodeClasses, updateNodeBounds } from './util.js'; import { getNodeClasses, updateNodeBounds } from './util.js';
import type { Node } from '../../types.d.ts'; import type { Node, RenderOptions } from '../../types.d.ts';
import type { SVG } from '../../../diagram-api/types.js'; import type { SVG } from '../../../diagram-api/types.js';
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import rough from 'roughjs'; import rough from 'roughjs';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import { getConfig } from '../../../config.js';
export const filledCircle = (parent: SVG, node: Node) => { export const filledCircle = (
parent: SVG,
node: Node,
{ config: { themeVariables } }: RenderOptions
) => {
const { labelStyles, nodeStyles } = styles2String(node);
node.label = ''; node.label = '';
const shapeSvg = parent const shapeSvg = parent
.insert('g') .insert('g')
@@ -18,7 +22,6 @@ export const filledCircle = (parent: SVG, node: Node) => {
// @ts-ignore - rough is not typed // @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg); const rc = rough.svg(shapeSvg);
const { themeVariables } = getConfig();
const { nodeBorder } = themeVariables; const { nodeBorder } = themeVariables;
const options = userNodeOverrides(node, { fillStyle: 'solid' }); const options = userNodeOverrides(node, { fillStyle: 'solid' });

View File

@@ -1,21 +1,26 @@
import { log } from '../../../logger.js'; import { log } from '../../../logger.js';
import { labelHelper, updateNodeBounds } from './util.js'; import { labelHelper, updateNodeBounds } from './util.js';
import type { Node } from '../../types.d.ts'; import type { Node, RenderOptions } from '../../types.d.ts';
import type { SVG } from '../../../diagram-api/types.js'; import type { SVG } from '../../../diagram-api/types.js';
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import rough from 'roughjs'; import rough from 'roughjs';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import { getIconSVG } from '../../icons.js'; import { getIconSVG } from '../../icons.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
export const icon = async (parent: SVG, node: Node) => { export const icon = async (
parent: SVG,
node: Node,
{ config: { themeVariables, flowchart } }: RenderOptions
) => {
const { labelStyles } = styles2String(node); const { labelStyles } = styles2String(node);
node.labelStyle = labelStyles; node.labelStyle = labelStyles;
const assetHeight = node.assetHeight ?? 48; const assetHeight = node.assetHeight ?? 48;
const assetWidth = node.assetWidth ?? 48; const assetWidth = node.assetWidth ?? 48;
const iconSize = Math.max(assetHeight, assetWidth); const iconSize = Math.max(assetHeight, assetWidth);
const defaultWidth = getConfig()?.flowchart?.wrappingWidth; const defaultWidth = flowchart?.wrappingWidth;
node.width = Math.max(iconSize, defaultWidth ?? 0); node.width = Math.max(iconSize, defaultWidth ?? 0);
const { nodeBorder } = themeVariables;
const { stylesMap } = compileStyles(node);
const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default'); const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default');
const topLabel = node.pos === 't'; const topLabel = node.pos === 't';
@@ -51,6 +56,7 @@ export const icon = async (parent: SVG, node: Node) => {
'transform', 'transform',
`translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight + bbox.height / 2 : -height / 2 - bbox.height / 2})` `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight + bbox.height / 2 : -height / 2 - bbox.height / 2})`
); );
iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
} }
label.attr( label.attr(

View File

@@ -1,36 +1,35 @@
import { log } from '../../../logger.js'; import { log } from '../../../logger.js';
import { labelHelper, updateNodeBounds } from './util.js'; import { labelHelper, updateNodeBounds } from './util.js';
import type { Node } from '../../types.d.ts'; import type { Node, RenderOptions } from '../../types.d.ts';
import type { SVG } from '../../../diagram-api/types.js'; import type { SVG } from '../../../diagram-api/types.js';
import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import rough from 'roughjs'; import rough from 'roughjs';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import { getIconSVG } from '../../icons.js'; import { getIconSVG } from '../../icons.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
export const iconCircle = async (parent: SVG, node: Node, dir: string) => { export const iconCircle = async (
const translateHorizontal = dir === 'TB' || dir === 'BT' || dir === 'TD' || dir === 'DT'; parent: SVG,
const { labelStyles, nodeStyles } = styles2String(node); node: Node,
{ config: { themeVariables, flowchart } }: RenderOptions
) => {
const { labelStyles } = styles2String(node);
node.labelStyle = labelStyles; node.labelStyle = labelStyles;
const assetHeight = node.assetHeight ?? 48; const assetHeight = node.assetHeight ?? 48;
const assetWidth = node.assetWidth ?? 48; const assetWidth = node.assetWidth ?? 48;
const iconSize = Math.max(assetHeight, assetWidth); const iconSize = Math.max(assetHeight, assetWidth);
const defaultWidth = getConfig()?.flowchart?.wrappingWidth; const defaultWidth = flowchart?.wrappingWidth;
node.width = Math.max(iconSize, defaultWidth ?? 0); node.width = Math.max(iconSize, defaultWidth ?? 0);
const { shapeSvg, bbox, halfPadding, label } = await labelHelper( const { shapeSvg, bbox, halfPadding, label } = await labelHelper(
parent, parent,
node, node,
'icon-shape default' 'icon-shape default'
); );
const { cssStyles } = node;
const topLabel = node.pos === 't'; const topLabel = node.pos === 't';
const diameter = iconSize + halfPadding * 2; const diameter = iconSize + halfPadding * 2;
const { themeVariables } = getConfig(); const { nodeBorder, mainBkg } = themeVariables;
const { mainBkg } = themeVariables;
const { stylesMap } = compileStyles(node); const { stylesMap } = compileStyles(node);
// @ts-ignore - rough is not typed // @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg); const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') || mainBkg }); const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') || mainBkg });
@@ -43,9 +42,8 @@ export const iconCircle = async (parent: SVG, node: Node, dir: string) => {
const iconNode = rc.circle(0, 0, diameter, options); const iconNode = rc.circle(0, 0, diameter, options);
const iconShape = shapeSvg.insert(() => iconNode, ':first-child'); const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
const iconElem = shapeSvg.append('g');
if (node.icon) { if (node.icon) {
const iconElem = shapeSvg.append('g');
iconElem.html( iconElem.html(
`<g>${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}</g>` `<g>${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}</g>`
); );
@@ -54,26 +52,17 @@ export const iconCircle = async (parent: SVG, node: Node, dir: string) => {
const iconHeight = iconBBox.height; const iconHeight = iconBBox.height;
iconElem.attr( iconElem.attr(
'transform', 'transform',
`translate(${-iconWidth / 2},${topLabel ? diameter / 2 - iconHeight - halfPadding + (translateHorizontal ? bbox.height / 2 : 0) : -diameter / 2 + halfPadding - (translateHorizontal ? bbox.height / 2 : 0)})` `translate(${-iconWidth / 2},${topLabel ? diameter / 2 - iconHeight - halfPadding + bbox.height / 2 : -diameter / 2 + halfPadding - bbox.height / 2})`
); );
iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
} }
label.attr( label.attr(
'transform', 'transform',
`translate(${-diameter / 2 + diameter / 2 - bbox.width / 2},${topLabel ? -diameter / 2 - 2.5 - (translateHorizontal ? bbox.height / 2 : bbox.height) : diameter / 2 + 5 - (translateHorizontal ? bbox.height / 2 : 0)})` `translate(${-diameter / 2 + diameter / 2 - bbox.width / 2},${topLabel ? -diameter / 2 - bbox.height / 2 : diameter / 2 - bbox.height / 2})`
); );
if (translateHorizontal) { iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
}
if (cssStyles && node.look !== 'handDrawn') {
iconShape.selectAll('path').attr('style', cssStyles);
}
if (nodeStyles && node.look !== 'handDrawn') {
iconShape.selectAll('path').attr('style', nodeStyles);
}
updateNodeBounds(node, shapeSvg); updateNodeBounds(node, shapeSvg);

View File

@@ -1,35 +1,36 @@
import { log } from '../../../logger.js'; import { log } from '../../../logger.js';
import { labelHelper, updateNodeBounds } from './util.js'; import { labelHelper, updateNodeBounds } from './util.js';
import type { Node } from '../../types.js'; import type { Node, RenderOptions } from '../../types.js';
import type { SVG } from '../../../diagram-api/types.js'; import type { SVG } from '../../../diagram-api/types.js';
import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import rough from 'roughjs'; import rough from 'roughjs';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import { getIconSVG } from '../../icons.js'; import { getIconSVG } from '../../icons.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
import { createRoundedRectPathD } from './roundedRectPath.js'; import { createRoundedRectPathD } from './roundedRectPath.js';
export const iconRounded = async (parent: SVG, node: Node) => { export const iconRounded = async (
const { labelStyles, nodeStyles } = styles2String(node); parent: SVG,
node: Node,
{ config: { themeVariables, flowchart } }: RenderOptions
) => {
const { labelStyles } = styles2String(node);
node.labelStyle = labelStyles; node.labelStyle = labelStyles;
const assetHeight = node.assetHeight ?? 48; const assetHeight = node.assetHeight ?? 48;
const assetWidth = node.assetWidth ?? 48; const assetWidth = node.assetWidth ?? 48;
const iconSize = Math.max(assetHeight, assetWidth); const iconSize = Math.max(assetHeight, assetWidth);
const defaultWidth = getConfig()?.flowchart?.wrappingWidth; const defaultWidth = flowchart?.wrappingWidth;
node.width = Math.max(iconSize, defaultWidth ?? 0); node.width = Math.max(iconSize, defaultWidth ?? 0);
const { shapeSvg, bbox, halfPadding, label } = await labelHelper( const { shapeSvg, bbox, halfPadding, label } = await labelHelper(
parent, parent,
node, node,
'icon-shape default' 'icon-shape default'
); );
const { cssStyles } = node;
const topLabel = node.pos === 't'; const topLabel = node.pos === 't';
const height = iconSize + halfPadding * 2; const height = iconSize + halfPadding * 2;
const width = iconSize + halfPadding * 2; const width = iconSize + halfPadding * 2;
const { themeVariables } = getConfig(); const { nodeBorder, mainBkg } = themeVariables;
const { mainBkg } = themeVariables;
const { stylesMap } = compileStyles(node); const { stylesMap } = compileStyles(node);
const x = -width / 2; const x = -width / 2;
@@ -58,8 +59,9 @@ export const iconRounded = async (parent: SVG, node: Node) => {
const iconHeight = iconBBox.height; const iconHeight = iconBBox.height;
iconElem.attr( iconElem.attr(
'transform', 'transform',
`translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight + bbox.height / 2 : -height / 2 - bbox.height / 2})` `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + bbox.height / 2 : -height / 2 + halfPadding - bbox.height / 2})`
); );
iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
} }
label.attr( label.attr(
@@ -69,14 +71,6 @@ export const iconRounded = async (parent: SVG, node: Node) => {
iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`); iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
if (cssStyles && node.look !== 'handDrawn') {
iconShape.selectAll('path').attr('style', cssStyles);
}
if (nodeStyles && node.look !== 'handDrawn') {
iconShape.selectAll('path').attr('style', nodeStyles);
}
updateNodeBounds(node, shapeSvg); updateNodeBounds(node, shapeSvg);
node.intersect = function (point) { node.intersect = function (point) {

View File

@@ -1,34 +1,35 @@
import { log } from '../../../logger.js'; import { log } from '../../../logger.js';
import { labelHelper, updateNodeBounds } from './util.js'; import { labelHelper, updateNodeBounds } from './util.js';
import type { Node } from '../../types.d.ts'; import type { Node, RenderOptions } from '../../types.d.ts';
import type { SVG } from '../../../diagram-api/types.js'; import type { SVG } from '../../../diagram-api/types.js';
import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import rough from 'roughjs'; import rough from 'roughjs';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import { getIconSVG } from '../../icons.js'; import { getIconSVG } from '../../icons.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
export const iconSquare = async (parent: SVG, node: Node) => { export const iconSquare = async (
const { labelStyles, nodeStyles } = styles2String(node); parent: SVG,
node: Node,
{ config: { themeVariables, flowchart } }: RenderOptions
) => {
const { labelStyles } = styles2String(node);
node.labelStyle = labelStyles; node.labelStyle = labelStyles;
const assetHeight = node.assetHeight ?? 48; const assetHeight = node.assetHeight ?? 48;
const assetWidth = node.assetWidth ?? 48; const assetWidth = node.assetWidth ?? 48;
const iconSize = Math.max(assetHeight, assetWidth); const iconSize = Math.max(assetHeight, assetWidth);
const defaultWidth = getConfig()?.flowchart?.wrappingWidth; const defaultWidth = flowchart?.wrappingWidth;
node.width = Math.max(iconSize, defaultWidth ?? 0); node.width = Math.max(iconSize, defaultWidth ?? 0);
const { shapeSvg, bbox, halfPadding, label } = await labelHelper( const { shapeSvg, bbox, halfPadding, label } = await labelHelper(
parent, parent,
node, node,
'icon-shape default' 'icon-shape default'
); );
const { cssStyles } = node;
const topLabel = node.pos === 't'; const topLabel = node.pos === 't';
const height = iconSize + halfPadding * 2; const height = iconSize + halfPadding * 2;
const width = iconSize + halfPadding * 2; const width = iconSize + halfPadding * 2;
const { themeVariables } = getConfig(); const { nodeBorder, mainBkg } = themeVariables;
const { mainBkg } = themeVariables;
const { stylesMap } = compileStyles(node); const { stylesMap } = compileStyles(node);
const x = -width / 2; const x = -width / 2;
@@ -59,6 +60,7 @@ export const iconSquare = async (parent: SVG, node: Node) => {
'transform', 'transform',
`translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + bbox.height / 2 : -height / 2 + halfPadding - bbox.height / 2})` `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + bbox.height / 2 : -height / 2 + halfPadding - bbox.height / 2})`
); );
iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
} }
label.attr( label.attr(
@@ -68,14 +70,6 @@ export const iconSquare = async (parent: SVG, node: Node) => {
iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`); iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
if (cssStyles && node.look !== 'handDrawn') {
iconShape.selectAll('path').attr('style', cssStyles);
}
if (nodeStyles && node.look !== 'handDrawn') {
iconShape.selectAll('path').attr('style', nodeStyles);
}
updateNodeBounds(node, shapeSvg); updateNodeBounds(node, shapeSvg);
node.intersect = function (point) { node.intersect = function (point) {

View File

@@ -1,16 +1,18 @@
import { updateNodeBounds } from './util.js'; import { updateNodeBounds } from './util.js';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import type { Node } from '../../types.js'; import type { Node, RenderOptions } from '../../types.js';
import type { SVG } from '../../../diagram-api/types.js'; import type { SVG } from '../../../diagram-api/types.js';
import rough from 'roughjs'; import rough from 'roughjs';
import { solidStateFill, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import { solidStateFill, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
export const stateEnd = (parent: SVG, node: Node) => { export const stateEnd = (
parent: SVG,
node: Node,
{ config: { themeVariables } }: RenderOptions
) => {
const { labelStyles, nodeStyles } = styles2String(node); const { labelStyles, nodeStyles } = styles2String(node);
node.labelStyle = labelStyles; node.labelStyle = labelStyles;
const { cssStyles } = node; const { cssStyles } = node;
const { themeVariables } = getConfig();
const { lineColor } = themeVariables; const { lineColor } = themeVariables;
const shapeSvg = parent const shapeSvg = parent
.insert('g') .insert('g')

View File

@@ -1,13 +1,15 @@
import { updateNodeBounds } from './util.js'; import { updateNodeBounds } from './util.js';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import type { Node } from '../../types.js'; import type { Node, RenderOptions } from '../../types.js';
import type { SVG } from '../../../diagram-api/types.js'; import type { SVG } from '../../../diagram-api/types.js';
import rough from 'roughjs'; import rough from 'roughjs';
import { solidStateFill } from './handDrawnShapeStyles.js'; import { solidStateFill } from './handDrawnShapeStyles.js';
import { getConfig } from '../../../diagram-api/diagramAPI.js';
export const stateStart = (parent: SVG, node: Node) => { export const stateStart = (
const { themeVariables } = getConfig(); parent: SVG,
node: Node,
{ config: { themeVariables } }: RenderOptions
) => {
const { lineColor } = themeVariables; const { lineColor } = themeVariables;
const shapeSvg = parent const shapeSvg = parent

View File

@@ -140,3 +140,7 @@ export type LayoutMethod =
| 'fdp' | 'fdp'
| 'osage' | 'osage'
| 'grid'; | 'grid';
export interface RenderOptions {
config: MermaidConfig;
}