Merge pull request #3210 from mermaid-js/3061_refactoring_and_modularisation

3061 refactoring and modularisation
This commit is contained in:
Knut Sveidqvist 2022-07-10 07:33:47 +02:00 committed by GitHub
commit c20c362557
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 583 additions and 721 deletions

View File

@ -31,14 +31,15 @@
<div class="mermaid2" style="width: 50%;"> <div class="mermaid2" style="width: 50%;">
journey journey
title Adding journey diagram functionality to mermaid title My working day
accTitle: Adding acc journey diagram functionality to mermaid section Go to work
accDescr { Make tea: 5: Me
My multi-line description Go upstairs: 3: Me
of the diagram Do work: 1: Me, Cat
} section Go home
section Order from website Go downstairs: 5: Me
Sit down: 5: Mee
</div> </div>
<div class="mermaid2" style="width: 50%;"> <div class="mermaid2" style="width: 50%;">
pie pie
@ -52,20 +53,16 @@
"Iron" : 5 "Iron" : 5
</div> </div>
<div class="mermaid2" style="width: 50%;"> <div class="mermaid2" style="width: 50%;">
gitGraph gitGraph
accTitle: My Gitgraph Accessibility Title commit
accDescr: My Gitgraph Accessibility Description commit
branch develop
commit commit
commit commit
branch develop commit
checkout develop checkout main
commit commit
commit commit
checkout main
merge develop
commit
commit
</div> </div>
<div class="mermaid2" style="width: 50%;"> <div class="mermaid2" style="width: 50%;">
sequenceDiagram sequenceDiagram
@ -99,6 +96,9 @@ graph TD
Sit down: 5: Me Sit down: 5: Me
</div> </div>
<div class="mermaid2" style="width: 100%;"> <div class="mermaid2" style="width: 100%;">
info
</div>
<div class="mermaid2" style="width: 100%;">
requirementDiagram requirementDiagram
accTitle: My req Diagram accTitle: My req Diagram
accDescr: My req Diagram Description accDescr: My req Diagram Description
@ -138,8 +138,41 @@ requirementDiagram
test_req - traces -> test_req2 test_req - traces -> test_req2
test_req - contains -> test_req3 test_req - contains -> test_req3
test_req <- copies - test_entity2 test_req <- copies - test_entity2
</div> </div>
<div class="mermaid" style="width: 100%;"> <div class="mermaid2" style="width: 100%;">
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid
excludes weekends
%% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)
section A section
Completed task :done, des1, 2014-01-06,2014-01-08
Active task :active, des2, 2014-01-09, 3d
Future task : des3, after des2, 5d
Future task2 : des4, after des3, 5d
section Critical tasks
Completed task in the critical line :crit, done, 2014-01-06,24h
Implement parser and jison :crit, done, after des1, 2d
Create tests for parser :crit, active, 3d
Future task in critical line :crit, 5d
Create tests for renderer :2d
Add to mermaid :1d
Functionality added :milestone, 2014-01-25, 0d
section Documentation
Describe gantt syntax :active, a1, after des1, 3d
Add gantt diagram to demo page :after a1 , 20h
Add another diagram to demo page :doc1, after a1 , 48h
section Last section
Describe gantt syntax :after doc1, 3d
Add gantt diagram to demo page :20h
Add another diagram to demo page :48h
</div>
<div class="mermaid2" style="width: 100%;">
stateDiagram stateDiagram
state Active { state Active {
Idle Idle
@ -148,7 +181,7 @@ stateDiagram
Active --> Active: LOG Active --> Active: LOG
</div> </div>
<div class="mermaid2" style="width: 100%;"> <div class="mermaid2" style="width: 100%;">
graph TB flowchart TB
accTitle: My flowchart accTitle: My flowchart
accDescr: My flowchart Description accDescr: My flowchart Description
subgraph One subgraph One
@ -165,8 +198,7 @@ stateDiagram
end end
end end
end end
B ->> A: Return B ->> A: Return</div>
</div>
<div class="mermaid2" style="width: 100%;"> <div class="mermaid2" style="width: 100%;">
classDiagram classDiagram
accTitle: My class diagram accTitle: My class diagram
@ -185,7 +217,7 @@ class Class10 {
size() size()
} }
</div> </div>
<div class="mermaid2" style="width: 100%;"> <div class="mermaid" style="width: 100%;">
stateDiagram stateDiagram
accTitle: Apa accTitle: Apa
accDescr: One that can climb better then any man accDescr: One that can climb better then any man
@ -215,6 +247,21 @@ class Class10 {
+run() +run()
} }
</div> </div>
<div class="mermaid2" style="width: 100%;">
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string registrationNumber
string make
string model
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string firstName
string lastName
int age
}
</div>
<script src="./mermaid.js"></script> <script src="./mermaid.js"></script>
<script> <script>
@ -251,6 +298,7 @@ class Class10 {
state: { state: {
nodeSpacing: 50, nodeSpacing: 50,
rankSpacing: 50, rankSpacing: 50,
defaultRenderer: 'dagre-d3',
}, },
logLevel: 0, logLevel: 0,
fontSize: 18, fontSize: 18,

View File

@ -57,22 +57,30 @@ class Diagram {
this.parser.parser.yy = c4Db; this.parser.parser.yy = c4Db;
this.db = c4Db; this.db = c4Db;
this.renderer = c4Renderer; this.renderer = c4Renderer;
this.renderer.setConf(cnf.c4);
break; break;
case 'gitGraph': case 'gitGraph':
this.parser = gitGraphParser; this.parser = gitGraphParser;
this.parser.parser.yy = gitGraphAst; this.parser.parser.yy = gitGraphAst;
this.db = gitGraphAst; this.db = gitGraphAst;
this.renderer = gitGraphRenderer; this.renderer = gitGraphRenderer;
this.txt = this.txt + '\n';
break; break;
case 'flowchart': case 'flowchart':
flowRenderer.setConf(cnf.flowchart);
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
flowDb.clear(); flowDb.clear();
flowDb.setGen('gen-1');
this.parser = flowParser; this.parser = flowParser;
this.parser.parser.yy = flowDb; this.parser.parser.yy = flowDb;
this.db = flowDb; this.db = flowDb;
this.renderer = flowRenderer; this.renderer = flowRenderer;
break; break;
case 'flowchart-v2': case 'flowchart-v2':
flowRendererV2.setConf(cnf.flowchart);
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
flowDb.clear(); flowDb.clear();
flowDb.setGen('gen-2');
this.parser = flowParser; this.parser = flowParser;
this.parser.parser.yy = flowDb; this.parser.parser.yy = flowDb;
this.db = flowDb; this.db = flowDb;
@ -80,39 +88,60 @@ class Diagram {
break; break;
case 'sequenceDiagram': case 'sequenceDiagram':
case 'sequence': case 'sequence':
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
if (cnf.sequenceDiagram) {
// backwards compatibility
sequenceRenderer.setConf(Object.assign(cnf.sequence, cnf.sequenceDiagram));
console.error(
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
);
}
this.parser = sequenceParser; this.parser = sequenceParser;
this.parser.parser.yy = sequenceDb; this.parser.parser.yy = sequenceDb;
this.db = sequenceDb; this.db = sequenceDb;
this.db.setWrap(cnf.wrap);
this.renderer = sequenceRenderer; this.renderer = sequenceRenderer;
this.renderer.setConf(cnf.sequence);
this.txt = this.txt + '\n';
break; break;
case 'gantt': case 'gantt':
cnf.gantt.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
this.parser = ganttParser; this.parser = ganttParser;
this.parser.parser.yy = ganttDb; this.parser.parser.yy = ganttDb;
this.db = ganttDb; this.db = ganttDb;
this.renderer = ganttRenderer; this.renderer = ganttRenderer;
ganttRenderer.setConf(cnf.gantt);
break; break;
case 'class': case 'class':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
this.parser = classParser; this.parser = classParser;
this.parser.parser.yy = classDb; this.parser.parser.yy = classDb;
this.db = classDb; this.db = classDb;
this.db.clear();
this.renderer = classRenderer; this.renderer = classRenderer;
break; break;
case 'classDiagram': case 'classDiagram':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
this.parser = classParser; this.parser = classParser;
this.parser.parser.yy = classDb; this.parser.parser.yy = classDb;
this.db = classDb; this.db = classDb;
this.db.clear();
this.renderer = classRendererV2; this.renderer = classRendererV2;
break; break;
case 'state': case 'state':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
this.parser = stateParser; this.parser = stateParser;
this.parser.parser.yy = stateDb; this.parser.parser.yy = stateDb;
this.db = stateDb; this.db = stateDb;
this.db.clear();
this.renderer = stateRenderer; this.renderer = stateRenderer;
break; break;
case 'stateDiagram': case 'stateDiagram':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
this.parser = stateParser; this.parser = stateParser;
this.parser.parser.yy = stateDb; this.parser.parser.yy = stateDb;
this.db = stateDb; this.db = stateDb;
this.db.clear();
this.renderer = stateRendererV2; this.renderer = stateRendererV2;
break; break;
case 'info': case 'info':
@ -138,9 +167,11 @@ class Diagram {
break; break;
case 'journey': case 'journey':
log.debug('Journey'); log.debug('Journey');
journeyRenderer.setConf(cnf.journey);
this.parser = journeyParser; this.parser = journeyParser;
this.parser.parser.yy = journeyDb; this.parser.parser.yy = journeyDb;
this.db = journeyDb; this.db = journeyDb;
this.db.clear();
this.renderer = journeyRenderer; this.renderer = journeyRenderer;
break; break;
case 'requirement': case 'requirement':
@ -160,7 +191,7 @@ class Diagram {
const error = { str, hash }; const error = { str, hash };
throw error; throw error;
}; };
this.parser.parse(txt); this.parser.parse(this.txt);
} }
getParser() { getParser() {
return this.parser; return this.parser;

View File

@ -817,6 +817,9 @@ const config = {
}, },
class: { class: {
arrowMarkerAbsolute: false, arrowMarkerAbsolute: false,
dividerMargin: 10,
padding: 5,
textHeight: 10,
/** /**
* | Parameter | Description | Type | Required | Values | * | Parameter | Description | Type | Required | Values |

View File

@ -0,0 +1,9 @@
const diagrams = {};
export const registerDiagram = (id, parser, identifier, renderer) => {
diagrams[id] = { parser, identifier, renderer };
};
export const getDiagrams = () => {
return diagrams;
};

View File

@ -25,7 +25,7 @@ parser.yy = c4Db;
let conf = {}; let conf = {};
class Bounds { class Bounds {
constructor() { constructor(diagObj) {
this.name = ''; this.name = '';
this.data = {}; this.data = {};
this.data.startx = undefined; this.data.startx = undefined;
@ -41,7 +41,7 @@ class Bounds {
this.nextData.stopy = undefined; this.nextData.stopy = undefined;
this.nextData.cnt = 0; this.nextData.cnt = 0;
setConf(parser.yy.getConfig()); setConf(diagObj.db.getConfig());
} }
setData(startx, stopx, starty, stopy) { setData(startx, stopx, starty, stopy) {
@ -96,7 +96,7 @@ class Bounds {
this.updateVal(this.nextData, 'stopy', _stopy, Math.max); this.updateVal(this.nextData, 'stopy', _stopy, Math.max);
} }
init() { init(diagObj) {
this.name = ''; this.name = '';
this.data = { this.data = {
startx: undefined, startx: undefined,
@ -112,7 +112,7 @@ class Bounds {
stopy: undefined, stopy: undefined,
cnt: 0, cnt: 0,
}; };
setConf(parser.yy.getConfig()); setConf(diagObj.db.getConfig());
} }
bumpLastMargin(margin) { bumpLastMargin(margin) {
@ -411,13 +411,13 @@ let getIntersectPoints = function (fromNode, endNode) {
return { startPoint: startPoint, endPoint: endPoint }; return { startPoint: startPoint, endPoint: endPoint };
}; };
export const drawRels = function (diagram, rels, getC4ShapeObj) { export const drawRels = function (diagram, rels, getC4ShapeObj, diagObj) {
let i = 0; let i = 0;
for (let rel of rels) { for (let rel of rels) {
i = i + 1; i = i + 1;
let relTextWrap = rel.wrap && conf.wrap; let relTextWrap = rel.wrap && conf.wrap;
let relConf = messageFont(conf); let relConf = messageFont(conf);
let diagramType = parser.yy.getC4Type(); let diagramType = diagObj.db.getC4Type();
if (diagramType === 'C4Dynamic') rel.label.text = i + ': ' + rel.label.text; if (diagramType === 'C4Dynamic') rel.label.text = i + ': ' + rel.label.text;
let textLimitWidth = calculateTextWidth(rel.label.text, relConf); let textLimitWidth = calculateTextWidth(rel.label.text, relConf);
calcC4ShapeTextWH('label', rel, relTextWrap, relConf, textLimitWidth); calcC4ShapeTextWH('label', rel, relTextWrap, relConf, textLimitWidth);
@ -446,9 +446,10 @@ export const drawRels = function (diagram, rels, getC4ShapeObj) {
* @param parentBoundaryAlias * @param parentBoundaryAlias
* @param parentBounds * @param parentBounds
* @param currentBoundarys * @param currentBoundarys
* @param diagObj
*/ */
function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentBoundarys) { function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentBoundarys, diagObj) {
let currentBounds = new Bounds(); let currentBounds = new Bounds(diagObj);
// Calculate the width limit of the boundar. label/type 的长度, // Calculate the width limit of the boundar. label/type 的长度,
currentBounds.data.widthLimit = currentBounds.data.widthLimit =
parentBounds.data.widthLimit / Math.min(c4BoundaryInRow, currentBoundarys.length); parentBounds.data.widthLimit / Math.min(c4BoundaryInRow, currentBoundarys.length);
@ -527,8 +528,8 @@ function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentB
currentBounds.setData(_x, _x, _y, _y); currentBounds.setData(_x, _x, _y, _y);
} }
currentBounds.name = currentBoundary.alias; currentBounds.name = currentBoundary.alias;
let currentPersonOrSystemArray = parser.yy.getC4ShapeArray(currentBoundary.alias); let currentPersonOrSystemArray = diagObj.db.getC4ShapeArray(currentBoundary.alias);
let currentPersonOrSystemKeys = parser.yy.getC4ShapeKeys(currentBoundary.alias); let currentPersonOrSystemKeys = diagObj.db.getC4ShapeKeys(currentBoundary.alias);
if (currentPersonOrSystemKeys.length > 0) { if (currentPersonOrSystemKeys.length > 0) {
drawC4ShapeArray( drawC4ShapeArray(
@ -539,13 +540,19 @@ function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentB
); );
} }
parentBoundaryAlias = currentBoundary.alias; parentBoundaryAlias = currentBoundary.alias;
let nextCurrentBoundarys = parser.yy.getBoundarys(parentBoundaryAlias); let nextCurrentBoundarys = diagObj.db.getBoundarys(parentBoundaryAlias);
if (nextCurrentBoundarys.length > 0) { if (nextCurrentBoundarys.length > 0) {
// draw boundary inside currentBoundary // draw boundary inside currentBoundary
// bounds.init(); // bounds.init();
// parentBoundaryWidthLimit = bounds.data.stopx - bounds.startx; // parentBoundaryWidthLimit = bounds.data.stopx - bounds.startx;
drawInsideBoundary(diagram, parentBoundaryAlias, currentBounds, nextCurrentBoundarys); drawInsideBoundary(
diagram,
parentBoundaryAlias,
currentBounds,
nextCurrentBoundarys,
diagObj
);
} }
// draw boundary // draw boundary
if (currentBoundary.alias !== 'global') drawBoundary(diagram, currentBoundary, currentBounds); if (currentBoundary.alias !== 'global') drawBoundary(diagram, currentBoundary, currentBounds);
@ -566,9 +573,12 @@ function drawInsideBoundary(diagram, parentBoundaryAlias, parentBounds, currentB
* Draws a sequenceDiagram in the tag with id: id based on the graph definition in text. * Draws a sequenceDiagram in the tag with id: id based on the graph definition in text.
* *
* @param {any} text * @param {any} text
* @param _text
* @param {any} id * @param {any} id
* @param _version
* @param diagObj
*/ */
export const draw = function (text, id) { export const draw = function (_text, id, _version, diagObj) {
conf = configApi.getConfig().c4; conf = configApi.getConfig().c4;
const securityLevel = configApi.getConfig().securityLevel; const securityLevel = configApi.getConfig().securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sanbox mode
@ -580,13 +590,10 @@ export const draw = function (text, id) {
securityLevel === 'sandbox' securityLevel === 'sandbox'
? select(sandboxElement.nodes()[0].contentDocument.body) ? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body'); : select('body');
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
let db = parser.yy; let db = diagObj.db;
parser.yy.clear(); diagObj.db.setWrap(conf.wrap);
parser.yy.setWrap(conf.wrap);
parser.parse(text + '\n');
c4ShapeInRow = db.getC4ShapeInRow(); c4ShapeInRow = db.getC4ShapeInRow();
c4BoundaryInRow = db.getC4BoundaryInRow(); c4BoundaryInRow = db.getC4BoundaryInRow();
@ -600,7 +607,7 @@ export const draw = function (text, id) {
svgDraw.insertDatabaseIcon(diagram); svgDraw.insertDatabaseIcon(diagram);
svgDraw.insertClockIcon(diagram); svgDraw.insertClockIcon(diagram);
let screenBounds = new Bounds(); let screenBounds = new Bounds(diagObj);
screenBounds.setData( screenBounds.setData(
conf.diagramMarginX, conf.diagramMarginX,
@ -613,12 +620,12 @@ export const draw = function (text, id) {
globalBoundaryMaxX = conf.diagramMarginX; globalBoundaryMaxX = conf.diagramMarginX;
globalBoundaryMaxY = conf.diagramMarginY; globalBoundaryMaxY = conf.diagramMarginY;
const title = parser.yy.getTitle(); const title = diagObj.db.getTitle();
const c4type = parser.yy.getC4Type(); const c4type = diagObj.db.getC4Type();
let currentBoundarys = parser.yy.getBoundarys(''); let currentBoundarys = diagObj.db.getBoundarys('');
// switch (c4type) { // switch (c4type) {
// case 'C4Context': // case 'C4Context':
drawInsideBoundary(diagram, '', screenBounds, currentBoundarys); drawInsideBoundary(diagram, '', screenBounds, currentBoundarys, diagObj);
// break; // break;
// } // }
@ -628,7 +635,7 @@ export const draw = function (text, id) {
svgDraw.insertArrowCrossHead(diagram); svgDraw.insertArrowCrossHead(diagram);
svgDraw.insertArrowFilledHead(diagram); svgDraw.insertArrowFilledHead(diagram);
drawRels(diagram, parser.yy.getRels(), parser.yy.getC4Shape); drawRels(diagram, diagObj.db.getRels(), diagObj.db.getC4Shape, diagObj);
screenBounds.data.stopx = globalBoundaryMaxX; screenBounds.data.stopx = globalBoundaryMaxX;
screenBounds.data.stopy = globalBoundaryMaxY; screenBounds.data.stopy = globalBoundaryMaxY;

View File

@ -1,10 +1,6 @@
import { select } from 'd3'; import { select } from 'd3';
import dagre from 'dagre';
import graphlib from 'graphlib'; import graphlib from 'graphlib';
import { log } from '../../logger'; import { log } from '../../logger';
import classDb, { lookUpDomId } from './classDb';
import { parser } from './parser/classDiagram';
import svgDraw from './svgDraw';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import { render } from '../../dagre-wrapper/index.js'; import { render } from '../../dagre-wrapper/index.js';
// import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; // import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
@ -13,14 +9,12 @@ import { interpolateToCurve, getStylesFromArray, setupGraphViewbox } from '../..
import common from '../common/common'; import common from '../common/common';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
parser.yy = classDb;
let idCache = {}; let idCache = {};
const padding = 20; const padding = 20;
const sanitizeText = (txt) => common.sanitizeText(txt, getConfig()); const sanitizeText = (txt) => common.sanitizeText(txt, getConfig());
const conf = { let conf = {
dividerMargin: 10, dividerMargin: 10,
padding: 5, padding: 5,
textHeight: 10, textHeight: 10,
@ -144,6 +138,7 @@ export const addClasses = function (classes, g) {
* @param {object} g The graph object * @param {object} g The graph object
*/ */
export const addRelations = function (relations, g) { export const addRelations = function (relations, g) {
const conf = getConfig().flowchart;
let cnt = 0; let cnt = 0;
let defaultStyle; let defaultStyle;
@ -269,16 +264,18 @@ export const setConf = function (cnf) {
* *
* @param {string} text * @param {string} text
* @param {string} id * @param {string} id
* @param _version
* @param diagObj
*/ */
export const draw = function (text, id) { export const draw = function (text, id, _version, diagObj) {
log.info('Drawing class - ', id); log.info('Drawing class - ', id);
classDb.clear(); // diagObj.db.clear();
// const parser = classDb.parser; // const parser = diagObj.db.parser;
// parser.yy = classDb; // parser.yy = classDb;
// Parse the graph definition // Parse the graph definition
// try { // try {
parser.parse(text); // parser.parse(text);
// } catch (err) { // } catch (err) {
// log.debug('Parsing failed'); // log.debug('Parsing failed');
// } // }
@ -298,7 +295,7 @@ export const draw = function (text, id) {
compound: true, compound: true,
}) })
.setGraph({ .setGraph({
rankdir: classDb.getDirection(), rankdir: diagObj.db.getDirection(),
nodesep: nodeSpacing, nodesep: nodeSpacing,
ranksep: rankSpacing, ranksep: rankSpacing,
marginx: 8, marginx: 8,
@ -318,8 +315,8 @@ export const draw = function (text, id) {
// } // }
// Fetch the vertices/nodes and edges/links from the parsed graph definition // Fetch the vertices/nodes and edges/links from the parsed graph definition
const classes = classDb.getClasses(); const classes = diagObj.db.getClasses();
const relations = classDb.getRelations(); const relations = diagObj.db.getRelations();
log.info(relations); log.info(relations);
addClasses(classes, g, id); addClasses(classes, g, id);
@ -366,7 +363,7 @@ export const draw = function (text, id) {
} }
} }
addSVGAccessibilityFields(parser.yy, svg, id); addSVGAccessibilityFields(diagObj.db, svg, id);
// If node has a link, wrap it in an anchor SVG object. // If node has a link, wrap it in an anchor SVG object.
// const keys = Object.keys(classes); // const keys = Object.keys(classes);
// keys.forEach(function(key) { // keys.forEach(function(key) {

View File

@ -2,19 +2,15 @@ import { select } from 'd3';
import dagre from 'dagre'; import dagre from 'dagre';
import graphlib from 'graphlib'; import graphlib from 'graphlib';
import { log } from '../../logger'; import { log } from '../../logger';
import classDb, { lookUpDomId } from './classDb';
import { parser } from './parser/classDiagram';
import svgDraw from './svgDraw'; import svgDraw from './svgDraw';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
parser.yy = classDb;
let idCache = {}; let idCache = {};
const padding = 20; const padding = 20;
const conf = { const confa = {
dividerMargin: 10, dividerMargin: 10,
padding: 5, padding: 5,
textHeight: 10, textHeight: 10,
@ -141,29 +137,20 @@ const insertMarkers = function (elem) {
.attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z'); .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z');
}; };
/**
* Merges the value of `conf` with the passed `cnf`
*
* @param {object} cnf Config to merge
*/
export const setConf = function (cnf) {
const keys = Object.keys(cnf);
keys.forEach(function (key) {
conf[key] = cnf[key];
});
};
/** /**
* Draws a flowchart in the tag with id: id based on the graph definition in text. * Draws a flowchart in the tag with id: id based on the graph definition in text.
* *
* @param {string} text * @param {string} text
* @param {string} id * @param {string} id
* @param version
* @param _version
* @param diagObj
*/ */
export const draw = function (text, id) { export const draw = function (text, id, _version, diagObj) {
const conf = getConfig().class;
idCache = {}; idCache = {};
parser.yy.clear(); // diagObj.db.clear();
parser.parse(text); // diagObj.parser.parse(text);
log.info('Rendering diagram ' + text); log.info('Rendering diagram ' + text);
@ -198,12 +185,12 @@ export const draw = function (text, id) {
return {}; return {};
}); });
const classes = classDb.getClasses(); const classes = diagObj.db.getClasses();
const keys = Object.keys(classes); const keys = Object.keys(classes);
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
const classDef = classes[keys[i]]; const classDef = classes[keys[i]];
const node = svgDraw.drawClass(diagram, classDef, conf); const node = svgDraw.drawClass(diagram, classDef, conf, diagObj);
idCache[node.id] = node; idCache[node.id] = node;
// Add nodes to the graph. The first argument is the node id. The second is // Add nodes to the graph. The first argument is the node id. The second is
@ -214,7 +201,7 @@ export const draw = function (text, id) {
log.info('Org height: ' + node.height); log.info('Org height: ' + node.height);
} }
const relations = classDb.getRelations(); const relations = diagObj.db.getRelations();
relations.forEach(function (relation) { relations.forEach(function (relation) {
log.info( log.info(
'tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation) 'tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation)
@ -234,7 +221,7 @@ export const draw = function (text, id) {
if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') { if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') {
log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))); log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)));
root root
.select('#' + lookUpDomId(v)) .select('#' + diagObj.db.lookUpDomId(v))
.attr( .attr(
'transform', 'transform',
'translate(' + 'translate(' +
@ -249,7 +236,7 @@ export const draw = function (text, id) {
g.edges().forEach(function (e) { g.edges().forEach(function (e) {
if (typeof e !== 'undefined' && typeof g.edge(e) !== 'undefined') { if (typeof e !== 'undefined' && typeof g.edge(e) !== 'undefined') {
log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e))); log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e)));
svgDraw.drawEdge(diagram, g.edge(e), g.edge(e).relation, conf); svgDraw.drawEdge(diagram, g.edge(e), g.edge(e).relation, conf, diagObj);
} }
}); });
@ -263,10 +250,9 @@ export const draw = function (text, id) {
const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`; const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;
log.debug(`viewBox ${vBox}`); log.debug(`viewBox ${vBox}`);
diagram.attr('viewBox', vBox); diagram.attr('viewBox', vBox);
addSVGAccessibilityFields(parser.yy, diagram, id); addSVGAccessibilityFields(diagObj.db, diagram, id);
}; };
export default { export default {
setConf,
draw, draw,
}; };

View File

@ -1,19 +1,18 @@
import { line, curveBasis } from 'd3'; import { line, curveBasis } from 'd3';
import { lookUpDomId, relationType } from './classDb';
import utils from '../../utils'; import utils from '../../utils';
import { log } from '../../logger'; import { log } from '../../logger';
let edgeCount = 0; let edgeCount = 0;
export const drawEdge = function (elem, path, relation, conf) { export const drawEdge = function (elem, path, relation, conf, diagObj) {
const getRelationType = function (type) { const getRelationType = function (type) {
switch (type) { switch (type) {
case relationType.AGGREGATION: case diagObj.db.relationType.AGGREGATION:
return 'aggregation'; return 'aggregation';
case relationType.EXTENSION: case diagObj.db.EXTENSION:
return 'extension'; return 'extension';
case relationType.COMPOSITION: case diagObj.db.COMPOSITION:
return 'composition'; return 'composition';
case relationType.DEPENDENCY: case diagObj.db.DEPENDENCY:
return 'dependency'; return 'dependency';
} }
}; };
@ -150,10 +149,11 @@ export const drawEdge = function (elem, path, relation, conf) {
* @param {SVGSVGElement} elem The element to draw it into * @param {SVGSVGElement} elem The element to draw it into
* @param classDef * @param classDef
* @param conf * @param conf
* @param diagObj
* @todo Add more information in the JSDOC here * @todo Add more information in the JSDOC here
*/ */
export const drawClass = function (elem, classDef, conf) { export const drawClass = function (elem, classDef, conf, diagObj) {
log.info('Rendering class ' + classDef); log.debug('Rendering class ', classDef, conf);
const id = classDef.id; const id = classDef.id;
const classInfo = { const classInfo = {
@ -164,7 +164,7 @@ export const drawClass = function (elem, classDef, conf) {
}; };
// add class group // add class group
const g = elem.append('g').attr('id', lookUpDomId(id)).attr('class', 'classGroup'); const g = elem.append('g').attr('id', diagObj.db.lookUpDomId(id)).attr('class', 'classGroup');
// add title // add title
let title; let title;

View File

@ -1,7 +1,7 @@
import graphlib from 'graphlib'; import graphlib from 'graphlib';
import { line, curveBasis, select } from 'd3'; import { line, curveBasis, select } from 'd3';
import erDb from './erDb'; // import erDb from './erDb';
import erParser from './parser/erDiagram'; // import erParser from './parser/erDiagram';
import dagre from 'dagre'; import dagre from 'dagre';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import { log } from '../../logger'; import { log } from '../../logger';
@ -9,7 +9,7 @@ import erMarkers from './erMarkers';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
const conf = {}; let conf = {};
/** /**
* Allows the top-level API module to inject config specific to this renderer, storing it in the * Allows the top-level API module to inject config specific to this renderer, storing it in the
@ -409,8 +409,9 @@ let relCnt = 0;
* @param g The graph containing the edge information * @param g The graph containing the edge information
* @param insert The insertion point in the svg DOM (because relationships have markers that need to * @param insert The insertion point in the svg DOM (because relationships have markers that need to
* sit 'behind' opaque entity boxes) * sit 'behind' opaque entity boxes)
* @param diagObj
*/ */
const drawRelationshipFromLayout = function (svg, rel, g, insert) { const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) {
relCnt++; relCnt++;
// Find the edge relating to this relationship // Find the edge relating to this relationship
@ -435,7 +436,7 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert) {
.attr('fill', 'none'); .attr('fill', 'none');
// ...and with dashes if necessary // ...and with dashes if necessary
if (rel.relSpec.relType === erDb.Identification.NON_IDENTIFYING) { if (rel.relSpec.relType === diagObj.db.Identification.NON_IDENTIFYING) {
svgPath.attr('stroke-dasharray', '8,8'); svgPath.attr('stroke-dasharray', '8,8');
} }
@ -457,40 +458,40 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert) {
// Note that the 'A' entity's marker is at the end of the relationship and the 'B' entity's marker is at the start // Note that the 'A' entity's marker is at the end of the relationship and the 'B' entity's marker is at the start
switch (rel.relSpec.cardA) { switch (rel.relSpec.cardA) {
case erDb.Cardinality.ZERO_OR_ONE: case diagObj.db.Cardinality.ZERO_OR_ONE:
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')'); svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_END + ')');
break; break;
case erDb.Cardinality.ZERO_OR_MORE: case diagObj.db.Cardinality.ZERO_OR_MORE:
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')'); svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_END + ')');
break; break;
case erDb.Cardinality.ONE_OR_MORE: case diagObj.db.Cardinality.ONE_OR_MORE:
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')'); svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_END + ')');
break; break;
case erDb.Cardinality.ONLY_ONE: case diagObj.db.Cardinality.ONLY_ONE:
svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_END + ')'); svgPath.attr('marker-end', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_END + ')');
break; break;
} }
switch (rel.relSpec.cardB) { switch (rel.relSpec.cardB) {
case erDb.Cardinality.ZERO_OR_ONE: case diagObj.db.Cardinality.ZERO_OR_ONE:
svgPath.attr( svgPath.attr(
'marker-start', 'marker-start',
'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')' 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_ONE_START + ')'
); );
break; break;
case erDb.Cardinality.ZERO_OR_MORE: case diagObj.db.Cardinality.ZERO_OR_MORE:
svgPath.attr( svgPath.attr(
'marker-start', 'marker-start',
'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')' 'url(' + url + '#' + erMarkers.ERMarkers.ZERO_OR_MORE_START + ')'
); );
break; break;
case erDb.Cardinality.ONE_OR_MORE: case diagObj.db.Cardinality.ONE_OR_MORE:
svgPath.attr( svgPath.attr(
'marker-start', 'marker-start',
'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')' 'url(' + url + '#' + erMarkers.ERMarkers.ONE_OR_MORE_START + ')'
); );
break; break;
case erDb.Cardinality.ONLY_ONE: case diagObj.db.Cardinality.ONLY_ONE:
svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_START + ')'); svgPath.attr('marker-start', 'url(' + url + '#' + erMarkers.ERMarkers.ONLY_ONE_START + ')');
break; break;
} }
@ -540,12 +541,14 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert) {
* *
* @param text The text of the diagram * @param text The text of the diagram
* @param id The unique id of the DOM node that contains the diagram * @param id The unique id of the DOM node that contains the diagram
* @param _version
* @param diag
* @param diagObj
*/ */
export const draw = function (text, id) { export const draw = function (text, id, _version, diagObj) {
conf = getConfig().er;
log.info('Drawing ER diagram'); log.info('Drawing ER diagram');
erDb.clear(); // diag.db.clear();
const parser = erParser.parser;
parser.yy = erDb;
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sanbox mode
let sandboxElement; let sandboxElement;
@ -556,14 +559,14 @@ export const draw = function (text, id) {
securityLevel === 'sandbox' securityLevel === 'sandbox'
? select(sandboxElement.nodes()[0].contentDocument.body) ? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body'); : select('body');
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; // const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
// Parse the text to populate erDb // Parse the text to populate erDb
try { // try {
parser.parse(text); // parser.parse(text);
} catch (err) { // } catch (err) {
log.debug('Parsing failed'); // log.debug('Parsing failed');
} // }
// Get a reference to the svg node that contains the text // Get a reference to the svg node that contains the text
const svg = root.select(`[id='${id}']`); const svg = root.select(`[id='${id}']`);
@ -612,12 +615,12 @@ export const draw = function (text, id) {
// Draw the entities (at 0,0), returning the first svg node that got // Draw the entities (at 0,0), returning the first svg node that got
// inserted - this represents the insertion point for relationship paths // inserted - this represents the insertion point for relationship paths
const firstEntity = drawEntities(svg, erDb.getEntities(), g); const firstEntity = drawEntities(svg, diagObj.db.getEntities(), g);
// TODO: externalise the addition of entities to the graph - it's a bit 'buried' in the above // TODO: externalise the addition of entities to the graph - it's a bit 'buried' in the above
// Add all the relationships to the graph // Add all the relationships to the graph
const relationships = addRelationships(erDb.getRelationships(), g); const relationships = addRelationships(diagObj.db.getRelationships(), g);
dagre.layout(g); // Node and edge positions will be updated dagre.layout(g); // Node and edge positions will be updated
@ -626,7 +629,7 @@ export const draw = function (text, id) {
// Draw the relationships // Draw the relationships
relationships.forEach(function (rel) { relationships.forEach(function (rel) {
drawRelationshipFromLayout(svg, rel, g, firstEntity); drawRelationshipFromLayout(svg, rel, g, firstEntity, diagObj);
}); });
const padding = conf.diagramPadding; const padding = conf.diagramPadding;
@ -639,7 +642,7 @@ export const draw = function (text, id) {
svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`);
addSVGAccessibilityFields(parser.yy, svg, id); addSVGAccessibilityFields(diagObj.db, svg, id);
}; // draw }; // draw
export default { export default {

View File

@ -489,7 +489,6 @@ export const addSubGraph = function (_id, list, _title) {
const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list));
nodeList = nl; nodeList = nl;
if (version === 'gen-1') { if (version === 'gen-1') {
log.warn('LOOKING UP');
for (let i = 0; i < nodeList.length; i++) { for (let i = 0; i < nodeList.length; i++) {
nodeList[i] = lookUpDomId(nodeList[i]); nodeList[i] = lookUpDomId(nodeList[i]);
} }

View File

@ -28,8 +28,9 @@ export const setConf = function (cnf) {
* @param svgId * @param svgId
* @param root * @param root
* @param doc * @param doc
* @param diagObj
*/ */
export const addVertices = function (vert, g, svgId, root, doc) { export const addVertices = function (vert, g, svgId, root, doc, diagObj) {
const svg = root.select(`[id="${svgId}"]`); const svg = root.select(`[id="${svgId}"]`);
const keys = Object.keys(vert); const keys = Object.keys(vert);
@ -152,8 +153,8 @@ export const addVertices = function (vert, g, svgId, root, doc) {
id: vertex.id, id: vertex.id,
link: vertex.link, link: vertex.link,
linkTarget: vertex.linkTarget, linkTarget: vertex.linkTarget,
tooltip: flowDb.getTooltip(vertex.id) || '', tooltip: diagObj.db.getTooltip(vertex.id) || '',
domId: flowDb.lookUpDomId(vertex.id), domId: diagObj.db.lookUpDomId(vertex.id),
haveCallback: vertex.haveCallback, haveCallback: vertex.haveCallback,
width: vertex.type === 'group' ? 500 : undefined, width: vertex.type === 'group' ? 500 : undefined,
dir: vertex.dir, dir: vertex.dir,
@ -171,7 +172,7 @@ export const addVertices = function (vert, g, svgId, root, doc) {
class: classStr, class: classStr,
style: styles.style, style: styles.style,
id: vertex.id, id: vertex.id,
domId: flowDb.lookUpDomId(vertex.id), domId: diagObj.db.lookUpDomId(vertex.id),
width: vertex.type === 'group' ? 500 : undefined, width: vertex.type === 'group' ? 500 : undefined,
type: vertex.type, type: vertex.type,
dir: vertex.dir, dir: vertex.dir,
@ -186,8 +187,9 @@ export const addVertices = function (vert, g, svgId, root, doc) {
* *
* @param {object} edges The edges to add to the graph * @param {object} edges The edges to add to the graph
* @param {object} g The graph object * @param {object} g The graph object
* @param diagObj
*/ */
export const addEdges = function (edges, g) { export const addEdges = function (edges, g, diagObj) {
log.info('abc78 edges = ', edges); log.info('abc78 edges = ', edges);
let cnt = 0; let cnt = 0;
let linkIdCnt = {}; let linkIdCnt = {};
@ -304,11 +306,7 @@ export const addEdges = function (edges, g) {
edgeData.arrowheadStyle = 'fill: #333'; edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c'; edgeData.labelpos = 'c';
} }
// if (evaluate(getConfig().flowchart.htmlLabels) && false) {
// // eslint-disable-line
// edgeData.labelType = 'html';
// edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}">${edge.text}</span>`;
// } else {
edgeData.labelType = 'text'; edgeData.labelType = 'text';
edgeData.label = edge.text.replace(common.lineBreakRegex, '\n'); edgeData.label = edge.text.replace(common.lineBreakRegex, '\n');
@ -317,7 +315,6 @@ export const addEdges = function (edges, g) {
} }
edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:'); edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:');
// }
edgeData.id = linkId; edgeData.id = linkId;
edgeData.classes = 'flowchart-link ' + linkNameStart + ' ' + linkNameEnd; edgeData.classes = 'flowchart-link ' + linkNameStart + ' ' + linkNameEnd;
@ -331,22 +328,19 @@ export const addEdges = function (edges, g) {
* Returns the all the styles from classDef statements in the graph definition. * Returns the all the styles from classDef statements in the graph definition.
* *
* @param text * @param text
* @param diagObj
* @returns {object} ClassDef styles * @returns {object} ClassDef styles
*/ */
export const getClasses = function (text) { export const getClasses = function (text, diagObj) {
log.info('Extracting classes'); log.info('Extracting classes');
flowDb.clear(); diagObj.db.clear();
const parser = flow.parser;
parser.yy = flowDb;
try { try {
// Parse the graph definition // Parse the graph definition
parser.parse(text); diagObj.parse(text);
return diagObj.db.getClasses();
} catch (e) { } catch (e) {
return; return;
} }
return flowDb.getClasses();
}; };
/** /**
@ -356,22 +350,15 @@ export const getClasses = function (text) {
* @param id * @param id
*/ */
export const draw = function (text, id) { export const draw = function (text, id, _version, diagObj) {
log.info('Drawing flowchart'); log.info('Drawing flowchart');
flowDb.clear(); diagObj.db.clear();
flowDb.setGen('gen-2'); flowDb.setGen('gen-2');
const parser = flow.parser;
parser.yy = flowDb;
// Parse the graph definition // Parse the graph definition
// try { diagObj.parser.parse(text);
parser.parse(text);
// } catch (err) {
// log.debug('Parsing failed');
// }
// Fetch the default direction, use TD if none was found // Fetch the default direction, use TD if none was found
let dir = flowDb.getDirection(); let dir = diagObj.db.getDirection();
if (typeof dir === 'undefined') { if (typeof dir === 'undefined') {
dir = 'TD'; dir = 'TD';
} }
@ -409,18 +396,18 @@ export const draw = function (text, id) {
}); });
let subG; let subG;
const subGraphs = flowDb.getSubGraphs(); const subGraphs = diagObj.db.getSubGraphs();
log.info('Subgraphs - ', subGraphs); log.info('Subgraphs - ', subGraphs);
for (let i = subGraphs.length - 1; i >= 0; i--) { for (let i = subGraphs.length - 1; i >= 0; i--) {
subG = subGraphs[i]; subG = subGraphs[i];
log.info('Subgraph - ', subG); log.info('Subgraph - ', subG);
flowDb.addVertex(subG.id, subG.title, 'group', undefined, subG.classes, subG.dir); diagObj.db.addVertex(subG.id, subG.title, 'group', undefined, subG.classes, subG.dir);
} }
// Fetch the vertices/nodes and edges/links from the parsed graph definition // Fetch the vertices/nodes and edges/links from the parsed graph definition
const vert = flowDb.getVertices(); const vert = diagObj.db.getVertices();
const edges = flowDb.getEdges(); const edges = diagObj.db.getEdges();
log.info(edges); log.info(edges);
let i = 0; let i = 0;
@ -435,8 +422,8 @@ export const draw = function (text, id) {
g.setParent(subG.nodes[j], subG.id); g.setParent(subG.nodes[j], subG.id);
} }
} }
addVertices(vert, g, id, root, doc); addVertices(vert, g, id, root, doc, diagObj);
addEdges(edges, g); addEdges(edges, g, diagObj);
// Add custom shapes // Add custom shapes
// flowChartShapes.addToRenderV2(addShape); // flowChartShapes.addToRenderV2(addShape);
@ -445,7 +432,7 @@ export const draw = function (text, id) {
const svg = root.select(`[id="${id}"]`); const svg = root.select(`[id="${id}"]`);
// Adds title and description to the flow chart // Adds title and description to the flow chart
addSVGAccessibilityFields(parser.yy, svg, id); addSVGAccessibilityFields(diagObj.db, svg, id);
// Run the renderer. This is what draws the final graph. // Run the renderer. This is what draws the final graph.
const element = root.select('#' + id + ' g'); const element = root.select('#' + id + ' g');
@ -454,7 +441,7 @@ export const draw = function (text, id) {
setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth); setupGraphViewbox(g, svg, conf.diagramPadding, conf.useMaxWidth);
// Index nodes // Index nodes
flowDb.indexNodes('subGraph' + i); diagObj.db.indexNodes('subGraph' + i);
// Add label rects for non html labels // Add label rects for non html labels
if (!conf.htmlLabels) { if (!conf.htmlLabels) {

View File

@ -1,10 +1,6 @@
import graphlib from 'graphlib'; import graphlib from 'graphlib';
import { select, curveLinear, selectAll } from 'd3'; import { select, curveLinear, selectAll } from 'd3';
import flowDb from './flowDb';
import flow from './parser/flow';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import dagreD3 from 'dagre-d3'; import dagreD3 from 'dagre-d3';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { log } from '../../logger'; import { log } from '../../logger';
@ -30,8 +26,9 @@ export const setConf = function (cnf) {
* @param root * @param root
* @param doc * @param doc
* @param _doc * @param _doc
* @param diagObj
*/ */
export const addVertices = function (vert, g, svgId, root, _doc) { export const addVertices = function (vert, g, svgId, root, _doc, diagObj) {
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
const svg = !root ? select(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`); const svg = !root ? select(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`);
@ -144,7 +141,7 @@ export const addVertices = function (vert, g, svgId, root, _doc) {
} }
// Add the node // Add the node
log.warn('Adding node', vertex.id, vertex.domId); log.warn('Adding node', vertex.id, vertex.domId);
g.setNode(flowDb.lookUpDomId(vertex.id), { g.setNode(diagObj.db.lookUpDomId(vertex.id), {
labelType: 'svg', labelType: 'svg',
labelStyle: styles.labelStyle, labelStyle: styles.labelStyle,
shape: _shape, shape: _shape,
@ -153,7 +150,7 @@ export const addVertices = function (vert, g, svgId, root, _doc) {
ry: radious, ry: radious,
class: classStr, class: classStr,
style: styles.style, style: styles.style,
id: flowDb.lookUpDomId(vertex.id), id: diagObj.db.lookUpDomId(vertex.id),
}); });
}); });
}; };
@ -163,8 +160,9 @@ export const addVertices = function (vert, g, svgId, root, _doc) {
* *
* @param {object} edges The edges to add to the graph * @param {object} edges The edges to add to the graph
* @param {object} g The graph object * @param {object} g The graph object
* @param diagObj
*/ */
export const addEdges = function (edges, g) { export const addEdges = function (edges, g, diagObj) {
let cnt = 0; let cnt = 0;
let defaultStyle; let defaultStyle;
@ -264,7 +262,7 @@ export const addEdges = function (edges, g) {
edgeData.minlen = edge.length || 1; edgeData.minlen = edge.length || 1;
// Add the edge to the graph // Add the edge to the graph
g.setEdge(flowDb.lookUpDomId(edge.start), flowDb.lookUpDomId(edge.end), edgeData, cnt); g.setEdge(diagObj.db.lookUpDomId(edge.start), diagObj.db.lookUpDomId(edge.end), edgeData, cnt);
}); });
}; };
@ -272,18 +270,16 @@ export const addEdges = function (edges, g) {
* Returns the all the styles from classDef statements in the graph definition. * Returns the all the styles from classDef statements in the graph definition.
* *
* @param text * @param text
* @param diagObj
* @returns {object} ClassDef styles * @returns {object} ClassDef styles
*/ */
export const getClasses = function (text) { export const getClasses = function (text, diagObj) {
log.info('Extracting classes'); log.info('Extracting classes');
flowDb.clear(); diagObj.db.clear();
try { try {
const parser = flow.parser;
parser.yy = flowDb;
// Parse the graph definition // Parse the graph definition
parser.parse(text); diagObj.parse(text);
return flowDb.getClasses(); return diagObj.db.getClasses();
} catch (e) { } catch (e) {
return; return;
} }
@ -294,14 +290,12 @@ export const getClasses = function (text) {
* *
* @param text * @param text
* @param id * @param id
* @param _version
* @param diagObj
*/ */
export const draw = function (text, id) { export const draw = function (text, id, _version, diagObj) {
log.info('Drawing flowchart'); log.info('Drawing flowchart');
flowDb.clear(); diagObj.db.clear();
flowDb.setGen('gen-1');
const parser = flow.parser;
parser.yy = flowDb;
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
let sandboxElement; let sandboxElement;
if (securityLevel === 'sandbox') { if (securityLevel === 'sandbox') {
@ -314,14 +308,14 @@ export const draw = function (text, id) {
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
// Parse the graph definition // Parse the graph definition
// try { try {
parser.parse(text); diagObj.parser.parse(text);
// } catch (err) { } catch (err) {
// log.debug('Parsing failed'); log.debug('Parsing failed');
// } }
// Fetch the default direction, use TD if none was found // Fetch the default direction, use TD if none was found
let dir = flowDb.getDirection(); let dir = diagObj.db.getDirection();
if (typeof dir === 'undefined') { if (typeof dir === 'undefined') {
dir = 'TD'; dir = 'TD';
} }
@ -347,17 +341,17 @@ export const draw = function (text, id) {
}); });
let subG; let subG;
const subGraphs = flowDb.getSubGraphs(); const subGraphs = diagObj.db.getSubGraphs();
for (let i = subGraphs.length - 1; i >= 0; i--) { for (let i = subGraphs.length - 1; i >= 0; i--) {
subG = subGraphs[i]; subG = subGraphs[i];
flowDb.addVertex(subG.id, subG.title, 'group', undefined, subG.classes); diagObj.db.addVertex(subG.id, subG.title, 'group', undefined, subG.classes);
} }
// Fetch the vertices/nodes and edges/links from the parsed graph definition // Fetch the vertices/nodes and edges/links from the parsed graph definition
const vert = flowDb.getVertices(); const vert = diagObj.db.getVertices();
log.warn('Get vertices', vert); log.warn('Get vertices', vert);
const edges = flowDb.getEdges(); const edges = diagObj.db.getEdges();
let i = 0; let i = 0;
for (i = subGraphs.length - 1; i >= 0; i--) { for (i = subGraphs.length - 1; i >= 0; i--) {
@ -369,14 +363,14 @@ export const draw = function (text, id) {
log.warn( log.warn(
'Setting subgraph', 'Setting subgraph',
subG.nodes[j], subG.nodes[j],
flowDb.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.nodes[j]),
flowDb.lookUpDomId(subG.id) diagObj.db.lookUpDomId(subG.id)
); );
g.setParent(flowDb.lookUpDomId(subG.nodes[j]), flowDb.lookUpDomId(subG.id)); g.setParent(diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id));
} }
} }
addVertices(vert, g, id, root, doc); addVertices(vert, g, id, root, doc, diagObj);
addEdges(edges, g); addEdges(edges, g, diagObj);
// Create the renderer // Create the renderer
const Render = dagreD3.render; const Render = dagreD3.render;
@ -427,28 +421,28 @@ export const draw = function (text, id) {
const svg = root.select(`[id="${id}"]`); const svg = root.select(`[id="${id}"]`);
// Adds title and description to the flow chart // Adds title and description to the flow chart
addSVGAccessibilityFields(parser.yy, svg, id); addSVGAccessibilityFields(diagObj.db, svg, id);
// Run the renderer. This is what draws the final graph. // Run the renderer. This is what draws the final graph.
const element = root.select('#' + id + ' g'); const element = root.select('#' + id + ' g');
render(element, g); render(element, g);
element.selectAll('g.node').attr('title', function () { element.selectAll('g.node').attr('title', function () {
return flowDb.getTooltip(this.id); return diagObj.db.getTooltip(this.id);
}); });
// Index nodes // Index nodes
flowDb.indexNodes('subGraph' + i); diagObj.db.indexNodes('subGraph' + i);
// reposition labels // reposition labels
for (i = 0; i < subGraphs.length; i++) { for (i = 0; i < subGraphs.length; i++) {
subG = subGraphs[i]; subG = subGraphs[i];
if (subG.title !== 'undefined') { if (subG.title !== 'undefined') {
const clusterRects = doc.querySelectorAll( const clusterRects = doc.querySelectorAll(
'#' + id + ' [id="' + flowDb.lookUpDomId(subG.id) + '"] rect' '#' + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"] rect'
); );
const clusterEl = doc.querySelectorAll( const clusterEl = doc.querySelectorAll(
'#' + id + ' [id="' + flowDb.lookUpDomId(subG.id) + '"]' '#' + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"]'
); );
const xPos = clusterRects[0].x.baseVal.value; const xPos = clusterRects[0].x.baseVal.value;
@ -492,7 +486,7 @@ export const draw = function (text, id) {
const vertex = vert[key]; const vertex = vert[key];
if (vertex.link) { if (vertex.link) {
const node = root.select('#' + id + ' [id="' + flowDb.lookUpDomId(key) + '"]'); const node = root.select('#' + id + ' [id="' + diagObj.db.lookUpDomId(key) + '"]');
if (node) { if (node) {
const link = doc.createElementNS('http://www.w3.org/2000/svg', 'a'); const link = doc.createElementNS('http://www.w3.org/2000/svg', 'a');
link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' ')); link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' '));

View File

@ -1,5 +1,6 @@
import { addVertices, addEdges } from './flowRenderer'; import { addVertices, addEdges } from './flowRenderer';
import { setConfig } from '../../config'; import { setConfig } from '../../config';
import Diagram from '../../Diagram';
setConfig({ setConfig({
flowchart: { flowchart: {
@ -28,6 +29,13 @@ describe('the flowchart renderer', function () {
['group', 'rect'], ['group', 'rect'],
].forEach(function ([type, expectedShape, expectedRadios = 0]) { ].forEach(function ([type, expectedShape, expectedRadios = 0]) {
it(`should add the correct shaped node to the graph for vertex type ${type}`, function () { it(`should add the correct shaped node to the graph for vertex type ${type}`, function () {
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const addedNodes = []; const addedNodes = [];
const mockG = { const mockG = {
setNode: function (id, object) { setNode: function (id, object) {
@ -45,7 +53,10 @@ describe('the flowchart renderer', function () {
}, },
}, },
mockG, mockG,
'svg-id' 'svg-id',
undefined,
undefined,
fakeDiag
); );
expect(addedNodes).toHaveLength(1); expect(addedNodes).toHaveLength(1);
expect(addedNodes[0][0]).toEqual('my-node-id'); expect(addedNodes[0][0]).toEqual('my-node-id');
@ -62,6 +73,13 @@ describe('the flowchart renderer', function () {
) { ) {
it('should handle multiline texts with different line breaks', function () { it('should handle multiline texts with different line breaks', function () {
const addedNodes = []; const addedNodes = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = { const mockG = {
setNode: function (id, object) { setNode: function (id, object) {
addedNodes.push([id, object]); addedNodes.push([id, object]);
@ -78,7 +96,10 @@ describe('the flowchart renderer', function () {
}, },
}, },
mockG, mockG,
'svg-id' 'svg-id',
false,
document,
fakeDiag
); );
expect(addedNodes).toHaveLength(1); expect(addedNodes).toHaveLength(1);
expect(addedNodes[0][0]).toEqual('my-node-id'); expect(addedNodes[0][0]).toEqual('my-node-id');
@ -103,6 +124,13 @@ describe('the flowchart renderer', function () {
].forEach(function ([style, expectedStyle, expectedLabelStyle]) { ].forEach(function ([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function () { it(`should add the styles to style and/or labelStyle for style ${style}`, function () {
const addedNodes = []; const addedNodes = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = { const mockG = {
setNode: function (id, object) { setNode: function (id, object) {
addedNodes.push([id, object]); addedNodes.push([id, object]);
@ -119,7 +147,10 @@ describe('the flowchart renderer', function () {
}, },
}, },
mockG, mockG,
'svg-id' 'svg-id',
undefined,
undefined,
fakeDiag
); );
expect(addedNodes).toHaveLength(1); expect(addedNodes).toHaveLength(1);
expect(addedNodes[0][0]).toEqual('my-node-id'); expect(addedNodes[0][0]).toEqual('my-node-id');
@ -137,11 +168,18 @@ describe('the flowchart renderer', function () {
addedNodes.push([id, object]); addedNodes.push([id, object]);
}, },
}; };
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
addVertices( addVertices(
{ {
v1: { v1: {
type: 'rect', type: 'rect',
id: 'defaultNode', id: 'my-node-id',
classes: [], classes: [],
styles: [], styles: [],
text: 'my vertex text', text: 'my vertex text',
@ -155,12 +193,15 @@ describe('the flowchart renderer', function () {
}, },
}, },
mockG, mockG,
'svg-id' 'svg-id',
undefined,
undefined,
fakeDiag
); );
expect(addedNodes).toHaveLength(2); expect(addedNodes).toHaveLength(2);
expect(addedNodes[0][0]).toEqual('defaultNode'); expect(addedNodes[0][0]).toEqual('my-node-id');
expect(addedNodes[0][1]).toHaveProperty('class', 'default'); expect(addedNodes[0][1]).toHaveProperty('class', 'default');
expect(addedNodes[1][0]).toEqual('myNode'); expect(addedNodes[1][0]).toEqual('my-node-id');
expect(addedNodes[1][1]).toHaveProperty('class', 'myClass'); expect(addedNodes[1][1]).toHaveProperty('class', 'myClass');
}); });
}); });
@ -168,6 +209,13 @@ describe('the flowchart renderer', function () {
describe('when adding edges to a graph', function () { describe('when adding edges to a graph', function () {
it('should handle multiline texts and set centered label position', function () { it('should handle multiline texts and set centered label position', function () {
const addedEdges = []; const addedEdges = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = { const mockG = {
setEdge: function (s, e, data, c) { setEdge: function (s, e, data, c) {
addedEdges.push(data); addedEdges.push(data);
@ -185,7 +233,7 @@ describe('the flowchart renderer', function () {
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br\t/>Line' }, { style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br\t/>Line' },
], ],
mockG, mockG,
'svg-id' fakeDiag
); );
addedEdges.forEach(function (edge) { addedEdges.forEach(function (edge) {
@ -206,12 +254,19 @@ describe('the flowchart renderer', function () {
].forEach(function ([style, expectedStyle, expectedLabelStyle]) { ].forEach(function ([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function () { it(`should add the styles to style and/or labelStyle for style ${style}`, function () {
const addedEdges = []; const addedEdges = [];
const fakeDiag = {
db: {
lookUpDomId: () => {
return 'my-node-id';
},
},
};
const mockG = { const mockG = {
setEdge: function (s, e, data, c) { setEdge: function (s, e, data, c) {
addedEdges.push(data); addedEdges.push(data);
}, },
}; };
addEdges([{ style: style, text: 'styling' }], mockG, 'svg-id'); addEdges([{ style: style, text: 'styling' }], mockG, fakeDiag);
expect(addedEdges).toHaveLength(1); expect(addedEdges).toHaveLength(1);
expect(addedEdges[0]).toHaveProperty('style', expectedStyle); expect(addedEdges[0]).toHaveProperty('style', expectedStyle);

View File

@ -11,23 +11,20 @@ import {
axisTop, axisTop,
timeFormat, timeFormat,
} from 'd3'; } from 'd3';
import { parser } from './parser/gantt';
import common from '../common/common'; import common from '../common/common';
import ganttDb from './ganttDb';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
parser.yy = ganttDb;
export const setConf = function () { export const setConf = function () {
log.debug('Something is calling, setConf, remove the call'); log.debug('Something is calling, setConf, remove the call');
}; };
let w; let w;
export const draw = function (text, id) { export const draw = function (text, id, version, diagObj) {
const conf = getConfig().gantt; const conf = getConfig().gantt;
parser.yy.clear(); // diagObj.db.clear();
parser.parse(text); // parser.parse(text);
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sanbox mode
@ -52,7 +49,7 @@ export const draw = function (text, id) {
w = conf.useWidth; w = conf.useWidth;
} }
const taskArray = parser.yy.getTasks(); const taskArray = diagObj.db.getTasks();
// Set height based on number of tasks // Set height based on number of tasks
const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding; const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding;
@ -109,12 +106,12 @@ export const draw = function (text, id) {
svg svg
.append('text') .append('text')
.text(parser.yy.getDiagramTitle()) .text(diagObj.db.getDiagramTitle())
.attr('x', w / 2) .attr('x', w / 2)
.attr('y', conf.titleTopMargin) .attr('y', conf.titleTopMargin)
.attr('class', 'titleText'); .attr('class', 'titleText');
addSVGAccessibilityFields(parser.yy, svg, id); addSVGAccessibilityFields(diagObj.db, svg, id);
/** /**
* @param tasks * @param tasks
@ -139,8 +136,8 @@ export const draw = function (text, id) {
pageWidth, pageWidth,
pageHeight, pageHeight,
tasks, tasks,
parser.yy.getExcludes(), diagObj.db.getExcludes(),
parser.yy.getIncludes() diagObj.db.getIncludes()
); );
makeGrid(leftPadding, topPadding, pageWidth, pageHeight); makeGrid(leftPadding, topPadding, pageWidth, pageHeight);
drawRects(tasks, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth, pageHeight); drawRects(tasks, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth, pageHeight);
@ -187,7 +184,7 @@ export const draw = function (text, id) {
// Draw the rects representing the tasks // Draw the rects representing the tasks
const rectangles = svg.append('g').selectAll('rect').data(theArray).enter(); const rectangles = svg.append('g').selectAll('rect').data(theArray).enter();
const links = ganttDb.getLinks(); const links = diagObj.db.getLinks();
// Render the tasks with links // Render the tasks with links
// Render the other tasks // Render the other tasks
@ -430,14 +427,14 @@ export const draw = function (text, id) {
0 0
); );
const maxTime = tasks.reduce((max, { endTime }) => (max ? Math.max(max, endTime) : endTime), 0); const maxTime = tasks.reduce((max, { endTime }) => (max ? Math.max(max, endTime) : endTime), 0);
const dateFormat = parser.yy.getDateFormat(); const dateFormat = diagObj.db.getDateFormat();
if (!minTime || !maxTime) return; if (!minTime || !maxTime) return;
const excludeRanges = []; const excludeRanges = [];
let range = null; let range = null;
let d = moment(minTime); let d = moment(minTime);
while (d.valueOf() <= maxTime) { while (d.valueOf() <= maxTime) {
if (parser.yy.isInvalidDate(d, dateFormat, excludes, includes)) { if (diagObj.db.isInvalidDate(d, dateFormat, excludes, includes)) {
if (!range) { if (!range) {
range = { range = {
start: d.clone(), start: d.clone(),
@ -495,7 +492,7 @@ export const draw = function (text, id) {
function makeGrid(theSidePad, theTopPad, w, h) { function makeGrid(theSidePad, theTopPad, w, h) {
let bottomXAxis = axisBottom(timeScale) let bottomXAxis = axisBottom(timeScale)
.tickSize(-h + theTopPad + conf.gridLineStartPadding) .tickSize(-h + theTopPad + conf.gridLineStartPadding)
.tickFormat(timeFormat(parser.yy.getAxisFormat() || conf.axisFormat || '%Y-%m-%d')); .tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'));
svg svg
.append('g') .append('g')
@ -509,10 +506,10 @@ export const draw = function (text, id) {
.attr('font-size', 10) .attr('font-size', 10)
.attr('dy', '1em'); .attr('dy', '1em');
if (ganttDb.topAxisEnabled() || conf.topAxis) { if (diagObj.db.topAxisEnabled() || conf.topAxis) {
let topXAxis = axisTop(timeScale) let topXAxis = axisTop(timeScale)
.tickSize(-h + theTopPad + conf.gridLineStartPadding) .tickSize(-h + theTopPad + conf.gridLineStartPadding)
.tickFormat(timeFormat(parser.yy.getAxisFormat() || conf.axisFormat || '%Y-%m-%d')); .tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'));
svg svg
.append('g') .append('g')
@ -592,7 +589,7 @@ export const draw = function (text, id) {
* @param h * @param h
*/ */
function drawToday(theSidePad, theTopPad, w, h) { function drawToday(theSidePad, theTopPad, w, h) {
const todayMarker = ganttDb.getTodayMarker(); const todayMarker = diagObj.db.getTodayMarker();
if (todayMarker === 'off') { if (todayMarker === 'off') {
return; return;
} }

View File

@ -1,7 +1,5 @@
import { curveBasis, line, select } from 'd3'; import { select } from 'd3';
import { interpolateToCurve, getStylesFromArray, configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import db from './gitGraphAst';
import gitGraphParser from './parser/gitGraph';
import { log } from '../../logger'; import { log } from '../../logger';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
@ -515,23 +513,17 @@ const drawBranches = (svg, branches) => {
* @param txt * @param txt
* @param id * @param id
* @param ver * @param ver
* @param diagObj
*/ */
export const draw = function (txt, id, ver) { export const draw = function (txt, id, ver, diagObj) {
clear(); clear();
const conf = getConfig(); const conf = getConfig();
const gitGraphConfig = getConfig().gitGraph; const gitGraphConfig = getConfig().gitGraph;
// try { // try {
const parser = gitGraphParser.parser;
parser.yy = db;
parser.yy.clear();
log.debug('in gitgraph renderer', txt + '\n', 'id:', id, ver); log.debug('in gitgraph renderer', txt + '\n', 'id:', id, ver);
// // Parse the graph definition
parser.parse(txt + '\n');
const direction = db.getDirection(); allCommitsDict = diagObj.db.getCommits();
allCommitsDict = db.getCommits(); const branches = diagObj.db.getBranchesAsObjArray();
const branches = db.getBranchesAsObjArray();
// Position branches vertically // Position branches vertically
let pos = 0; let pos = 0;
@ -543,7 +535,7 @@ export const draw = function (txt, id, ver) {
const diagram = select(`[id="${id}"]`); const diagram = select(`[id="${id}"]`);
// Adds title and description to the flow chart // Adds title and description to the flow chart
addSVGAccessibilityFields(parser.yy, diagram, id); addSVGAccessibilityFields(diagObj.db, diagram, id);
drawCommits(diagram, allCommitsDict, false); drawCommits(diagram, allCommitsDict, false);
if (gitGraphConfig.showBranches) { if (gitGraphConfig.showBranches) {

View File

@ -1,30 +1,20 @@
/** Created by knut on 14-12-11. */ /** Created by knut on 14-12-11. */
import { select } from 'd3'; import { select } from 'd3';
import db from './infoDb';
import infoParser from './parser/info';
import { log } from '../../logger'; import { log } from '../../logger';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
const conf = {};
export const setConf = function (cnf) {
const keys = Object.keys(cnf);
keys.forEach(function (key) {
conf[key] = cnf[key];
});
};
/** /**
* Draws a an info picture in the tag with id: id based on the graph definition in text. * Draws a an info picture in the tag with id: id based on the graph definition in text.
* *
* @param {any} text * @param {any} text
* @param {any} id * @param {any} id
* @param {any} version * @param {any} version
* @param diagObj
*/ */
export const draw = (text, id, version) => { export const draw = (text, id, version, diagObj) => {
try { try {
const parser = infoParser.parser; // const parser = infoParser.parser;
parser.yy = db; // parser.yy = db;
log.debug('Renering info diagram\n' + text); log.debug('Renering info diagram\n' + text);
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
@ -40,8 +30,8 @@ export const draw = (text, id, version) => {
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
// Parse the graph definition // Parse the graph definition
parser.parse(text); // parser.parse(text);
log.debug('Parsed info diagram'); // log.debug('Parsed info diagram');
// Fetch the default direction, use TD if none was found // Fetch the default direction, use TD if none was found
const svg = root.select('#' + id); const svg = root.select('#' + id);
@ -65,6 +55,5 @@ export const draw = (text, id, version) => {
}; };
export default { export default {
setConf,
draw, draw,
}; };

View File

@ -1,7 +1,5 @@
/** Created by AshishJ on 11-09-2019. */ /** Created by AshishJ on 11-09-2019. */
import { select, scaleOrdinal, pie as d3pie, arc } from 'd3'; import { select, scaleOrdinal, pie as d3pie, arc } from 'd3';
import pieData from './pieDb';
import pieParser from './parser/pie';
import { log } from '../../logger'; import { log } from '../../logger';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import * as configApi from '../../config'; import * as configApi from '../../config';
@ -17,11 +15,9 @@ let conf = configApi.getConfig();
*/ */
let width; let width;
const height = 450; const height = 450;
export const draw = (txt, id) => { export const draw = (txt, id, _version, diagObj) => {
try { try {
conf = configApi.getConfig(); conf = configApi.getConfig();
const parser = pieParser.parser;
parser.yy = pieData;
log.debug('Rendering info diagram\n' + txt); log.debug('Rendering info diagram\n' + txt);
const securityLevel = configApi.getConfig().securityLevel; const securityLevel = configApi.getConfig().securityLevel;
@ -37,8 +33,8 @@ export const draw = (txt, id) => {
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
// Parse the Pie Chart definition // Parse the Pie Chart definition
parser.yy.clear(); diagObj.db.clear();
parser.parse(txt); diagObj.parser.parse(txt);
log.debug('Parsed info diagram'); log.debug('Parsed info diagram');
const elem = doc.getElementById(id); const elem = doc.getElementById(id);
width = elem.parentElement.offsetWidth; width = elem.parentElement.offsetWidth;
@ -57,7 +53,7 @@ export const draw = (txt, id) => {
const diagram = root.select('#' + id); const diagram = root.select('#' + id);
configureSvgSize(diagram, height, width, conf.pie.useMaxWidth); configureSvgSize(diagram, height, width, conf.pie.useMaxWidth);
addSVGAccessibilityFields(parser.yy, diagram, id); addSVGAccessibilityFields(diagObj.db, diagram, id);
// Set viewBox // Set viewBox
elem.setAttribute('viewBox', '0 0 ' + width + ' ' + height); elem.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
@ -72,7 +68,7 @@ export const draw = (txt, id) => {
.append('g') .append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')'); .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
var data = pieData.getSections(); var data = diagObj.db.getSections();
var sum = 0; var sum = 0;
Object.keys(data).forEach(function (key) { Object.keys(data).forEach(function (key) {
sum += data[key]; sum += data[key];
@ -136,7 +132,7 @@ export const draw = (txt, id) => {
svg svg
.append('text') .append('text')
.text(parser.yy.getDiagramTitle()) .text(diagObj.db.getDiagramTitle())
.attr('x', 0) .attr('x', 0)
.attr('y', -(height - 50) / 2) .attr('y', -(height - 50) / 2)
.attr('class', 'pieTitleText'); .attr('class', 'pieTitleText');
@ -169,7 +165,7 @@ export const draw = (txt, id) => {
.attr('x', legendRectSize + legendSpacing) .attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing) .attr('y', legendRectSize - legendSpacing)
.text(function (d) { .text(function (d) {
if (parser.yy.getShowData() || conf.showData || conf.pie.showData) { if (diagObj.db.getShowData() || conf.showData || conf.pie.showData) {
return d.data[0] + ' [' + d.data[1] + ']'; return d.data[0] + ' [' + d.data[1] + ']';
} else { } else {
return d.data[0]; return d.data[0];

View File

@ -1,29 +1,16 @@
import { line, select } from 'd3'; import { line, select } from 'd3';
import dagre from 'dagre'; import dagre from 'dagre';
import graphlib from 'graphlib'; import graphlib from 'graphlib';
// import * as configApi from '../../config';
import { log } from '../../logger'; import { log } from '../../logger';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import common from '../common/common'; import common from '../common/common';
import { parser } from './parser/requirementDiagram';
import requirementDb from './requirementDb';
import markers from './requirementMarkers'; import markers from './requirementMarkers';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
const conf = {}; let conf = {};
let relCnt = 0; let relCnt = 0;
export const setConf = function (cnf) {
if (typeof cnf === 'undefined') {
return;
}
const keys = Object.keys(cnf);
for (let i = 0; i < keys.length; i++) {
conf[keys[i]] = cnf[keys[i]];
}
};
const newRectNode = (parentNode, id) => { const newRectNode = (parentNode, id) => {
return parentNode return parentNode
.insert('rect', '#' + id) .insert('rect', '#' + id)
@ -162,7 +149,7 @@ const addEdgeLabel = (parentNode, svgPath, conf, txt) => {
.attr('fill-opacity', '85%'); .attr('fill-opacity', '85%');
}; };
const drawRelationshipFromLayout = function (svg, rel, g, insert) { const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) {
// Find the edge relating to this relationship // Find the edge relating to this relationship
const edge = g.edge(elementString(rel.src), elementString(rel.dst)); const edge = g.edge(elementString(rel.src), elementString(rel.dst));
@ -182,7 +169,7 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert) {
.attr('d', lineFunction(edge.points)) .attr('d', lineFunction(edge.points))
.attr('fill', 'none'); .attr('fill', 'none');
if (rel.type == requirementDb.Relationships.CONTAINS) { if (rel.type == diagObj.db.Relationships.CONTAINS) {
svgPath.attr( svgPath.attr(
'marker-start', 'marker-start',
'url(' + common.getUrl(conf.arrowMarkerAbsolute) + '#' + rel.type + '_line_ending' + ')' 'url(' + common.getUrl(conf.arrowMarkerAbsolute) + '#' + rel.type + '_line_ending' + ')'
@ -318,12 +305,12 @@ const elementString = (str) => {
return str.replace(/\s/g, '').replace(/\./g, '_'); return str.replace(/\s/g, '').replace(/\./g, '_');
}; };
export const draw = (text, id) => { export const draw = (text, id, _version, diagObj) => {
parser.yy = requirementDb; conf = getConfig().requirement;
parser.yy.clear(); diagObj.db.clear();
parser.parse(text); diagObj.parser.parse(text);
const securityLevel = getConfig().securityLevel; const securityLevel = conf.securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sanbox mode
let sandboxElement; let sandboxElement;
if (securityLevel === 'sandbox') { if (securityLevel === 'sandbox') {
@ -355,9 +342,9 @@ export const draw = (text, id) => {
return {}; return {};
}); });
let requirements = requirementDb.getRequirements(); let requirements = diagObj.db.getRequirements();
let elements = requirementDb.getElements(); let elements = diagObj.db.getElements();
let relationships = requirementDb.getRelationships(); let relationships = diagObj.db.getRelationships();
drawReqs(requirements, g, svg); drawReqs(requirements, g, svg);
drawElements(elements, g, svg); drawElements(elements, g, svg);
@ -366,10 +353,9 @@ export const draw = (text, id) => {
adjustEntities(svg, g); adjustEntities(svg, g);
relationships.forEach(function (rel) { relationships.forEach(function (rel) {
drawRelationshipFromLayout(svg, rel, g, id); drawRelationshipFromLayout(svg, rel, g, id, diagObj);
}); });
// svg.attr('height', '500px');
const padding = conf.rect_padding; const padding = conf.rect_padding;
const svgBounds = svg.node().getBBox(); const svgBounds = svg.node().getBBox();
const width = svgBounds.width + padding * 2; const width = svgBounds.width + padding * 2;
@ -379,10 +365,9 @@ export const draw = (text, id) => {
svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`);
// Adds title and description to the requirements diagram // Adds title and description to the requirements diagram
addSVGAccessibilityFields(parser.yy, svg, id); addSVGAccessibilityFields(diagObj.db, svg, id);
}; };
export default { export default {
setConf,
draw, draw,
}; };

View File

@ -1,9 +1,9 @@
import { parser } from './parser/sequenceDiagram'; import sequence from './parser/sequenceDiagram';
import sequenceDb from './sequenceDb'; import sequenceDb from './sequenceDb';
import * as configApi from '../../config'; import * as configApi from '../../config';
import renderer from './sequenceRenderer'; import renderer from './sequenceRenderer';
import mermaidAPI from '../../mermaidAPI'; import mermaidAPI from '../../mermaidAPI';
import Diagram from '../../Diagram';
/** /**
* @param conf * @param conf
* @param key * @param key
@ -16,18 +16,23 @@ function addConf(conf, key, value) {
return conf; return conf;
} }
const parser = sequence.parser;
describe('when parsing a sequenceDiagram', function () { describe('when parsing a sequenceDiagram', function () {
beforeEach(function () { beforeEach(function () {
parser.yy = sequenceDb; parser.yy = sequenceDb;
parser.yy.clear(); parser.yy.clear();
}); });
it('should handle a sequenceDiagram definition', function () { fit('should handle a sequenceDiagram definition', function () {
const str = ` const str = `
sequenceDiagram sequenceDiagram
Alice->Bob:Hello Bob, how are you? Alice->Bob:Hello Bob, how are you?
Note right of Bob: Bob thinks Note right of Bob: Bob thinks
Bob-->Alice: I am good thanks!`; Bob-->Alice: I am good thanks!`;
// const dia = new Diagram(str);
// console.log('Type = ' + dia.type);
mermaidAPI.parse(str); mermaidAPI.parse(str);
const actors = parser.yy.getActors(); const actors = parser.yy.getActors();
expect(actors.Alice.description).toBe('Alice'); expect(actors.Alice.description).toBe('Alice');

View File

@ -1,15 +1,13 @@
import { select, selectAll } from 'd3'; import { select, selectAll } from 'd3';
import svgDraw, { drawText, fixLifeLineHeights } from './svgDraw'; import svgDraw, { drawText, fixLifeLineHeights } from './svgDraw';
import { log } from '../../logger'; import { log } from '../../logger';
import { parser } from './parser/sequenceDiagram'; // import { parser } from './parser/sequenceDiagram';
import common from '../common/common'; import common from '../common/common';
import sequenceDb from './sequenceDb'; // import sequenceDb from './sequenceDb';
import * as configApi from '../../config'; import * as configApi from '../../config';
import utils, { assignWithDepth, configureSvgSize } from '../../utils'; import utils, { assignWithDepth, configureSvgSize } from '../../utils';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
parser.yy = sequenceDb;
let conf = {}; let conf = {};
export const bounds = { export const bounds = {
@ -86,7 +84,7 @@ export const bounds = {
stopy: undefined, stopy: undefined,
}; };
this.verticalPos = 0; this.verticalPos = 0;
setConf(parser.yy.getConfig()); setConf(configApi.getConfig());
}, },
updateVal: function (obj, key, val, fun) { updateVal: function (obj, key, val, fun) {
if (typeof obj[key] === 'undefined') { if (typeof obj[key] === 'undefined') {
@ -327,8 +325,9 @@ const boundMessage = function (diagram, msgModel) {
* @param {any} diagram - The parent of the message element * @param {any} diagram - The parent of the message element
* @param {any} msgModel - The model containing fields describing a message * @param {any} msgModel - The model containing fields describing a message
* @param {float} lineStarty - The Y coordinate at which the message line starts * @param {float} lineStarty - The Y coordinate at which the message line starts
* @param diagObj
*/ */
const drawMessage = function (diagram, msgModel, lineStarty) { const drawMessage = function (diagram, msgModel, lineStarty, diagObj) {
const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel; const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel;
let textDims = utils.calculateTextDimensions(message, messageFont(conf)); let textDims = utils.calculateTextDimensions(message, messageFont(conf));
const textObj = svgDraw.getTextObj(); const textObj = svgDraw.getTextObj();
@ -394,10 +393,10 @@ const drawMessage = function (diagram, msgModel, lineStarty) {
// Make an SVG Container // Make an SVG Container
// Draw the line // Draw the line
if ( if (
type === parser.yy.LINETYPE.DOTTED || type === diagObj.db.LINETYPE.DOTTED ||
type === parser.yy.LINETYPE.DOTTED_CROSS || type === diagObj.db.LINETYPE.DOTTED_CROSS ||
type === parser.yy.LINETYPE.DOTTED_POINT || type === diagObj.db.LINETYPE.DOTTED_POINT ||
type === parser.yy.LINETYPE.DOTTED_OPEN type === diagObj.db.LINETYPE.DOTTED_OPEN
) { ) {
line.style('stroke-dasharray', '3, 3'); line.style('stroke-dasharray', '3, 3');
line.attr('class', 'messageLine1'); line.attr('class', 'messageLine1');
@ -420,14 +419,14 @@ const drawMessage = function (diagram, msgModel, lineStarty) {
line.attr('stroke-width', 2); line.attr('stroke-width', 2);
line.attr('stroke', 'none'); // handled by theme/css anyway line.attr('stroke', 'none'); // handled by theme/css anyway
line.style('fill', 'none'); // remove any fill colour line.style('fill', 'none'); // remove any fill colour
if (type === parser.yy.LINETYPE.SOLID || type === parser.yy.LINETYPE.DOTTED) { if (type === diagObj.db.LINETYPE.SOLID || type === diagObj.db.LINETYPE.DOTTED) {
line.attr('marker-end', 'url(' + url + '#arrowhead)'); line.attr('marker-end', 'url(' + url + '#arrowhead)');
} }
if (type === parser.yy.LINETYPE.SOLID_POINT || type === parser.yy.LINETYPE.DOTTED_POINT) { if (type === diagObj.db.LINETYPE.SOLID_POINT || type === diagObj.db.LINETYPE.DOTTED_POINT) {
line.attr('marker-end', 'url(' + url + '#filled-head)'); line.attr('marker-end', 'url(' + url + '#filled-head)');
} }
if (type === parser.yy.LINETYPE.SOLID_CROSS || type === parser.yy.LINETYPE.DOTTED_CROSS) { if (type === diagObj.db.LINETYPE.SOLID_CROSS || type === diagObj.db.LINETYPE.DOTTED_CROSS) {
line.attr('marker-end', 'url(' + url + '#crosshead)'); line.attr('marker-end', 'url(' + url + '#crosshead)');
} }
@ -581,10 +580,13 @@ function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoop
/** /**
* Draws a sequenceDiagram in the tag with id: id based on the graph definition in text. * Draws a sequenceDiagram in the tag with id: id based on the graph definition in text.
* *
* @param {any} text * @param {any} text The text of the diagram
* @param {any} id * @param _text
* @param {any} id The id of the diagram which will be used as a DOM element id¨
* @param {any} _version Mermaid version from package.json
* @param {any} diagObj A stanard diagram containing the db and the text and type etc of the diagram
*/ */
export const draw = function (text, id) { export const draw = function (_text, id, _version, diagObj) {
conf = configApi.getConfig().sequence; conf = configApi.getConfig().sequence;
const securityLevel = configApi.getConfig().securityLevel; const securityLevel = configApi.getConfig().securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sanbox mode
@ -592,28 +594,25 @@ export const draw = function (text, id) {
if (securityLevel === 'sandbox') { if (securityLevel === 'sandbox') {
sandboxElement = select('#i' + id); sandboxElement = select('#i' + id);
} }
const root = const root =
securityLevel === 'sandbox' securityLevel === 'sandbox'
? select(sandboxElement.nodes()[0].contentDocument.body) ? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body'); : select('body');
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
parser.yy.clear();
parser.yy.setWrap(conf.wrap);
parser.parse(text + '\n');
bounds.init(); bounds.init();
log.debug(`C:${JSON.stringify(conf, null, 2)}`); log.debug(diagObj.db);
const diagram = const diagram =
securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : select(`[id="${id}"]`); securityLevel === 'sandbox' ? root.select(`[id="${id}"]`) : select(`[id="${id}"]`);
// Fetch data from the parsing // Fetch data from the parsing
const actors = parser.yy.getActors(); const actors = diagObj.db.getActors();
const actorKeys = parser.yy.getActorKeys(); const actorKeys = diagObj.db.getActorKeys();
const messages = parser.yy.getMessages(); const messages = diagObj.db.getMessages();
const title = parser.yy.getDiagramTitle(); const title = diagObj.db.getDiagramTitle();
const maxMessageWidthPerActor = getMaxMessageWidthPerActor(actors, messages); const maxMessageWidthPerActor = getMaxMessageWidthPerActor(actors, messages, diagObj);
conf.height = calculateActorMargins(actors, maxMessageWidthPerActor); conf.height = calculateActorMargins(actors, maxMessageWidthPerActor);
svgDraw.insertComputerIcon(diagram); svgDraw.insertComputerIcon(diagram);
@ -621,7 +620,7 @@ export const draw = function (text, id) {
svgDraw.insertClockIcon(diagram); svgDraw.insertClockIcon(diagram);
drawActors(diagram, actors, actorKeys, 0, conf, messages); drawActors(diagram, actors, actorKeys, 0, conf, messages);
const loopWidths = calculateLoopBounds(messages, actors, maxMessageWidthPerActor); const loopWidths = calculateLoopBounds(messages, actors, maxMessageWidthPerActor, diagObj);
// The arrow head definition is attached to the svg once // The arrow head definition is attached to the svg once
svgDraw.insertArrowHead(diagram); svgDraw.insertArrowHead(diagram);
@ -658,17 +657,17 @@ export const draw = function (text, id) {
let loopModel, noteModel, msgModel; let loopModel, noteModel, msgModel;
switch (msg.type) { switch (msg.type) {
case parser.yy.LINETYPE.NOTE: case diagObj.db.LINETYPE.NOTE:
noteModel = msg.noteModel; noteModel = msg.noteModel;
drawNote(diagram, noteModel); drawNote(diagram, noteModel);
break; break;
case parser.yy.LINETYPE.ACTIVE_START: case diagObj.db.LINETYPE.ACTIVE_START:
bounds.newActivation(msg, diagram, actors); bounds.newActivation(msg, diagram, actors);
break; break;
case parser.yy.LINETYPE.ACTIVE_END: case diagObj.db.LINETYPE.ACTIVE_END:
activeEnd(msg, bounds.getVerticalPos()); activeEnd(msg, bounds.getVerticalPos());
break; break;
case parser.yy.LINETYPE.LOOP_START: case diagObj.db.LINETYPE.LOOP_START:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -677,24 +676,24 @@ export const draw = function (text, id) {
(message) => bounds.newLoop(message) (message) => bounds.newLoop(message)
); );
break; break;
case parser.yy.LINETYPE.LOOP_END: case diagObj.db.LINETYPE.LOOP_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawLoop(diagram, loopModel, 'loop', conf); svgDraw.drawLoop(diagram, loopModel, 'loop', conf);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
bounds.models.addLoop(loopModel); bounds.models.addLoop(loopModel);
break; break;
case parser.yy.LINETYPE.RECT_START: case diagObj.db.LINETYPE.RECT_START:
adjustLoopHeightForWrap(loopWidths, msg, conf.boxMargin, conf.boxMargin, (message) => adjustLoopHeightForWrap(loopWidths, msg, conf.boxMargin, conf.boxMargin, (message) =>
bounds.newLoop(undefined, message.message) bounds.newLoop(undefined, message.message)
); );
break; break;
case parser.yy.LINETYPE.RECT_END: case diagObj.db.LINETYPE.RECT_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawBackgroundRect(diagram, loopModel); svgDraw.drawBackgroundRect(diagram, loopModel);
bounds.models.addLoop(loopModel); bounds.models.addLoop(loopModel);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
break; break;
case parser.yy.LINETYPE.OPT_START: case diagObj.db.LINETYPE.OPT_START:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -703,13 +702,13 @@ export const draw = function (text, id) {
(message) => bounds.newLoop(message) (message) => bounds.newLoop(message)
); );
break; break;
case parser.yy.LINETYPE.OPT_END: case diagObj.db.LINETYPE.OPT_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawLoop(diagram, loopModel, 'opt', conf); svgDraw.drawLoop(diagram, loopModel, 'opt', conf);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
bounds.models.addLoop(loopModel); bounds.models.addLoop(loopModel);
break; break;
case parser.yy.LINETYPE.ALT_START: case diagObj.db.LINETYPE.ALT_START:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -718,7 +717,7 @@ export const draw = function (text, id) {
(message) => bounds.newLoop(message) (message) => bounds.newLoop(message)
); );
break; break;
case parser.yy.LINETYPE.ALT_ELSE: case diagObj.db.LINETYPE.ALT_ELSE:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -727,13 +726,13 @@ export const draw = function (text, id) {
(message) => bounds.addSectionToLoop(message) (message) => bounds.addSectionToLoop(message)
); );
break; break;
case parser.yy.LINETYPE.ALT_END: case diagObj.db.LINETYPE.ALT_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawLoop(diagram, loopModel, 'alt', conf); svgDraw.drawLoop(diagram, loopModel, 'alt', conf);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
bounds.models.addLoop(loopModel); bounds.models.addLoop(loopModel);
break; break;
case parser.yy.LINETYPE.PAR_START: case diagObj.db.LINETYPE.PAR_START:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -742,7 +741,7 @@ export const draw = function (text, id) {
(message) => bounds.newLoop(message) (message) => bounds.newLoop(message)
); );
break; break;
case parser.yy.LINETYPE.PAR_AND: case diagObj.db.LINETYPE.PAR_AND:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -751,19 +750,19 @@ export const draw = function (text, id) {
(message) => bounds.addSectionToLoop(message) (message) => bounds.addSectionToLoop(message)
); );
break; break;
case parser.yy.LINETYPE.PAR_END: case diagObj.db.LINETYPE.PAR_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawLoop(diagram, loopModel, 'par', conf); svgDraw.drawLoop(diagram, loopModel, 'par', conf);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
bounds.models.addLoop(loopModel); bounds.models.addLoop(loopModel);
break; break;
case parser.yy.LINETYPE.AUTONUMBER: case diagObj.db.LINETYPE.AUTONUMBER:
sequenceIndex = msg.message.start || sequenceIndex; sequenceIndex = msg.message.start || sequenceIndex;
sequenceIndexStep = msg.message.step || sequenceIndexStep; sequenceIndexStep = msg.message.step || sequenceIndexStep;
if (msg.message.visible) parser.yy.enableSequenceNumbers(); if (msg.message.visible) diagObj.db.enableSequenceNumbers();
else parser.yy.disableSequenceNumbers(); else diagObj.db.disableSequenceNumbers();
break; break;
case parser.yy.LINETYPE.CRITICAL_START: case diagObj.db.LINETYPE.CRITICAL_START:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -772,7 +771,7 @@ export const draw = function (text, id) {
(message) => bounds.newLoop(message) (message) => bounds.newLoop(message)
); );
break; break;
case parser.yy.LINETYPE.CRITICAL_OPTION: case diagObj.db.LINETYPE.CRITICAL_OPTION:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -781,13 +780,13 @@ export const draw = function (text, id) {
(message) => bounds.addSectionToLoop(message) (message) => bounds.addSectionToLoop(message)
); );
break; break;
case parser.yy.LINETYPE.CRITICAL_END: case diagObj.db.LINETYPE.CRITICAL_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawLoop(diagram, loopModel, 'critical', conf); svgDraw.drawLoop(diagram, loopModel, 'critical', conf);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
bounds.models.addLoop(loopModel); bounds.models.addLoop(loopModel);
break; break;
case parser.yy.LINETYPE.BREAK_START: case diagObj.db.LINETYPE.BREAK_START:
adjustLoopHeightForWrap( adjustLoopHeightForWrap(
loopWidths, loopWidths,
msg, msg,
@ -796,7 +795,7 @@ export const draw = function (text, id) {
(message) => bounds.newLoop(message) (message) => bounds.newLoop(message)
); );
break; break;
case parser.yy.LINETYPE.BREAK_END: case diagObj.db.LINETYPE.BREAK_END:
loopModel = bounds.endLoop(); loopModel = bounds.endLoop();
svgDraw.drawLoop(diagram, loopModel, 'break', conf); svgDraw.drawLoop(diagram, loopModel, 'break', conf);
bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());
@ -808,7 +807,7 @@ export const draw = function (text, id) {
msgModel = msg.msgModel; msgModel = msg.msgModel;
msgModel.starty = bounds.getVerticalPos(); msgModel.starty = bounds.getVerticalPos();
msgModel.sequenceIndex = sequenceIndex; msgModel.sequenceIndex = sequenceIndex;
msgModel.sequenceVisible = parser.yy.showSequenceNumbers(); msgModel.sequenceVisible = diagObj.db.showSequenceNumbers();
let lineStarty = boundMessage(diagram, msgModel); let lineStarty = boundMessage(diagram, msgModel);
messagesToDraw.push({ messageModel: msgModel, lineStarty: lineStarty }); messagesToDraw.push({ messageModel: msgModel, lineStarty: lineStarty });
bounds.models.addMessage(msgModel); bounds.models.addMessage(msgModel);
@ -820,21 +819,21 @@ export const draw = function (text, id) {
// Increment sequence counter if msg.type is a line (and not another event like activation or note, etc) // Increment sequence counter if msg.type is a line (and not another event like activation or note, etc)
if ( if (
[ [
parser.yy.LINETYPE.SOLID_OPEN, diagObj.db.LINETYPE.SOLID_OPEN,
parser.yy.LINETYPE.DOTTED_OPEN, diagObj.db.LINETYPE.DOTTED_OPEN,
parser.yy.LINETYPE.SOLID, diagObj.db.LINETYPE.SOLID,
parser.yy.LINETYPE.DOTTED, diagObj.db.LINETYPE.DOTTED,
parser.yy.LINETYPE.SOLID_CROSS, diagObj.db.LINETYPE.SOLID_CROSS,
parser.yy.LINETYPE.DOTTED_CROSS, diagObj.db.LINETYPE.DOTTED_CROSS,
parser.yy.LINETYPE.SOLID_POINT, diagObj.db.LINETYPE.SOLID_POINT,
parser.yy.LINETYPE.DOTTED_POINT, diagObj.db.LINETYPE.DOTTED_POINT,
].includes(msg.type) ].includes(msg.type)
) { ) {
sequenceIndex = sequenceIndex + sequenceIndexStep; sequenceIndex = sequenceIndex + sequenceIndexStep;
} }
}); });
messagesToDraw.forEach((e) => drawMessage(diagram, e.messageModel, e.lineStarty)); messagesToDraw.forEach((e) => drawMessage(diagram, e.messageModel, e.lineStarty, diagObj));
if (conf.mirrorActors) { if (conf.mirrorActors) {
// Draw actors below diagram // Draw actors below diagram
@ -895,7 +894,7 @@ export const draw = function (text, id) {
(height + extraVertForTitle) (height + extraVertForTitle)
); );
addSVGAccessibilityFields(parser.yy, diagram, id); addSVGAccessibilityFields(diagObj.db, diagram, id);
log.debug(`models:`, bounds.models); log.debug(`models:`, bounds.models);
}; };
@ -907,9 +906,10 @@ export const draw = function (text, id) {
* *
* @param {any} actors - The actors map * @param {any} actors - The actors map
* @param {Array} messages - A list of message objects to iterate * @param {Array} messages - A list of message objects to iterate
* @param diagObj
* @returns {any} * @returns {any}
*/ */
const getMaxMessageWidthPerActor = function (actors, messages) { const getMaxMessageWidthPerActor = function (actors, messages, diagObj) {
const maxMessageWidthPerActor = {}; const maxMessageWidthPerActor = {};
messages.forEach(function (msg) { messages.forEach(function (msg) {
@ -917,12 +917,12 @@ const getMaxMessageWidthPerActor = function (actors, messages) {
const actor = actors[msg.to]; const actor = actors[msg.to];
// If this is the first actor, and the message is left of it, no need to calculate the margin // If this is the first actor, and the message is left of it, no need to calculate the margin
if (msg.placement === parser.yy.PLACEMENT.LEFTOF && !actor.prevActor) { if (msg.placement === diagObj.db.PLACEMENT.LEFTOF && !actor.prevActor) {
return; return;
} }
// If this is the last actor, and the message is right of it, no need to calculate the margin // If this is the last actor, and the message is right of it, no need to calculate the margin
if (msg.placement === parser.yy.PLACEMENT.RIGHTOF && !actor.nextActor) { if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF && !actor.nextActor) {
return; return;
} }
@ -972,17 +972,17 @@ const getMaxMessageWidthPerActor = function (actors, messages) {
maxMessageWidthPerActor[msg.to] || 0, maxMessageWidthPerActor[msg.to] || 0,
messageWidth / 2 messageWidth / 2
); );
} else if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) { } else if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) {
maxMessageWidthPerActor[msg.from] = Math.max( maxMessageWidthPerActor[msg.from] = Math.max(
maxMessageWidthPerActor[msg.from] || 0, maxMessageWidthPerActor[msg.from] || 0,
messageWidth messageWidth
); );
} else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) { } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) {
maxMessageWidthPerActor[actor.prevActor] = Math.max( maxMessageWidthPerActor[actor.prevActor] = Math.max(
maxMessageWidthPerActor[actor.prevActor] || 0, maxMessageWidthPerActor[actor.prevActor] || 0,
messageWidth messageWidth
); );
} else if (msg.placement === parser.yy.PLACEMENT.OVER) { } else if (msg.placement === diagObj.db.PLACEMENT.OVER) {
if (actor.prevActor) { if (actor.prevActor) {
maxMessageWidthPerActor[actor.prevActor] = Math.max( maxMessageWidthPerActor[actor.prevActor] = Math.max(
maxMessageWidthPerActor[actor.prevActor] || 0, maxMessageWidthPerActor[actor.prevActor] || 0,
@ -1070,7 +1070,7 @@ const calculateActorMargins = function (actors, actorToMessageWidth) {
return Math.max(maxHeight, conf.height); return Math.max(maxHeight, conf.height);
}; };
const buildNoteModel = function (msg, actors) { const buildNoteModel = function (msg, actors, diagObj) {
let startx = actors[msg.from].x; let startx = actors[msg.from].x;
let stopx = actors[msg.to].x; let stopx = actors[msg.to].x;
let shouldWrap = msg.wrap && msg.message; let shouldWrap = msg.wrap && msg.message;
@ -1090,7 +1090,7 @@ const buildNoteModel = function (msg, actors) {
stopy: 0, stopy: 0,
message: msg.message, message: msg.message,
}; };
if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) { if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) {
noteModel.width = shouldWrap noteModel.width = shouldWrap
? Math.max(conf.width, textDimensions.width) ? Math.max(conf.width, textDimensions.width)
: Math.max( : Math.max(
@ -1098,7 +1098,7 @@ const buildNoteModel = function (msg, actors) {
textDimensions.width + 2 * conf.noteMargin textDimensions.width + 2 * conf.noteMargin
); );
noteModel.startx = startx + (actors[msg.from].width + conf.actorMargin) / 2; noteModel.startx = startx + (actors[msg.from].width + conf.actorMargin) / 2;
} else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) { } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) {
noteModel.width = shouldWrap noteModel.width = shouldWrap
? Math.max(conf.width, textDimensions.width + 2 * conf.noteMargin) ? Math.max(conf.width, textDimensions.width + 2 * conf.noteMargin)
: Math.max( : Math.max(
@ -1139,18 +1139,18 @@ const buildNoteModel = function (msg, actors) {
return noteModel; return noteModel;
}; };
const buildMessageModel = function (msg, actors) { const buildMessageModel = function (msg, actors, diagObj) {
let process = false; let process = false;
if ( if (
[ [
parser.yy.LINETYPE.SOLID_OPEN, diagObj.db.LINETYPE.SOLID_OPEN,
parser.yy.LINETYPE.DOTTED_OPEN, diagObj.db.LINETYPE.DOTTED_OPEN,
parser.yy.LINETYPE.SOLID, diagObj.db.LINETYPE.SOLID,
parser.yy.LINETYPE.DOTTED, diagObj.db.LINETYPE.DOTTED,
parser.yy.LINETYPE.SOLID_CROSS, diagObj.db.LINETYPE.SOLID_CROSS,
parser.yy.LINETYPE.DOTTED_CROSS, diagObj.db.LINETYPE.DOTTED_CROSS,
parser.yy.LINETYPE.SOLID_POINT, diagObj.db.LINETYPE.SOLID_POINT,
parser.yy.LINETYPE.DOTTED_POINT, diagObj.db.LINETYPE.DOTTED_POINT,
].includes(msg.type) ].includes(msg.type)
) { ) {
process = true; process = true;
@ -1192,7 +1192,7 @@ const buildMessageModel = function (msg, actors) {
}; };
}; };
const calculateLoopBounds = function (messages, actors) { const calculateLoopBounds = function (messages, actors, _maxWidthPerActor, diagObj) {
const loops = {}; const loops = {};
const stack = []; const stack = [];
let current, noteModel, msgModel; let current, noteModel, msgModel;
@ -1200,12 +1200,12 @@ const calculateLoopBounds = function (messages, actors) {
messages.forEach(function (msg) { messages.forEach(function (msg) {
msg.id = utils.random({ length: 10 }); msg.id = utils.random({ length: 10 });
switch (msg.type) { switch (msg.type) {
case parser.yy.LINETYPE.LOOP_START: case diagObj.db.LINETYPE.LOOP_START:
case parser.yy.LINETYPE.ALT_START: case diagObj.db.LINETYPE.ALT_START:
case parser.yy.LINETYPE.OPT_START: case diagObj.db.LINETYPE.OPT_START:
case parser.yy.LINETYPE.PAR_START: case diagObj.db.LINETYPE.PAR_START:
case parser.yy.LINETYPE.CRITICAL_START: case diagObj.db.LINETYPE.CRITICAL_START:
case parser.yy.LINETYPE.BREAK_START: case diagObj.db.LINETYPE.BREAK_START:
stack.push({ stack.push({
id: msg.id, id: msg.id,
msg: msg.message, msg: msg.message,
@ -1214,9 +1214,9 @@ const calculateLoopBounds = function (messages, actors) {
width: 0, width: 0,
}); });
break; break;
case parser.yy.LINETYPE.ALT_ELSE: case diagObj.db.LINETYPE.ALT_ELSE:
case parser.yy.LINETYPE.PAR_AND: case diagObj.db.LINETYPE.PAR_AND:
case parser.yy.LINETYPE.CRITICAL_OPTION: case diagObj.db.LINETYPE.CRITICAL_OPTION:
if (msg.message) { if (msg.message) {
current = stack.pop(); current = stack.pop();
loops[current.id] = current; loops[current.id] = current;
@ -1224,16 +1224,16 @@ const calculateLoopBounds = function (messages, actors) {
stack.push(current); stack.push(current);
} }
break; break;
case parser.yy.LINETYPE.LOOP_END: case diagObj.db.LINETYPE.LOOP_END:
case parser.yy.LINETYPE.ALT_END: case diagObj.db.LINETYPE.ALT_END:
case parser.yy.LINETYPE.OPT_END: case diagObj.db.LINETYPE.OPT_END:
case parser.yy.LINETYPE.PAR_END: case diagObj.db.LINETYPE.PAR_END:
case parser.yy.LINETYPE.CRITICAL_END: case diagObj.db.LINETYPE.CRITICAL_END:
case parser.yy.LINETYPE.BREAK_END: case diagObj.db.LINETYPE.BREAK_END:
current = stack.pop(); current = stack.pop();
loops[current.id] = current; loops[current.id] = current;
break; break;
case parser.yy.LINETYPE.ACTIVE_START: case diagObj.db.LINETYPE.ACTIVE_START:
{ {
const actorRect = actors[msg.from ? msg.from.actor : msg.to.actor]; const actorRect = actors[msg.from ? msg.from.actor : msg.to.actor];
const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length; const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length;
@ -1248,7 +1248,7 @@ const calculateLoopBounds = function (messages, actors) {
bounds.activations.push(toAdd); bounds.activations.push(toAdd);
} }
break; break;
case parser.yy.LINETYPE.ACTIVE_END: case diagObj.db.LINETYPE.ACTIVE_END:
{ {
const lastActorActivationIdx = bounds.activations const lastActorActivationIdx = bounds.activations
.map((a) => a.actor) .map((a) => a.actor)
@ -1259,7 +1259,7 @@ const calculateLoopBounds = function (messages, actors) {
} }
const isNote = msg.placement !== undefined; const isNote = msg.placement !== undefined;
if (isNote) { if (isNote) {
noteModel = buildNoteModel(msg, actors); noteModel = buildNoteModel(msg, actors, diagObj);
msg.noteModel = noteModel; msg.noteModel = noteModel;
stack.forEach((stk) => { stack.forEach((stk) => {
current = stk; current = stk;
@ -1269,7 +1269,7 @@ const calculateLoopBounds = function (messages, actors) {
Math.max(current.width, Math.abs(current.from - current.to)) - conf.labelBoxWidth; Math.max(current.width, Math.abs(current.from - current.to)) - conf.labelBoxWidth;
}); });
} else { } else {
msgModel = buildMessageModel(msg, actors); msgModel = buildMessageModel(msg, actors, diagObj);
msg.msgModel = msgModel; msg.msgModel = msgModel;
if (msgModel.startx && msgModel.stopx && stack.length > 0) { if (msgModel.startx && msgModel.stopx && stack.length > 0) {
stack.forEach((stk) => { stack.forEach((stk) => {

View File

@ -1,7 +1,5 @@
import graphlib from 'graphlib'; import graphlib from 'graphlib';
import { select } from 'd3'; import { select } from 'd3';
import stateDb from './stateDb';
import state from './parser/stateDiagram';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import { render } from '../../dagre-wrapper/index.js'; import { render } from '../../dagre-wrapper/index.js';
import { log } from '../../logger'; import { log } from '../../logger';
@ -23,17 +21,16 @@ let nodeDb = {};
* Returns the all the styles from classDef statements in the graph definition. * Returns the all the styles from classDef statements in the graph definition.
* *
* @param {any} text * @param {any} text
* @param diag
* @returns {object} ClassDef styles * @returns {object} ClassDef styles
*/ */
export const getClasses = function (text) { export const getClasses = function (text, diag) {
log.trace('Extracting classes'); log.trace('Extracting classes');
stateDb.clear(); diag.sb.clear();
const parser = state.parser;
parser.yy = stateDb;
// Parse the graph definition // Parse the graph definition
parser.parse(text); diag.parser.parse(text);
return stateDb.getClasses(); return diag.sb.getClasses();
}; };
const setupNode = (g, parent, node, altFlag) => { const setupNode = (g, parent, node, altFlag) => {
@ -238,19 +235,15 @@ const getDir = (nodes, defaultDir) => {
* *
* @param {any} text * @param {any} text
* @param {any} id * @param {any} id
* @param _version
* @param diag
*/ */
export const draw = function (text, id) { export const draw = function (text, id, _version, diag) {
log.info('Drawing state diagram (v2)', id); log.info('Drawing state diagram (v2)', id);
stateDb.clear(); // diag.sb.clear();
nodeDb = {}; nodeDb = {};
const parser = state.parser;
parser.yy = stateDb;
// Parse the graph definition
parser.parse(text);
// Fetch the default direction, use TD if none was found // Fetch the default direction, use TD if none was found
let dir = stateDb.getDirection(); let dir = diag.db.getDirection();
if (typeof dir === 'undefined') { if (typeof dir === 'undefined') {
dir = 'LR'; dir = 'LR';
} }
@ -261,9 +254,9 @@ export const draw = function (text, id) {
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
log.info(stateDb.getRootDocV2()); log.info(diag.db.getRootDocV2());
stateDb.extract(stateDb.getRootDocV2()); diag.db.extract(diag.db.getRootDocV2());
log.info(stateDb.getRootDocV2()); log.info(diag.db.getRootDocV2());
// Create the input mermaid.graph // Create the input mermaid.graph
const g = new graphlib.Graph({ const g = new graphlib.Graph({
@ -271,7 +264,7 @@ export const draw = function (text, id) {
compound: true, compound: true,
}) })
.setGraph({ .setGraph({
rankdir: getDir(stateDb.getRootDocV2()), rankdir: getDir(diag.db.getRootDocV2()),
nodesep: nodeSpacing, nodesep: nodeSpacing,
ranksep: rankSpacing, ranksep: rankSpacing,
marginx: 8, marginx: 8,
@ -281,7 +274,7 @@ export const draw = function (text, id) {
return {}; return {};
}); });
setupNode(g, undefined, stateDb.getRootDocV2(), true); setupNode(g, undefined, diag.db.getRootDocV2(), true);
// Set up an SVG group so that we can translate the final graph. // Set up an SVG group so that we can translate the final graph.
let sandboxElement; let sandboxElement;
@ -337,7 +330,7 @@ export const draw = function (text, id) {
label.insertBefore(rect, label.firstChild); label.insertBefore(rect, label.firstChild);
// } // }
} }
addSVGAccessibilityFields(parser.yy, svg, id); addSVGAccessibilityFields(diag.db, svg, id);
}; };
export default { export default {

View File

@ -2,17 +2,12 @@ import { select } from 'd3';
import dagre from 'dagre'; import dagre from 'dagre';
import graphlib from 'graphlib'; import graphlib from 'graphlib';
import { log } from '../../logger'; import { log } from '../../logger';
import stateDb from './stateDb';
import common from '../common/common'; import common from '../common/common';
import { parser } from './parser/stateDiagram';
// import idCache from './id-cache';
import { drawState, addTitleAndBox, drawEdge } from './shapes'; import { drawState, addTitleAndBox, drawEdge } from './shapes';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
parser.yy = stateDb;
// TODO Move conf object to main conf in mermaidAPI // TODO Move conf object to main conf in mermaidAPI
let conf; let conf;
@ -44,8 +39,10 @@ const insertMarkers = function (elem) {
* *
* @param {any} text * @param {any} text
* @param {any} id * @param {any} id
* @param _version
* @param diagObj
*/ */
export const draw = function (text, id) { export const draw = function (text, id, _version, diagObj) {
conf = getConfig().state; conf = getConfig().state;
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sanbox mode
@ -59,8 +56,8 @@ export const draw = function (text, id) {
: select('body'); : select('body');
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
parser.yy.clear(); // diagObj.db.clear();
parser.parse(text); // parser.parse(text);
log.debug('Rendering diagram ' + text); log.debug('Rendering diagram ' + text);
// Fetch the default direction, use TD if none was found // Fetch the default direction, use TD if none was found
@ -81,8 +78,8 @@ export const draw = function (text, id) {
return {}; return {};
}); });
const rootDoc = stateDb.getRootDoc(); const rootDoc = diagObj.db.getRootDoc();
renderDoc(rootDoc, diagram, undefined, false, root, doc); renderDoc(rootDoc, diagram, undefined, false, root, doc, diagObj);
const padding = conf.padding; const padding = conf.padding;
const bounds = diagram.node().getBBox(); const bounds = diagram.node().getBBox();
@ -98,13 +95,13 @@ export const draw = function (text, id) {
'viewBox', 'viewBox',
`${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + ' ' + height
); );
addSVGAccessibilityFields(parser.yy, diagram, id); addSVGAccessibilityFields(diagObj.db, diagram, id);
}; };
const getLabelWidth = (text) => { const getLabelWidth = (text) => {
return text ? text.length * conf.fontSizeFactor : 1; return text ? text.length * conf.fontSizeFactor : 1;
}; };
const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument) => { const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) => {
// Layout graph, Create a new directed graph // Layout graph, Create a new directed graph
const graph = new graphlib.Graph({ const graph = new graphlib.Graph({
compound: true, compound: true,
@ -155,9 +152,9 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument) => {
return {}; return {};
}); });
stateDb.extract(doc); diagObj.db.extract(doc);
const states = stateDb.getStates(); const states = diagObj.db.getStates();
const relations = stateDb.getRelations(); const relations = diagObj.db.getRelations();
const keys = Object.keys(states); const keys = Object.keys(states);
@ -173,7 +170,7 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument) => {
let node; let node;
if (stateDef.doc) { if (stateDef.doc) {
let sub = diagram.append('g').attr('id', stateDef.id).attr('class', 'stateGroup'); let sub = diagram.append('g').attr('id', stateDef.id).attr('class', 'stateGroup');
node = renderDoc(stateDef.doc, sub, stateDef.id, !altBkg, root, domDocument); node = renderDoc(stateDef.doc, sub, stateDef.id, !altBkg, root, domDocument, diagObj);
if (first) { if (first) {
// first = false; // first = false;

View File

@ -1,13 +1,9 @@
import { select } from 'd3'; import { select } from 'd3';
import { parser } from './parser/journey';
import journeyDb from './journeyDb';
import svgDraw from './svgDraw'; import svgDraw from './svgDraw';
import { getConfig } from '../../config'; import { getConfig } from '../../config';
import { configureSvgSize } from '../../utils'; import { configureSvgSize } from '../../utils';
import addSVGAccessibilityFields from '../../accessibility'; import addSVGAccessibilityFields from '../../accessibility';
parser.yy = journeyDb;
export const setConf = function (cnf) { export const setConf = function (cnf) {
const keys = Object.keys(cnf); const keys = Object.keys(cnf);
@ -50,10 +46,10 @@ function drawActorLegend(diagram) {
} }
const conf = getConfig().journey; const conf = getConfig().journey;
const LEFT_MARGIN = getConfig().journey.leftMargin; const LEFT_MARGIN = getConfig().journey.leftMargin;
export const draw = function (text, id) { export const draw = function (text, id, version, diagObj) {
const conf = getConfig().journey; const conf = getConfig().journey;
parser.yy.clear(); diagObj.db.clear();
parser.parse(text + '\n'); diagObj.parser.parse(text + '\n');
const securityLevel = getConfig().securityLevel; const securityLevel = getConfig().securityLevel;
// Handle root and Document for when rendering in sanbox mode // Handle root and Document for when rendering in sanbox mode
@ -65,17 +61,18 @@ export const draw = function (text, id) {
securityLevel === 'sandbox' securityLevel === 'sandbox'
? select(sandboxElement.nodes()[0].contentDocument.body) ? select(sandboxElement.nodes()[0].contentDocument.body)
: select('body'); : select('body');
const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; // const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
bounds.init(); bounds.init();
const diagram = root.select('#' + id); const diagram = root.select('#' + id);
svgDraw.initGraphics(diagram); svgDraw.initGraphics(diagram);
const tasks = parser.yy.getTasks(); const tasks = diagObj.db.getTasks();
const title = parser.yy.getDiagramTitle(); console.log('text and tasks', text, tasks);
const title = diagObj.db.getDiagramTitle();
const actorNames = parser.yy.getActors(); const actorNames = diagObj.db.getActors();
for (let member in actors) delete actors[member]; for (let member in actors) delete actors[member];
let actorPos = 0; let actorPos = 0;
actorNames.forEach((actorName) => { actorNames.forEach((actorName) => {
@ -122,7 +119,7 @@ export const draw = function (text, id) {
diagram.attr('preserveAspectRatio', 'xMinYMin meet'); diagram.attr('preserveAspectRatio', 'xMinYMin meet');
diagram.attr('height', height + extraVertForTitle + 25); diagram.attr('height', height + extraVertForTitle + 25);
addSVGAccessibilityFields(parser.yy, diagram, id); addSVGAccessibilityFields(diagObj.db, diagram, id);
}; };
export const bounds = { export const bounds = {

View File

@ -2,6 +2,7 @@ import mermaid from './mermaid';
import flowDb from './diagrams/flowchart/flowDb'; import flowDb from './diagrams/flowchart/flowDb';
import flowParser from './diagrams/flowchart/parser/flow'; import flowParser from './diagrams/flowchart/parser/flow';
import flowRenderer from './diagrams/flowchart/flowRenderer'; import flowRenderer from './diagrams/flowchart/flowRenderer';
import Diagram from './Diagram';
const spyOn = jest.spyOn; const spyOn = jest.spyOn;
@ -46,9 +47,9 @@ describe('when using mermaid and ', function () {
flowDb.setGen('gen-2'); flowDb.setGen('gen-2');
}); });
it('it should handle edges with text', function () { it('it should handle edges with text', function () {
flowParser.parser.parse('graph TD;A-->|text ex|B;'); const diag = new Diagram('graph TD;A-->|text ex|B;');
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
@ -59,13 +60,13 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
it('should handle edges without text', function () { it('should handle edges without text', function () {
flowParser.parser.parse('graph TD;A-->B;'); const diag = new Diagram('graph TD;A-->B;');
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
@ -75,13 +76,13 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
it('should handle open-ended edges', function () { it('should handle open-ended edges', function () {
flowParser.parser.parse('graph TD;A---B;'); const diag = new Diagram('graph TD;A---B;');
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
@ -91,13 +92,13 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
it('should handle edges with styles defined', function () { it('should handle edges with styles defined', function () {
flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;'); const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
@ -108,12 +109,12 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
it('should handle edges with interpolation defined', function () { it('should handle edges with interpolation defined', function () {
flowParser.parser.parse('graph TD;A---B; linkStyle 0 interpolate basis'); const diag = new Diagram('graph TD;A---B; linkStyle 0 interpolate basis');
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
@ -124,14 +125,14 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
it('should handle edges with text and styles defined', function () { it('should handle edges with text and styles defined', function () {
flowParser.parser.parse( const diag = new Diagram(
'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;' 'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;'
); );
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
@ -143,13 +144,13 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
it('should set fill to "none" by default when handling edges', function () { it('should set fill to "none" by default when handling edges', function () {
flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;'); const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
@ -160,15 +161,15 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
it('should not set fill to none if fill is set in linkStyle', function () { it('should not set fill to none if fill is set in linkStyle', function () {
flowParser.parser.parse( const diag = new Diagram(
'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;' 'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;'
); );
flowParser.parser.yy.getVertices(); diag.db.getVertices();
const edges = flowParser.parser.yy.getEdges(); const edges = diag.db.getEdges();
const mockG = { const mockG = {
setEdge: function (start, end, options) { setEdge: function (start, end, options) {
expect(start).toContain('flowchart-A-'); expect(start).toContain('flowchart-A-');
@ -178,7 +179,7 @@ describe('when using mermaid and ', function () {
}, },
}; };
flowRenderer.addEdges(edges, mockG); flowRenderer.addEdges(edges, mockG, diag);
}); });
}); });

View File

@ -59,6 +59,7 @@ import stateRendererV2 from './diagrams/state/stateRenderer-v2';
import journeyDb from './diagrams/user-journey/journeyDb'; import journeyDb from './diagrams/user-journey/journeyDb';
import journeyRenderer from './diagrams/user-journey/journeyRenderer'; import journeyRenderer from './diagrams/user-journey/journeyRenderer';
import journeyParser from './diagrams/user-journey/parser/journey'; import journeyParser from './diagrams/user-journey/parser/journey';
import Diagram from './Diagram';
import errorRenderer from './errorRenderer'; import errorRenderer from './errorRenderer';
import { attachFunctions } from './interactionDb'; import { attachFunctions } from './interactionDb';
import { log, setLogLevel } from './logger'; import { log, setLogLevel } from './logger';
@ -70,96 +71,20 @@ import mermaid from './mermaid';
/** /**
* @param text * @param text
* @param dia
* @returns {any} * @returns {any}
*/ */
function parse(text) { function parse(text, dia) {
var parseEncounteredException = false; var parseEncounteredException = false;
try { try {
text = text + '\n'; text = text + '\n';
const diag = dia ? dia : new Diagram(text);
diag.db.clear();
const cnf = configApi.getConfig(); const cnf = configApi.getConfig();
const graphInit = utils.detectInit(text, cnf); let parser = diag.parser;
if (graphInit) {
reinitialize(graphInit);
log.info('reinit ', graphInit);
}
const graphType = utils.detectType(text, cnf);
let parser;
log.debug('Type ' + graphType); log.debug('Type ' + diag.type);
switch (graphType) { parser.parser.yy.graphType = diag.type;
case 'c4':
c4Db.clear();
parser = c4Parser;
parser.parser.yy = c4Db;
break;
case 'gitGraph':
gitGraphAst.clear();
parser = gitGraphParser;
parser.parser.yy = gitGraphAst;
break;
case 'flowchart':
flowDb.clear();
parser = flowParser;
parser.parser.yy = flowDb;
break;
case 'flowchart-v2':
flowDb.clear();
parser = flowParser;
parser.parser.yy = flowDb;
break;
case 'sequence':
sequenceDb.clear();
parser = sequenceParser;
parser.parser.yy = sequenceDb;
break;
case 'gantt':
parser = ganttParser;
parser.parser.yy = ganttDb;
break;
case 'class':
parser = classParser;
parser.parser.yy = classDb;
break;
case 'classDiagram':
parser = classParser;
parser.parser.yy = classDb;
break;
case 'state':
parser = stateParser;
parser.parser.yy = stateDb;
break;
case 'stateDiagram':
parser = stateParser;
parser.parser.yy = stateDb;
break;
case 'info':
log.debug('info info info');
parser = infoParser;
parser.parser.yy = infoDb;
break;
case 'pie':
log.debug('pie');
parser = pieParser;
parser.parser.yy = pieDb;
break;
case 'er':
log.debug('er');
parser = erParser;
parser.parser.yy = erDb;
break;
case 'journey':
log.debug('Journey');
parser = journeyParser;
parser.parser.yy = journeyDb;
break;
case 'requirement':
case 'requirementDiagram':
log.debug('RequirementDiagram');
parser = requirementParser;
parser.parser.yy = requirementDb;
break;
}
parser.parser.yy.graphType = graphType;
parser.parser.yy.parseError = (str, hash) => { parser.parser.yy.parseError = (str, hash) => {
const error = { str, hash }; const error = { str, hash };
throw error; throw error;
@ -269,7 +194,6 @@ const render = function (id, _txt, cb, container) {
txt = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa'; txt = 'graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa';
} }
// let d3Iframe;
let root = select('body'); let root = select('body');
// In regular execution the container will be the div with a mermaid class // In regular execution the container will be the div with a mermaid class
@ -282,7 +206,6 @@ const render = function (id, _txt, cb, container) {
.attr('id', 'i' + id) .attr('id', 'i' + id)
.attr('style', 'width: 100%; height: 100%;') .attr('style', 'width: 100%; height: 100%;')
.attr('sandbox', ''); .attr('sandbox', '');
// const iframeBody = ;
root = select(iframe.nodes()[0].contentDocument.body); root = select(iframe.nodes()[0].contentDocument.body);
root.node().style.margin = 0; root.node().style.margin = 0;
} }
@ -335,15 +258,6 @@ const render = function (id, _txt, cb, container) {
element.remove(); element.remove();
} }
// if (cnf.securityLevel === 'sandbox') {
// const iframe = select('body')
// .append('iframe')
// .attr('id', 'i' + id)
// .attr('sandbox', '');
// // const iframeBody = ;
// root = select(iframe.nodes()[0].contentDocument.body);
// }
// Add the tmp div used for rendering with the id `d${id}` // Add the tmp div used for rendering with the id `d${id}`
// d+id it will contain a svg with the id "id" // d+id it will contain a svg with the id "id"
@ -355,7 +269,7 @@ const render = function (id, _txt, cb, container) {
.attr('id', 'i' + id) .attr('id', 'i' + id)
.attr('style', 'width: 100%; height: 100%;') .attr('style', 'width: 100%; height: 100%;')
.attr('sandbox', ''); .attr('sandbox', '');
// const iframeBody = ;
root = select(iframe.nodes()[0].contentDocument.body); root = select(iframe.nodes()[0].contentDocument.body);
root.node().style.margin = 0; root.node().style.margin = 0;
} else { } else {
@ -376,9 +290,10 @@ const render = function (id, _txt, cb, container) {
txt = encodeEntities(txt); txt = encodeEntities(txt);
const diag = new Diagram(txt);
// Get the tmp element containing the the svg // Get the tmp element containing the the svg
const element = root.select('#d' + id).node(); const element = root.select('#d' + id).node();
const graphType = utils.detectType(txt, cnf); const graphType = diag.type;
// insert inline style into svg // insert inline style into svg
const svg = element.firstChild; const svg = element.firstChild;
@ -402,7 +317,7 @@ const render = function (id, _txt, cb, container) {
// classDef // classDef
if (graphType === 'flowchart' || graphType === 'flowchart-v2' || graphType === 'graph') { if (graphType === 'flowchart' || graphType === 'flowchart-v2' || graphType === 'graph') {
const classes = flowRenderer.getClasses(txt); const classes = flowRenderer.getClasses(txt, diag);
const htmlLabels = cnf.htmlLabels || cnf.flowchart.htmlLabels; const htmlLabels = cnf.htmlLabels || cnf.flowchart.htmlLabels;
for (const className in classes) { for (const className in classes) {
if (htmlLabels) { if (htmlLabels) {
@ -437,8 +352,6 @@ const render = function (id, _txt, cb, container) {
} }
} }
// log.warn(cnf.themeVariables);
const stylis = (selector, styles) => serialize(compile(`${selector}{${styles}}`), stringify); const stylis = (selector, styles) => serialize(compile(`${selector}{${styles}}`), stringify);
const rules = stylis(`#${id}`, getStyles(graphType, userStyles, cnf.themeVariables)); const rules = stylis(`#${id}`, getStyles(graphType, userStyles, cnf.themeVariables));
@ -446,102 +359,9 @@ const render = function (id, _txt, cb, container) {
style1.innerHTML = `#${id} ` + rules; style1.innerHTML = `#${id} ` + rules;
svg.insertBefore(style1, firstChild); svg.insertBefore(style1, firstChild);
// Verify that the generated svgs are ok before removing this
// const style2 = document.createElement('style');
// const cs = window.getComputedStyle(svg);
// style2.innerHTML = `#d${id} * {
// color: ${cs.color};
// // font: ${cs.font};
// // font-family: Arial;
// // font-size: 24px;
// }`;
// svg.insertBefore(style2, firstChild);
try { try {
switch (graphType) { diag.renderer.draw(txt, id, pkg.version, diag);
case 'c4':
c4Renderer.setConf(cnf.c4);
c4Renderer.draw(txt, id);
break;
case 'gitGraph':
// cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
//gitGraphRenderer.setConf(cnf.git);
gitGraphRenderer.draw(txt, id, false);
break;
case 'flowchart':
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
flowRenderer.setConf(cnf.flowchart);
flowRenderer.draw(txt, id, false);
break;
case 'flowchart-v2':
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
flowRendererV2.setConf(cnf.flowchart);
flowRendererV2.draw(txt, id, false);
break;
case 'sequence':
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
if (cnf.sequenceDiagram) {
// backwards compatibility
sequenceRenderer.setConf(Object.assign(cnf.sequence, cnf.sequenceDiagram));
console.error(
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
);
} else {
sequenceRenderer.setConf(cnf.sequence);
}
sequenceRenderer.draw(txt, id);
break;
case 'gantt':
cnf.gantt.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
ganttRenderer.setConf(cnf.gantt);
ganttRenderer.draw(txt, id);
break;
case 'class':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
classRenderer.setConf(cnf.class);
classRenderer.draw(txt, id);
break;
case 'classDiagram':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
classRendererV2.setConf(cnf.class);
classRendererV2.draw(txt, id);
break;
case 'state':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
stateRenderer.setConf(cnf.state);
stateRenderer.draw(txt, id);
break;
case 'stateDiagram':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
stateRendererV2.setConf(cnf.state);
stateRendererV2.draw(txt, id);
break;
case 'info':
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
infoRenderer.setConf(cnf.class);
infoRenderer.draw(txt, id, pkg.version);
break;
case 'pie':
//cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
//pieRenderer.setConf(cnf.pie);
pieRenderer.draw(txt, id, pkg.version);
break;
case 'er':
erRenderer.setConf(cnf.er);
erRenderer.draw(txt, id, pkg.version);
break;
case 'journey':
journeyRenderer.setConf(cnf.journey);
journeyRenderer.draw(txt, id, pkg.version);
break;
case 'requirement':
requirementRenderer.setConf(cnf.requirement);
requirementRenderer.draw(txt, id, pkg.version);
break;
}
} catch (e) { } catch (e) {
// errorRenderer.setConf(cnf.class);
errorRenderer.draw(id, pkg.version); errorRenderer.draw(id, pkg.version);
throw e; throw e;
} }
@ -572,7 +392,6 @@ const render = function (id, _txt, cb, container) {
let width = '100%'; let width = '100%';
let height = '100%'; let height = '100%';
if (svgEl) { if (svgEl) {
// width = svgEl.viewBox.baseVal.width + 'px';
height = svgEl.viewBox.baseVal.height + 'px'; height = svgEl.viewBox.baseVal.height + 'px';
} }
svgCode = `<iframe style="width:${width};height:${height};border:0;margin:0;" src="data:text/html;base64,${btoa( svgCode = `<iframe style="width:${width};height:${height};border:0;margin:0;" src="data:text/html;base64,${btoa(
@ -666,7 +485,6 @@ const handleDirective = function (p, directive, type) {
log.debug('sanitize in handleDirective', directive.args); log.debug('sanitize in handleDirective', directive.args);
directiveSanitizer(directive.args); directiveSanitizer(directive.args);
log.debug('sanitize in handleDirective (done)', directive.args); log.debug('sanitize in handleDirective (done)', directive.args);
reinitialize(directive.args);
configApi.addDirective(directive.args); configApi.addDirective(directive.args);
break; break;
} }
@ -694,7 +512,6 @@ const handleDirective = function (p, directive, type) {
function updateRendererConfigs(conf) { function updateRendererConfigs(conf) {
// Todo remove, all diagrams should get config on demand from the config object, no need for this // Todo remove, all diagrams should get config on demand from the config object, no need for this
// gitGraphRenderer.setConf(conf.git); // Todo Remove all of these
flowRenderer.setConf(conf.flowchart); flowRenderer.setConf(conf.flowchart);
flowRendererV2.setConf(conf.flowchart); flowRendererV2.setConf(conf.flowchart);
if (typeof conf['sequenceDiagram'] !== 'undefined') { if (typeof conf['sequenceDiagram'] !== 'undefined') {
@ -702,37 +519,16 @@ function updateRendererConfigs(conf) {
} }
sequenceRenderer.setConf(conf.sequence); sequenceRenderer.setConf(conf.sequence);
ganttRenderer.setConf(conf.gantt); ganttRenderer.setConf(conf.gantt);
classRenderer.setConf(conf.class); // classRenderer.setConf(conf.class);
stateRenderer.setConf(conf.state); stateRenderer.setConf(conf.state);
stateRendererV2.setConf(conf.state); stateRendererV2.setConf(conf.state);
infoRenderer.setConf(conf.class); // infoRenderer.setConf(conf.class);
// pieRenderer.setConf(conf.class);
erRenderer.setConf(conf.er);
journeyRenderer.setConf(conf.journey); journeyRenderer.setConf(conf.journey);
requirementRenderer.setConf(conf.requirement);
errorRenderer.setConf(conf.class); errorRenderer.setConf(conf.class);
} }
/** To be removed */
function reinitialize() {
// `mermaidAPI.reinitialize: v${pkg.version}`,
// JSON.stringify(options),
// options.themeVariables.primaryColor;
// // if (options.theme && theme[options.theme]) {
// // options.themeVariables = theme[options.theme].getThemeVariables(options.themeVariables);
// // }
// // Set default options
// const config =
// typeof options === 'object' ? configApi.setConfig(options) : configApi.getSiteConfig();
// updateRendererConfigs(config);
// setLogLevel(config.logLevel);
// log.debug('mermaidAPI.reinitialize: ', config);
}
/** @param {any} options */ /** @param {any} options */
function initialize(options) { function initialize(options) {
// console.warn(`mermaidAPI.initialize: v${pkg.version} `, options);
// Handle legacy location of font-family configuration // Handle legacy location of font-family configuration
if (options && options.fontFamily) { if (options && options.fontFamily) {
if (!options.themeVariables) { if (!options.themeVariables) {
@ -758,7 +554,6 @@ function initialize(options) {
updateRendererConfigs(config); updateRendererConfigs(config);
setLogLevel(config.logLevel); setLogLevel(config.logLevel);
// log.debug('mermaidAPI.initialize: ', config);
} }
const mermaidAPI = Object.freeze({ const mermaidAPI = Object.freeze({
@ -766,16 +561,12 @@ const mermaidAPI = Object.freeze({
parse, parse,
parseDirective, parseDirective,
initialize, initialize,
reinitialize,
getConfig: configApi.getConfig, getConfig: configApi.getConfig,
setConfig: configApi.setConfig, setConfig: configApi.setConfig,
getSiteConfig: configApi.getSiteConfig, getSiteConfig: configApi.getSiteConfig,
updateSiteConfig: configApi.updateSiteConfig, updateSiteConfig: configApi.updateSiteConfig,
reset: () => { reset: () => {
// console.warn('reset');
configApi.reset(); configApi.reset();
// const siteConfig = configApi.getSiteConfig();
// updateRendererConfigs(siteConfig);
}, },
globalReset: () => { globalReset: () => {
configApi.reset(configApi.defaultConfig); configApi.reset(configApi.defaultConfig);

View File

@ -64,7 +64,7 @@ describe('when using mermaidAPI and ', function () {
mermaidAPI.initialize({ securityLevel: 'loose' }); mermaidAPI.initialize({ securityLevel: 'loose' });
}, },
}; };
mermaidAPI.reinitialize(config); // mermaidAPI.reinitialize(config);
expect(mermaidAPI.getConfig().secure).toEqual(mermaidAPI.getSiteConfig().secure); expect(mermaidAPI.getConfig().secure).toEqual(mermaidAPI.getSiteConfig().secure);
expect(mermaidAPI.getConfig().securityLevel).toBe('strict'); expect(mermaidAPI.getConfig().securityLevel).toBe('strict');
mermaidAPI.reset(); mermaidAPI.reset();