Merge github.com:mermaid-js/mermaid into eslint-fix

This commit is contained in:
Yash-Singh1 2021-11-11 10:31:08 -08:00
commit 2368ba4914
42 changed files with 1285 additions and 1880 deletions

View File

@ -35,13 +35,13 @@ The documentation is written in Markdown, for more information about Markdown [s
If you want to preview the documentation site on your machine, you need to install `docsify-cli`: If you want to preview the documentation site on your machine, you need to install `docsify-cli`:
``` ```sh
$ npm i docsify-cli -g $ npm i docsify-cli -g
```` ```
If you are more familiar with Yarn, you can use the following command: If you are more familiar with Yarn, you can use the following command:
``` ```sh
$ yarn global add docsify-cli $ yarn global add docsify-cli
``` ```
@ -50,7 +50,7 @@ If the installation is successful, the command `docsify` will be available in yo
You can now run the following command to serve the documentation site: You can now run the following command to serve the documentation site:
``` ```sh
$ docsify serve docs $ docsify serve docs
``` ```
@ -85,7 +85,7 @@ The rendering tests are very straightforward to create. There is a function imgS
When running in ci it will take a snapshot of the rendered diagram and compare it with the snapshot from last build and flag for review it if it differs. When running in ci it will take a snapshot of the rendered diagram and compare it with the snapshot from last build and flag for review it if it differs.
This is what a rendering test looks like: This is what a rendering test looks like:
``` ```javascript
it('should render forks and joins', () => { it('should render forks and joins', () => {
imgSnapshotTest( imgSnapshotTest(
` `

391
dist/mermaid.core.js vendored
View File

@ -8811,14 +8811,11 @@ var updateCurrentConfig = function updateCurrentConfig(siteCfg, _directives) {
* *
* **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls * **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls
* to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) * to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig)
* will reset siteConfig and current Config to the defaultConfig * will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this
* function *Default value: At default, will mirror Global Config**
* *
* Note: currentConfig is set in this function * @param conf - The base currentConfig to use as siteConfig
* * @returns {object} - The siteConfig
* Default value: At default, will mirror Global Config
*
* @param {any} conf - The base currentConfig to use as siteConfig
* @returns {any} - The siteConfig
*/ */
var setSiteConfig = function setSiteConfig(conf) { var setSiteConfig = function setSiteConfig(conf) {
@ -8843,13 +8840,13 @@ var updateSiteConfig = function updateSiteConfig(conf) {
/** /**
* ## getSiteConfig * ## getSiteConfig
* *
* | Function | Description | Type | Values | * | Function | Description | Type | Values |
* | ------------- | ------------------------------------------------- | ----------- | --------------------------------- | * | ------------- | ------------------------------------------------- | ----------- | -------------------------------- |
* | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in site Config | * | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig |
* *
* **Notes**: Returns **any** values in siteConfig. * **Notes**: Returns **any** values in siteConfig.
* *
* @returns {any} * @returns {object} - The siteConfig
*/ */
var getSiteConfig = function getSiteConfig() { var getSiteConfig = function getSiteConfig() {
@ -8937,6 +8934,12 @@ var sanitize = function sanitize(options) {
} }
}); });
}; };
/**
* Pushes in a directive to the configuration
*
* @param {object} directive The directive to push in
*/
var addDirective = function addDirective(directive) { var addDirective = function addDirective(directive) {
if (directive.fontFamily) { if (directive.fontFamily) {
if (!directive.themeVariables) { if (!directive.themeVariables) {
@ -13568,8 +13571,12 @@ var conf = {
/** /**
* Function that adds the vertices found during parsing to the graph to be rendered. * Function that adds the vertices found during parsing to the graph to be rendered.
* *
* @param classes * @param {Object<
* @param g The graph that is to be drawn. * string,
* { cssClasses: string[]; text: string; id: string; type: string; domId: string }
* >} classes
* Object containing the vertices.
* @param {SVGGElement} g The graph that is to be drawn.
*/ */
var addClasses = function addClasses(classes, g) { var addClasses = function addClasses(classes, g) {
@ -13769,19 +13776,29 @@ var addRelations = function addRelations(relations, g) {
g.setEdge(edge.id1, edge.id2, edgeData, cnt); g.setEdge(edge.id1, edge.id2, edgeData, cnt);
}); });
}; // Todo optimize };
/**
* Gets the ID with the same label as in the cache
*
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
var getGraphId = function getGraphId(label) { var getGraphId = function getGraphId(label) {
var keys = Object.keys(idCache); var foundEntry = Object.entries(idCache).find(function (entry) {
return entry[1].label === label;
});
for (var i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/**
* Merges the value of `conf` with the passed `cnf`
*
* @param {object} cnf Config to merge
*/
var setConf = function setConf(cnf) { var setConf = function setConf(cnf) {
var keys = Object.keys(cnf); var keys = Object.keys(cnf);
@ -13792,8 +13809,8 @@ var setConf = function setConf(cnf) {
/** /**
* 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 text * @param {string} text
* @param id * @param {string} id
*/ */
var drawOld = function drawOld(text, id) { var drawOld = function drawOld(text, id) {
@ -13982,11 +13999,12 @@ var draw = function draw(text, id) {
// }); // });
}; };
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ /**
setConf: setConf, * Gets the arrow marker for a type index
draw: draw *
}); * @param {number} type The type to look for
/** @param type */ * @returns {'aggregation' | 'extension' | 'composition' | 'dependency'} The arrow marker
*/
function getArrowMarker(type) { function getArrowMarker(type) {
var marker; var marker;
@ -14015,6 +14033,11 @@ function getArrowMarker(type) {
return marker; return marker;
} }
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
setConf: setConf,
draw: draw
});
/***/ }), /***/ }),
/***/ "./src/diagrams/class/classRenderer.js": /***/ "./src/diagrams/class/classRenderer.js":
@ -14057,23 +14080,27 @@ var conf = {
dividerMargin: 10, dividerMargin: 10,
padding: 5, padding: 5,
textHeight: 10 textHeight: 10
}; // Todo optimize };
/**
* Gets the ID with the same label as in the cache
*
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
var getGraphId = function getGraphId(label) { var getGraphId = function getGraphId(label) {
var keys = Object.keys(idCache); var foundEntry = Object.entries(idCache).find(function (entry) {
return entry[1].label === label;
});
for (var i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/** /**
* Setup arrow head and define the marker. The result is appended to the svg. * Setup arrow head and define the marker. The result is appended to the svg.
* *
* @param elem * @param {SVGSVGElement} elem The SVG element to append to
*/ */
@ -14088,6 +14115,12 @@ var insertMarkers = function insertMarkers(elem) {
elem.append('defs').append('marker').attr('id', 'dependencyStart').attr('class', 'extension').attr('refX', 0).attr('refY', 7).attr('markerWidth', 190).attr('markerHeight', 240).attr('orient', 'auto').append('path').attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z'); elem.append('defs').append('marker').attr('id', 'dependencyStart').attr('class', 'extension').attr('refX', 0).attr('refY', 7).attr('markerWidth', 190).attr('markerHeight', 240).attr('orient', 'auto').append('path').attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z');
elem.append('defs').append('marker').attr('id', 'dependencyEnd').attr('refX', 19).attr('refY', 7).attr('markerWidth', 20).attr('markerHeight', 28).attr('orient', 'auto').append('path').attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z'); elem.append('defs').append('marker').attr('id', 'dependencyEnd').attr('refX', 19).attr('refY', 7).attr('markerWidth', 20).attr('markerHeight', 28).attr('orient', 'auto').append('path').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
*/
var setConf = function setConf(cnf) { var setConf = function setConf(cnf) {
var keys = Object.keys(cnf); var keys = Object.keys(cnf);
@ -14098,8 +14131,8 @@ var setConf = function setConf(cnf) {
/** /**
* 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 text * @param {string} text
* @param id * @param {string} id
*/ */
var draw = function draw(text, id) { var draw = function draw(text, id) {
@ -14309,6 +14342,12 @@ var drawEdge = function drawEdge(elem, path, relation, conf) {
edgeCount++; edgeCount++;
}; };
/**
* Renders a class diagram
* @param {SVGSVGElement} elem The element to draw it into
* @todo Add more information in the JSDOC here
*/
var drawClass = function drawClass(elem, classDef, conf) { var drawClass = function drawClass(elem, classDef, conf) {
_logger__WEBPACK_IMPORTED_MODULE_3__.log.info('Rendering class ' + classDef); _logger__WEBPACK_IMPORTED_MODULE_3__.log.info('Rendering class ' + classDef);
var id = classDef.id; var id = classDef.id;
@ -14495,6 +14534,14 @@ var buildLegacyDisplay = function buildLegacyDisplay(text) {
cssStyle: cssStyle cssStyle: cssStyle
}; };
}; };
/**
* Adds a <tspan> for a member in a diagram
* @param {SVGElement} textEl The element to append to
* @param {string} txt The member
* @param {boolean} isFirst
* @param {{ padding: string; textHeight: string; }} conf The configuration for the member
*/
var addTspan = function addTspan(textEl, txt, isFirst, conf) { var addTspan = function addTspan(textEl, txt, isFirst, conf) {
var member = parseMember(txt); var member = parseMember(txt);
@ -14508,6 +14555,15 @@ var addTspan = function addTspan(textEl, txt, isFirst, conf) {
tSpan.attr('dy', conf.textHeight); tSpan.attr('dy', conf.textHeight);
} }
}; };
/**
* Makes generics in typescript syntax
* @example <caption>Array of array of strings in typescript syntax</caption>
* // returns "Array<Array<string>>"
* parseGenericTypes("Array~Array~string~~");
* @param {string} text The text to convert
* @returns {string} The converted string
*/
var parseGenericTypes = function parseGenericTypes(text) { var parseGenericTypes = function parseGenericTypes(text) {
var cleanedText = text; var cleanedText = text;
@ -14520,6 +14576,12 @@ var parseGenericTypes = function parseGenericTypes(text) {
return cleanedText; return cleanedText;
} }
}; };
/**
* Gives the styles for a classifier
* @param {"+" | "-" | "#" | "~" | "*" | "$"} classifier The classifier string
* @returns {string} Styling for the classifier
*/
var parseClassifier = function parseClassifier(classifier) { var parseClassifier = function parseClassifier(classifier) {
switch (classifier) { switch (classifier) {
@ -14563,12 +14625,24 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! dompurify */ "dompurify"); /* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! dompurify */ "dompurify");
/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(dompurify__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(dompurify__WEBPACK_IMPORTED_MODULE_0__);
/**
* Gets the number of lines in a string
* @param {string | undefined} s The string to check the lines for
* @returns {number} The number of lines in that string
*/
var getRows = function getRows(s) { var getRows = function getRows(s) {
if (!s) return 1; if (!s) return 1;
var str = breakToPlaceholder(s); var str = breakToPlaceholder(s);
str = str.replace(/\\n/g, '#br#'); str = str.replace(/\\n/g, '#br#');
return str.split('#br#'); return str.split('#br#');
}; };
/**
* Removes script tags from a text
* @param {string} txt The text to sanitize
* @returns {string} The safer text
*/
var removeScript = function removeScript(txt) { var removeScript = function removeScript(txt) {
var rs = ''; var rs = '';
var idx = 0; var idx = 0;
@ -14631,20 +14705,49 @@ var sanitizeText = function sanitizeText(text, config) {
return txt; return txt;
}; };
var lineBreakRegex = /<br\s*\/?>/gi; var lineBreakRegex = /<br\s*\/?>/gi;
/**
* Whether or not a text has any linebreaks
* @param {string} text The text to test
* @returns {boolean} Whether or not the text has breaks
*/
var hasBreaks = function hasBreaks(text) { var hasBreaks = function hasBreaks(text) {
return /<br\s*[/]?>/gi.test(text); return lineBreakRegex.test(text);
}; };
/**
* Splits on <br> tags
* @param {string} text Text to split
* @returns {Array<string>} List of lines as strings
*/
var splitBreaks = function splitBreaks(text) { var splitBreaks = function splitBreaks(text) {
return text.split(/<br\s*[/]?>/gi); return text.split(lineBreakRegex);
}; };
/**
* Converts placeholders to linebreaks in HTML
* @param {string} s HTML with placeholders
* @returns {string} HTML with breaks instead of placeholders
*/
var placeholderToBreak = function placeholderToBreak(s) { var placeholderToBreak = function placeholderToBreak(s) {
return s.replace(/#br#/g, '<br/>'); return s.replace(/#br#/g, '<br/>');
}; };
/**
* Opposite of `placeholderToBreak`, converts breaks to placeholders
* @param {string} s HTML string
* @returns {string} String with placeholders
*/
var breakToPlaceholder = function breakToPlaceholder(s) { var breakToPlaceholder = function breakToPlaceholder(s) {
return s.replace(lineBreakRegex, '#br#'); return s.replace(lineBreakRegex, '#br#');
}; };
/**
* Gets the current URL
* @param {boolean} useAbsolute Whether to return the absolute URL or not
* @returns {string} The current URL
*/
var getUrl = function getUrl(useAbsolute) { var getUrl = function getUrl(useAbsolute) {
var url = ''; var url = '';
@ -14657,6 +14760,12 @@ var getUrl = function getUrl(useAbsolute) {
return url; return url;
}; };
/**
* Converts a string/boolean into a boolean
* @param {string | boolean} val String or boolean to convert
* @returns {boolean} The result from the input
*/
var evaluate = function evaluate(val) { var evaluate = function evaluate(val) {
return val === 'false' || val === false ? false : true; return val === 'false' || val === false ? false : true;
@ -17758,8 +17867,13 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ }); /* harmony export */ });
/**
* Returns the styles given options
* @param {{ fontFamily: string; nodeTextColor: string; textColor: string; titleColor: string; mainBkg: string; nodeBorder: string; arrowheadColor: string; lineColor: string; edgeLabelBackground: string; clusterBkg: string; clusterBorder: string; tertiaryColor: string; border2: string; }} options The options for the styles
* @returns {string} The resulting styles
*/
var getStyles = function getStyles(options) { var getStyles = function getStyles(options) {
return ".label {\n font-family: ".concat(options.fontFamily, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n .cluster-label text {\n fill: ").concat(options.titleColor, ";\n }\n .cluster-label span {\n color: ").concat(options.titleColor, ";\n }\n\n .label text,span {\n fill: ").concat(options.nodeTextColor || options.textColor, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ").concat(options.mainBkg, ";\n stroke: ").concat(options.nodeBorder, ";\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ").concat(options.arrowheadColor, ";\n }\n\n .edgePath .path {\n stroke: ").concat(options.lineColor, ";\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ").concat(options.lineColor, ";\n fill: none;\n }\n\n .edgeLabel {\n background-color: ").concat(options.edgeLabelBackground, ";\n rect {\n opacity: 0.5;\n background-color: ").concat(options.edgeLabelBackground, ";\n fill: ").concat(options.edgeLabelBackground, ";\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ").concat(options.clusterBkg, ";\n stroke: ").concat(options.clusterBorder, ";\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ").concat(options.titleColor, ";\n }\n\n .cluster span {\n color: ").concat(options.titleColor, ";\n }\n // .cluster div {\n // color: ").concat(options.titleColor, ";\n // }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ").concat(options.fontFamily, ";\n font-size: 12px;\n background: ").concat(options.tertiaryColor, ";\n border: 1px solid ").concat(options.border2, ";\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n"); return ".label {\n font-family: ".concat(options.fontFamily, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n .cluster-label text {\n fill: ").concat(options.titleColor, ";\n }\n .cluster-label span {\n color: ").concat(options.titleColor, ";\n }\n\n .label text,span {\n fill: ").concat(options.nodeTextColor || options.textColor, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ").concat(options.mainBkg, ";\n stroke: ").concat(options.nodeBorder, ";\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ").concat(options.arrowheadColor, ";\n }\n\n .edgePath .path {\n stroke: ").concat(options.lineColor, ";\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ").concat(options.lineColor, ";\n fill: none;\n }\n\n .edgeLabel {\n background-color: ").concat(options.edgeLabelBackground, ";\n rect {\n opacity: 0.5;\n background-color: ").concat(options.edgeLabelBackground, ";\n fill: ").concat(options.edgeLabelBackground, ";\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ").concat(options.clusterBkg, ";\n stroke: ").concat(options.clusterBorder, ";\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ").concat(options.titleColor, ";\n }\n\n .cluster span {\n color: ").concat(options.titleColor, ";\n }\n /* .cluster div {\n color: ").concat(options.titleColor, ";\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ").concat(options.fontFamily, ";\n font-size: 12px;\n background: ").concat(options.tertiaryColor, ";\n border: 1px solid ").concat(options.border2, ";\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n");
}; };
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getStyles); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getStyles);
@ -19090,9 +19204,6 @@ var branches = {
var curBranch = 'master'; var curBranch = 'master';
var direction = 'LR'; var direction = 'LR';
var seq = 0; var seq = 0;
/**
*
*/
function getId() { function getId() {
return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.random)({ return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.random)({
@ -25334,6 +25445,12 @@ __webpack_require__.r(__webpack_exports__);
var conf = {}; var conf = {};
/**
* Merges the value of `conf` with the passed `cnf`
*
* @param {object} cnf Config to merge
*/
var setConf = function setConf(cnf) { var setConf = function setConf(cnf) {
var keys = Object.keys(cnf); var keys = Object.keys(cnf);
keys.forEach(function (key) { keys.forEach(function (key) {
@ -25343,8 +25460,8 @@ var setConf = function setConf(cnf) {
/** /**
* 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} id * @param {string} id The text for the error
* @param {any} ver * @param {string} ver The version
*/ */
var draw = function draw(id, ver) { var draw = function draw(id, ver) {
@ -25418,6 +25535,14 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-mini */ "moment-mini"); /* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-mini */ "moment-mini");
/* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_mini__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_mini__WEBPACK_IMPORTED_MODULE_0__);
/**
* @typedef {"debug" | "info" | "warn" | "error" | "fatal"} LogLevel A log level
*/
/**
* @type {Object<LogLevel, number>}
*/
var LEVELS = { var LEVELS = {
debug: 1, debug: 1,
info: 2, info: 2,
@ -25432,6 +25557,11 @@ var log = {
error: function error() {}, error: function error() {},
fatal: function fatal() {} fatal: function fatal() {}
}; };
/**
* Sets a log level
* @param {LogLevel} [level="fatal"] The level to set the logging to
*/
var setLogLevel = function setLogLevel() { var setLogLevel = function setLogLevel() {
var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'fatal'; var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'fatal';
@ -25476,6 +25606,11 @@ var setLogLevel = function setLogLevel() {
log.debug = console.debug ? console.debug.bind(console, format('DEBUG'), 'color: lightgreen') : console.log.bind(console, '\x1b[32m', format('DEBUG')); log.debug = console.debug ? console.debug.bind(console, format('DEBUG'), 'color: lightgreen') : console.log.bind(console, '\x1b[32m', format('DEBUG'));
} }
}; };
/**
* Returns a format with the timestamp and the log level
* @param {LogLevel} level The level for the log format
* @returns {string} The format with the timestamp and log level
*/
var format = function format(level) { var format = function format(level) {
var time = moment_mini__WEBPACK_IMPORTED_MODULE_0___default()().format('ss.SSS'); var time = moment_mini__WEBPACK_IMPORTED_MODULE_0___default()().format('ss.SSS');
@ -25984,7 +26119,7 @@ var decodeEntities = function decodeEntities(text) {
/** /**
* Function that renders an svg with a graph from a chart definition. Usage example below. * Function that renders an svg with a graph from a chart definition. Usage example below.
* *
* ```js * ```javascript
* mermaidAPI.initialize({ * mermaidAPI.initialize({
* startOnLoad: true, * startOnLoad: true,
* }); * });
@ -28216,7 +28351,11 @@ var detectDirective = function detectDirective(text) {
* g-->h * g-->h
* ``` * ```
* @param {string} text The text defining the graph * @param {string} text The text defining the graph
* @param {any} cnf * @param {{
* class: { defaultRenderer: string } | undefined;
* state: { defaultRenderer: string } | undefined;
* flowchart: { defaultRenderer: string } | undefined;
* }} [cnf]
* @returns {string} A graph definition key * @returns {string} A graph definition key
*/ */
@ -28280,6 +28419,13 @@ var detectType = function detectType(text, cnf) {
if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper') return 'flowchart-v2'; if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper') return 'flowchart-v2';
return 'flowchart'; return 'flowchart';
}; };
/**
* Caches results of functions based on input
*
* @param {Function} fn Function to run
* @param {Function} resolver Function that resolves to an ID given arguments the `fn` takes
* @returns {Function} An optimized caching function
*/
var memoize = function memoize(fn, resolver) { var memoize = function memoize(fn, resolver) {
var cache = {}; var cache = {};
@ -28314,6 +28460,14 @@ var isSubstringInArray = function isSubstringInArray(str, arr) {
return -1; return -1;
}; };
/**
* Returns a d3 curve given a curve name
*
* @param {string | undefined} interpolate The interpolation name
* @param {any} defaultCurve The default curve to return
* @returns {import('d3-shape').CurveFactory} The curve factory to use
*/
var interpolateToCurve = function interpolateToCurve(interpolate, defaultCurve) { var interpolateToCurve = function interpolateToCurve(interpolate, defaultCurve) {
if (!interpolate) { if (!interpolate) {
return defaultCurve; return defaultCurve;
@ -28322,6 +28476,14 @@ var interpolateToCurve = function interpolateToCurve(interpolate, defaultCurve)
var curveName = "curve".concat(interpolate.charAt(0).toUpperCase() + interpolate.slice(1)); var curveName = "curve".concat(interpolate.charAt(0).toUpperCase() + interpolate.slice(1));
return d3CurveTypes[curveName] || defaultCurve; return d3CurveTypes[curveName] || defaultCurve;
}; };
/**
* Formats a URL string
*
* @param {string} linkStr String of the URL
* @param {{ securityLevel: string }} config Configuration passed to MermaidJS
* @returns {string | undefined} The formatted URL
*/
var formatUrl = function formatUrl(linkStr, config) { var formatUrl = function formatUrl(linkStr, config) {
var url = linkStr.trim(); var url = linkStr.trim();
@ -28333,6 +28495,13 @@ var formatUrl = function formatUrl(linkStr, config) {
return url; return url;
} }
}; };
/**
* Runs a function
*
* @param {string} functionName A dot seperated path to the function relative to the `window`
* @param {...any} params Parameters to pass to the function
*/
var runFunc = function runFunc(functionName) { var runFunc = function runFunc(functionName) {
var _obj; var _obj;
@ -28352,10 +28521,29 @@ var runFunc = function runFunc(functionName) {
(_obj = obj)[fnName].apply(_obj, params); (_obj = obj)[fnName].apply(_obj, params);
}; };
/**
* @typedef {object} Point A (x, y) point
* @property {number} x The x value
* @property {number} y The y value
*/
/**
* Finds the distance between two points using the Distance Formula
*
* @param {Point} p1 The first point
* @param {Point} p2 The second point
* @returns {number} The distance
*/
var distance = function distance(p1, p2) { var distance = function distance(p1, p2) {
return p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0; return p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0;
}; };
/**
* @param {Point[]} points List of points
* @returns {Point}
* @todo Give this a description
*/
var traverseEdge = function traverseEdge(points) { var traverseEdge = function traverseEdge(points) {
var prevPoint; var prevPoint;
@ -28397,6 +28585,13 @@ var traverseEdge = function traverseEdge(points) {
}); });
return center; return center;
}; };
/**
* Alias for `traverseEdge`
*
* @param {Point[]} points List of points
* @returns {Point} Return result of `transverseEdge`
*/
var calcLabelPosition = function calcLabelPosition(points) { var calcLabelPosition = function calcLabelPosition(points) {
return traverseEdge(points); return traverseEdge(points);
@ -28548,6 +28743,13 @@ var calcTerminalLabelPosition = function calcTerminalLabelPosition(terminalMarke
return cardinalityPosition; return cardinalityPosition;
}; };
/**
* Gets styles from an array of declarations
*
* @param {string[]} arr Declarations
* @returns {{ style: string; labelStyle: string }} The styles grouped as strings
*/
var getStylesFromArray = function getStylesFromArray(arr) { var getStylesFromArray = function getStylesFromArray(arr) {
var style = ''; var style = '';
@ -28602,19 +28804,31 @@ var random = function random(options) {
* effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the * effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the
* config.clobber parameter === true. Example: * config.clobber parameter === true. Example:
* *
* let config_0 = { foo: { bar: 'bar' }, bar: 'foo' }; * ```js
* let config_1 = { foo: 'foo', bar: 'bar' }; * let config_0 = { foo: { bar: 'bar' }, bar: 'foo' };
* let result = assignWithDepth(config_0, config_1); * let config_1 = { foo: 'foo', bar: 'bar' };
* console.log(result); * let result = assignWithDepth(config_0, config_1);
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }<p> * console.log(result);
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }
* ```
* *
* Traditional Object.assign would have clobbered foo in config_0 with foo in config_1.<p> If src is * Traditional Object.assign would have clobbered foo in config_0 with foo in config_1. If src is a
* a destructured array of objects and dst is not an array, assignWithDepth will apply each * destructured array of objects and dst is not an array, assignWithDepth will apply each element
* element of src to dst in order. * of src to dst in order.
* @param dst
* @param src
* @param config
* @param dst
* @param src
* @param config
* @param dst
* @param src
* @param config
* @param {any} dst - The destination of the merge * @param {any} dst - The destination of the merge
* @param {any} src - The source object(s) to merge into destination * @param {any} src - The source object(s) to merge into destination
* @param {{ depth: number; clobber: boolean }} config - Depth: depth to traverse within src and dst * @param {{ depth: number; clobber: boolean }} [config={ depth: 2, clobber: false }] - Depth: depth
* for merging - clobber: should dissimilar types clobber (default: { depth: 2, clobber: false }) * to traverse within src and dst for merging - clobber: should dissimilar types clobber (default:
* { depth: 2, clobber: false }). Default is `{ depth: 2, clobber: false }`
* @returns {any} * @returns {any}
*/ */
@ -28682,6 +28896,25 @@ var getTextObj = function getTextObj() {
valign: undefined valign: undefined
}; };
}; };
/**
* Adds text to an element
*
* @param {SVGElement} elem Element to add text to
* @param {{
* text: string;
* x: number;
* y: number;
* anchor: 'start' | 'middle' | 'end';
* fontFamily: string;
* fontSize: string | number;
* fontWeight: string | number;
* fill: string;
* class: string | undefined;
* textMargin: number;
* }} textData
* @returns {SVGTextElement} Text element with given styling and content
*/
var drawSimpleText = function drawSimpleText(elem, textData) { var drawSimpleText = function drawSimpleText(elem, textData) {
// Remove and ignore br:s // Remove and ignore br:s
var nText = textData.text.replace(_diagrams_common_common__WEBPACK_IMPORTED_MODULE_3__["default"].lineBreakRegex, ' '); var nText = textData.text.replace(_diagrams_common_common__WEBPACK_IMPORTED_MODULE_3__["default"].lineBreakRegex, ' ');
@ -28910,6 +29143,12 @@ var calculateTextDimensions = memoize(function (text, config) {
}, function (text, config) { }, function (text, config) {
return "".concat(text, "-").concat(config.fontSize, "-").concat(config.fontWeight, "-").concat(config.fontFamily); return "".concat(text, "-").concat(config.fontSize, "-").concat(config.fontWeight, "-").concat(config.fontFamily);
}); });
/**
* Applys d3 attributes
*
* @param {any} d3Elem D3 Element to apply the attributes onto
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of attributes
*/
var d3Attrs = function d3Attrs(d3Elem, attrs) { var d3Attrs = function d3Attrs(d3Elem, attrs) {
var _iterator2 = _createForOfIteratorHelper(attrs), var _iterator2 = _createForOfIteratorHelper(attrs),
@ -28926,6 +29165,15 @@ var d3Attrs = function d3Attrs(d3Elem, attrs) {
_iterator2.f(); _iterator2.f();
} }
}; };
/**
* Gives attributes for an SVG's size given arguments
*
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
* @returns {Map<'height' | 'width' | 'style', string>} Attributes for the SVG
*/
var calculateSvgSizeAttrs = function calculateSvgSizeAttrs(height, width, useMaxWidth) { var calculateSvgSizeAttrs = function calculateSvgSizeAttrs(height, width, useMaxWidth) {
var attrs = new Map(); var attrs = new Map();
@ -28940,6 +29188,15 @@ var calculateSvgSizeAttrs = function calculateSvgSizeAttrs(height, width, useMax
return attrs; return attrs;
}; };
/**
* Applies attributes from `calculateSvgSizeAttrs`
*
* @param {SVGSVGElement} svgElem The SVG Element to configure
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
*/
var configureSvgSize = function configureSvgSize(svgElem, height, width, useMaxWidth) { var configureSvgSize = function configureSvgSize(svgElem, height, width, useMaxWidth) {
var attrs = calculateSvgSizeAttrs(height, width, useMaxWidth); var attrs = calculateSvgSizeAttrs(height, width, useMaxWidth);
d3Attrs(svgElem, attrs); d3Attrs(svgElem, attrs);
@ -28962,9 +29219,15 @@ var initIdGeneratior = /*#__PURE__*/function () {
}]); }]);
return iterator; return iterator;
}(); // Source https://github.com/shrpne/entity-decode/blob/master/browser.js }();
var decoder; var decoder;
/**
* Decodes HTML, source: {@link https://github.com/shrpne/entity-decode/blob/v2.0.1/browser.js}
*
* @param {string} html HTML as a string
* @returns Unescaped HTML
*/
var entityDecode = function entityDecode(html) { var entityDecode = function entityDecode(html) {
decoder = decoder || document.createElement('div'); // Escape HTML before decoding for HTML Entities decoder = decoder || document.createElement('div'); // Escape HTML before decoding for HTML Entities
@ -28973,6 +29236,12 @@ var entityDecode = function entityDecode(html) {
decoder.innerHTML = html; decoder.innerHTML = html;
return unescape(decoder.textContent); return unescape(decoder.textContent);
}; };
/**
* Sanitizes directive objects
*
* @param {object} args Directive's JSON
*/
var directiveSanitizer = function directiveSanitizer(args) { var directiveSanitizer = function directiveSanitizer(args) {
_logger__WEBPACK_IMPORTED_MODULE_2__.log.debug('directiveSanitizer called with', args); _logger__WEBPACK_IMPORTED_MODULE_2__.log.debug('directiveSanitizer called with', args);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

391
dist/mermaid.js vendored
View File

@ -8863,14 +8863,11 @@ var updateCurrentConfig = function updateCurrentConfig(siteCfg, _directives) {
* *
* **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls * **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls
* to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) * to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig)
* will reset siteConfig and current Config to the defaultConfig * will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this
* function *Default value: At default, will mirror Global Config**
* *
* Note: currentConfig is set in this function * @param conf - The base currentConfig to use as siteConfig
* * @returns {object} - The siteConfig
* Default value: At default, will mirror Global Config
*
* @param {any} conf - The base currentConfig to use as siteConfig
* @returns {any} - The siteConfig
*/ */
var setSiteConfig = function setSiteConfig(conf) { var setSiteConfig = function setSiteConfig(conf) {
@ -8895,13 +8892,13 @@ var updateSiteConfig = function updateSiteConfig(conf) {
/** /**
* ## getSiteConfig * ## getSiteConfig
* *
* | Function | Description | Type | Values | * | Function | Description | Type | Values |
* | ------------- | ------------------------------------------------- | ----------- | --------------------------------- | * | ------------- | ------------------------------------------------- | ----------- | -------------------------------- |
* | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in site Config | * | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig |
* *
* **Notes**: Returns **any** values in siteConfig. * **Notes**: Returns **any** values in siteConfig.
* *
* @returns {any} * @returns {object} - The siteConfig
*/ */
var getSiteConfig = function getSiteConfig() { var getSiteConfig = function getSiteConfig() {
@ -8989,6 +8986,12 @@ var sanitize = function sanitize(options) {
} }
}); });
}; };
/**
* Pushes in a directive to the configuration
*
* @param {object} directive The directive to push in
*/
var addDirective = function addDirective(directive) { var addDirective = function addDirective(directive) {
if (directive.fontFamily) { if (directive.fontFamily) {
if (!directive.themeVariables) { if (!directive.themeVariables) {
@ -13613,8 +13616,12 @@ var conf = {
/** /**
* Function that adds the vertices found during parsing to the graph to be rendered. * Function that adds the vertices found during parsing to the graph to be rendered.
* *
* @param classes * @param {Object<
* @param g The graph that is to be drawn. * string,
* { cssClasses: string[]; text: string; id: string; type: string; domId: string }
* >} classes
* Object containing the vertices.
* @param {SVGGElement} g The graph that is to be drawn.
*/ */
var addClasses = function addClasses(classes, g) { var addClasses = function addClasses(classes, g) {
@ -13814,19 +13821,29 @@ var addRelations = function addRelations(relations, g) {
g.setEdge(edge.id1, edge.id2, edgeData, cnt); g.setEdge(edge.id1, edge.id2, edgeData, cnt);
}); });
}; // Todo optimize };
/**
* Gets the ID with the same label as in the cache
*
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
var getGraphId = function getGraphId(label) { var getGraphId = function getGraphId(label) {
var keys = Object.keys(idCache); var foundEntry = Object.entries(idCache).find(function (entry) {
return entry[1].label === label;
});
for (var i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/**
* Merges the value of `conf` with the passed `cnf`
*
* @param {object} cnf Config to merge
*/
var setConf = function setConf(cnf) { var setConf = function setConf(cnf) {
var keys = Object.keys(cnf); var keys = Object.keys(cnf);
@ -13837,8 +13854,8 @@ var setConf = function setConf(cnf) {
/** /**
* 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 text * @param {string} text
* @param id * @param {string} id
*/ */
var drawOld = function drawOld(text, id) { var drawOld = function drawOld(text, id) {
@ -14027,11 +14044,12 @@ var draw = function draw(text, id) {
// }); // });
}; };
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ /**
setConf: setConf, * Gets the arrow marker for a type index
draw: draw *
}); * @param {number} type The type to look for
/** @param type */ * @returns {'aggregation' | 'extension' | 'composition' | 'dependency'} The arrow marker
*/
function getArrowMarker(type) { function getArrowMarker(type) {
var marker; var marker;
@ -14060,6 +14078,11 @@ function getArrowMarker(type) {
return marker; return marker;
} }
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
setConf: setConf,
draw: draw
});
/***/ }), /***/ }),
/***/ "./src/diagrams/class/classRenderer.js": /***/ "./src/diagrams/class/classRenderer.js":
@ -14101,23 +14124,27 @@ var conf = {
dividerMargin: 10, dividerMargin: 10,
padding: 5, padding: 5,
textHeight: 10 textHeight: 10
}; // Todo optimize };
/**
* Gets the ID with the same label as in the cache
*
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
var getGraphId = function getGraphId(label) { var getGraphId = function getGraphId(label) {
var keys = Object.keys(idCache); var foundEntry = Object.entries(idCache).find(function (entry) {
return entry[1].label === label;
});
for (var i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/** /**
* Setup arrow head and define the marker. The result is appended to the svg. * Setup arrow head and define the marker. The result is appended to the svg.
* *
* @param elem * @param {SVGSVGElement} elem The SVG element to append to
*/ */
@ -14132,6 +14159,12 @@ var insertMarkers = function insertMarkers(elem) {
elem.append('defs').append('marker').attr('id', 'dependencyStart').attr('class', 'extension').attr('refX', 0).attr('refY', 7).attr('markerWidth', 190).attr('markerHeight', 240).attr('orient', 'auto').append('path').attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z'); elem.append('defs').append('marker').attr('id', 'dependencyStart').attr('class', 'extension').attr('refX', 0).attr('refY', 7).attr('markerWidth', 190).attr('markerHeight', 240).attr('orient', 'auto').append('path').attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z');
elem.append('defs').append('marker').attr('id', 'dependencyEnd').attr('refX', 19).attr('refY', 7).attr('markerWidth', 20).attr('markerHeight', 28).attr('orient', 'auto').append('path').attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z'); elem.append('defs').append('marker').attr('id', 'dependencyEnd').attr('refX', 19).attr('refY', 7).attr('markerWidth', 20).attr('markerHeight', 28).attr('orient', 'auto').append('path').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
*/
var setConf = function setConf(cnf) { var setConf = function setConf(cnf) {
var keys = Object.keys(cnf); var keys = Object.keys(cnf);
@ -14142,8 +14175,8 @@ var setConf = function setConf(cnf) {
/** /**
* 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 text * @param {string} text
* @param id * @param {string} id
*/ */
var draw = function draw(text, id) { var draw = function draw(text, id) {
@ -14352,6 +14385,12 @@ var drawEdge = function drawEdge(elem, path, relation, conf) {
edgeCount++; edgeCount++;
}; };
/**
* Renders a class diagram
* @param {SVGSVGElement} elem The element to draw it into
* @todo Add more information in the JSDOC here
*/
var drawClass = function drawClass(elem, classDef, conf) { var drawClass = function drawClass(elem, classDef, conf) {
_logger__WEBPACK_IMPORTED_MODULE_3__.log.info('Rendering class ' + classDef); _logger__WEBPACK_IMPORTED_MODULE_3__.log.info('Rendering class ' + classDef);
var id = classDef.id; var id = classDef.id;
@ -14538,6 +14577,14 @@ var buildLegacyDisplay = function buildLegacyDisplay(text) {
cssStyle: cssStyle cssStyle: cssStyle
}; };
}; };
/**
* Adds a <tspan> for a member in a diagram
* @param {SVGElement} textEl The element to append to
* @param {string} txt The member
* @param {boolean} isFirst
* @param {{ padding: string; textHeight: string; }} conf The configuration for the member
*/
var addTspan = function addTspan(textEl, txt, isFirst, conf) { var addTspan = function addTspan(textEl, txt, isFirst, conf) {
var member = parseMember(txt); var member = parseMember(txt);
@ -14551,6 +14598,15 @@ var addTspan = function addTspan(textEl, txt, isFirst, conf) {
tSpan.attr('dy', conf.textHeight); tSpan.attr('dy', conf.textHeight);
} }
}; };
/**
* Makes generics in typescript syntax
* @example <caption>Array of array of strings in typescript syntax</caption>
* // returns "Array<Array<string>>"
* parseGenericTypes("Array~Array~string~~");
* @param {string} text The text to convert
* @returns {string} The converted string
*/
var parseGenericTypes = function parseGenericTypes(text) { var parseGenericTypes = function parseGenericTypes(text) {
var cleanedText = text; var cleanedText = text;
@ -14563,6 +14619,12 @@ var parseGenericTypes = function parseGenericTypes(text) {
return cleanedText; return cleanedText;
} }
}; };
/**
* Gives the styles for a classifier
* @param {"+" | "-" | "#" | "~" | "*" | "$"} classifier The classifier string
* @returns {string} Styling for the classifier
*/
var parseClassifier = function parseClassifier(classifier) { var parseClassifier = function parseClassifier(classifier) {
switch (classifier) { switch (classifier) {
@ -14606,12 +14668,24 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! dompurify */ "./node_modules/dompurify/dist/purify.js"); /* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! dompurify */ "./node_modules/dompurify/dist/purify.js");
/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(dompurify__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(dompurify__WEBPACK_IMPORTED_MODULE_0__);
/**
* Gets the number of lines in a string
* @param {string | undefined} s The string to check the lines for
* @returns {number} The number of lines in that string
*/
var getRows = function getRows(s) { var getRows = function getRows(s) {
if (!s) return 1; if (!s) return 1;
var str = breakToPlaceholder(s); var str = breakToPlaceholder(s);
str = str.replace(/\\n/g, '#br#'); str = str.replace(/\\n/g, '#br#');
return str.split('#br#'); return str.split('#br#');
}; };
/**
* Removes script tags from a text
* @param {string} txt The text to sanitize
* @returns {string} The safer text
*/
var removeScript = function removeScript(txt) { var removeScript = function removeScript(txt) {
var rs = ''; var rs = '';
var idx = 0; var idx = 0;
@ -14674,20 +14748,49 @@ var sanitizeText = function sanitizeText(text, config) {
return txt; return txt;
}; };
var lineBreakRegex = /<br\s*\/?>/gi; var lineBreakRegex = /<br\s*\/?>/gi;
/**
* Whether or not a text has any linebreaks
* @param {string} text The text to test
* @returns {boolean} Whether or not the text has breaks
*/
var hasBreaks = function hasBreaks(text) { var hasBreaks = function hasBreaks(text) {
return /<br\s*[/]?>/gi.test(text); return lineBreakRegex.test(text);
}; };
/**
* Splits on <br> tags
* @param {string} text Text to split
* @returns {Array<string>} List of lines as strings
*/
var splitBreaks = function splitBreaks(text) { var splitBreaks = function splitBreaks(text) {
return text.split(/<br\s*[/]?>/gi); return text.split(lineBreakRegex);
}; };
/**
* Converts placeholders to linebreaks in HTML
* @param {string} s HTML with placeholders
* @returns {string} HTML with breaks instead of placeholders
*/
var placeholderToBreak = function placeholderToBreak(s) { var placeholderToBreak = function placeholderToBreak(s) {
return s.replace(/#br#/g, '<br/>'); return s.replace(/#br#/g, '<br/>');
}; };
/**
* Opposite of `placeholderToBreak`, converts breaks to placeholders
* @param {string} s HTML string
* @returns {string} String with placeholders
*/
var breakToPlaceholder = function breakToPlaceholder(s) { var breakToPlaceholder = function breakToPlaceholder(s) {
return s.replace(lineBreakRegex, '#br#'); return s.replace(lineBreakRegex, '#br#');
}; };
/**
* Gets the current URL
* @param {boolean} useAbsolute Whether to return the absolute URL or not
* @returns {string} The current URL
*/
var getUrl = function getUrl(useAbsolute) { var getUrl = function getUrl(useAbsolute) {
var url = ''; var url = '';
@ -14700,6 +14803,12 @@ var getUrl = function getUrl(useAbsolute) {
return url; return url;
}; };
/**
* Converts a string/boolean into a boolean
* @param {string | boolean} val String or boolean to convert
* @returns {boolean} The result from the input
*/
var evaluate = function evaluate(val) { var evaluate = function evaluate(val) {
return val === 'false' || val === false ? false : true; return val === 'false' || val === false ? false : true;
@ -17797,8 +17906,13 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ }); /* harmony export */ });
/**
* Returns the styles given options
* @param {{ fontFamily: string; nodeTextColor: string; textColor: string; titleColor: string; mainBkg: string; nodeBorder: string; arrowheadColor: string; lineColor: string; edgeLabelBackground: string; clusterBkg: string; clusterBorder: string; tertiaryColor: string; border2: string; }} options The options for the styles
* @returns {string} The resulting styles
*/
var getStyles = function getStyles(options) { var getStyles = function getStyles(options) {
return ".label {\n font-family: ".concat(options.fontFamily, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n .cluster-label text {\n fill: ").concat(options.titleColor, ";\n }\n .cluster-label span {\n color: ").concat(options.titleColor, ";\n }\n\n .label text,span {\n fill: ").concat(options.nodeTextColor || options.textColor, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ").concat(options.mainBkg, ";\n stroke: ").concat(options.nodeBorder, ";\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ").concat(options.arrowheadColor, ";\n }\n\n .edgePath .path {\n stroke: ").concat(options.lineColor, ";\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ").concat(options.lineColor, ";\n fill: none;\n }\n\n .edgeLabel {\n background-color: ").concat(options.edgeLabelBackground, ";\n rect {\n opacity: 0.5;\n background-color: ").concat(options.edgeLabelBackground, ";\n fill: ").concat(options.edgeLabelBackground, ";\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ").concat(options.clusterBkg, ";\n stroke: ").concat(options.clusterBorder, ";\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ").concat(options.titleColor, ";\n }\n\n .cluster span {\n color: ").concat(options.titleColor, ";\n }\n // .cluster div {\n // color: ").concat(options.titleColor, ";\n // }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ").concat(options.fontFamily, ";\n font-size: 12px;\n background: ").concat(options.tertiaryColor, ";\n border: 1px solid ").concat(options.border2, ";\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n"); return ".label {\n font-family: ".concat(options.fontFamily, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n .cluster-label text {\n fill: ").concat(options.titleColor, ";\n }\n .cluster-label span {\n color: ").concat(options.titleColor, ";\n }\n\n .label text,span {\n fill: ").concat(options.nodeTextColor || options.textColor, ";\n color: ").concat(options.nodeTextColor || options.textColor, ";\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ").concat(options.mainBkg, ";\n stroke: ").concat(options.nodeBorder, ";\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ").concat(options.arrowheadColor, ";\n }\n\n .edgePath .path {\n stroke: ").concat(options.lineColor, ";\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ").concat(options.lineColor, ";\n fill: none;\n }\n\n .edgeLabel {\n background-color: ").concat(options.edgeLabelBackground, ";\n rect {\n opacity: 0.5;\n background-color: ").concat(options.edgeLabelBackground, ";\n fill: ").concat(options.edgeLabelBackground, ";\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ").concat(options.clusterBkg, ";\n stroke: ").concat(options.clusterBorder, ";\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ").concat(options.titleColor, ";\n }\n\n .cluster span {\n color: ").concat(options.titleColor, ";\n }\n /* .cluster div {\n color: ").concat(options.titleColor, ";\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ").concat(options.fontFamily, ";\n font-size: 12px;\n background: ").concat(options.tertiaryColor, ";\n border: 1px solid ").concat(options.border2, ";\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n");
}; };
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getStyles); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getStyles);
@ -19128,9 +19242,6 @@ var branches = {
var curBranch = 'master'; var curBranch = 'master';
var direction = 'LR'; var direction = 'LR';
var seq = 0; var seq = 0;
/**
*
*/
function getId() { function getId() {
return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.random)({ return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.random)({
@ -25361,6 +25472,12 @@ __webpack_require__.r(__webpack_exports__);
var conf = {}; var conf = {};
/**
* Merges the value of `conf` with the passed `cnf`
*
* @param {object} cnf Config to merge
*/
var setConf = function setConf(cnf) { var setConf = function setConf(cnf) {
var keys = Object.keys(cnf); var keys = Object.keys(cnf);
keys.forEach(function (key) { keys.forEach(function (key) {
@ -25370,8 +25487,8 @@ var setConf = function setConf(cnf) {
/** /**
* 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} id * @param {string} id The text for the error
* @param {any} ver * @param {string} ver The version
*/ */
var draw = function draw(id, ver) { var draw = function draw(id, ver) {
@ -25445,6 +25562,14 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-mini */ "./node_modules/moment-mini/moment.min.js"); /* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment-mini */ "./node_modules/moment-mini/moment.min.js");
/* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_mini__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var moment_mini__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment_mini__WEBPACK_IMPORTED_MODULE_0__);
/**
* @typedef {"debug" | "info" | "warn" | "error" | "fatal"} LogLevel A log level
*/
/**
* @type {Object<LogLevel, number>}
*/
var LEVELS = { var LEVELS = {
debug: 1, debug: 1,
info: 2, info: 2,
@ -25459,6 +25584,11 @@ var log = {
error: function error() {}, error: function error() {},
fatal: function fatal() {} fatal: function fatal() {}
}; };
/**
* Sets a log level
* @param {LogLevel} [level="fatal"] The level to set the logging to
*/
var setLogLevel = function setLogLevel() { var setLogLevel = function setLogLevel() {
var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'fatal'; var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'fatal';
@ -25503,6 +25633,11 @@ var setLogLevel = function setLogLevel() {
log.debug = console.debug ? console.debug.bind(console, format('DEBUG'), 'color: lightgreen') : console.log.bind(console, '\x1b[32m', format('DEBUG')); log.debug = console.debug ? console.debug.bind(console, format('DEBUG'), 'color: lightgreen') : console.log.bind(console, '\x1b[32m', format('DEBUG'));
} }
}; };
/**
* Returns a format with the timestamp and the log level
* @param {LogLevel} level The level for the log format
* @returns {string} The format with the timestamp and log level
*/
var format = function format(level) { var format = function format(level) {
var time = moment_mini__WEBPACK_IMPORTED_MODULE_0___default()().format('ss.SSS'); var time = moment_mini__WEBPACK_IMPORTED_MODULE_0___default()().format('ss.SSS');
@ -26010,7 +26145,7 @@ var decodeEntities = function decodeEntities(text) {
/** /**
* Function that renders an svg with a graph from a chart definition. Usage example below. * Function that renders an svg with a graph from a chart definition. Usage example below.
* *
* ```js * ```javascript
* mermaidAPI.initialize({ * mermaidAPI.initialize({
* startOnLoad: true, * startOnLoad: true,
* }); * });
@ -28241,7 +28376,11 @@ var detectDirective = function detectDirective(text) {
* g-->h * g-->h
* ``` * ```
* @param {string} text The text defining the graph * @param {string} text The text defining the graph
* @param {any} cnf * @param {{
* class: { defaultRenderer: string } | undefined;
* state: { defaultRenderer: string } | undefined;
* flowchart: { defaultRenderer: string } | undefined;
* }} [cnf]
* @returns {string} A graph definition key * @returns {string} A graph definition key
*/ */
@ -28305,6 +28444,13 @@ var detectType = function detectType(text, cnf) {
if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper') return 'flowchart-v2'; if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper') return 'flowchart-v2';
return 'flowchart'; return 'flowchart';
}; };
/**
* Caches results of functions based on input
*
* @param {Function} fn Function to run
* @param {Function} resolver Function that resolves to an ID given arguments the `fn` takes
* @returns {Function} An optimized caching function
*/
var memoize = function memoize(fn, resolver) { var memoize = function memoize(fn, resolver) {
var cache = {}; var cache = {};
@ -28339,6 +28485,14 @@ var isSubstringInArray = function isSubstringInArray(str, arr) {
return -1; return -1;
}; };
/**
* Returns a d3 curve given a curve name
*
* @param {string | undefined} interpolate The interpolation name
* @param {any} defaultCurve The default curve to return
* @returns {import('d3-shape').CurveFactory} The curve factory to use
*/
var interpolateToCurve = function interpolateToCurve(interpolate, defaultCurve) { var interpolateToCurve = function interpolateToCurve(interpolate, defaultCurve) {
if (!interpolate) { if (!interpolate) {
return defaultCurve; return defaultCurve;
@ -28347,6 +28501,14 @@ var interpolateToCurve = function interpolateToCurve(interpolate, defaultCurve)
var curveName = "curve".concat(interpolate.charAt(0).toUpperCase() + interpolate.slice(1)); var curveName = "curve".concat(interpolate.charAt(0).toUpperCase() + interpolate.slice(1));
return d3CurveTypes[curveName] || defaultCurve; return d3CurveTypes[curveName] || defaultCurve;
}; };
/**
* Formats a URL string
*
* @param {string} linkStr String of the URL
* @param {{ securityLevel: string }} config Configuration passed to MermaidJS
* @returns {string | undefined} The formatted URL
*/
var formatUrl = function formatUrl(linkStr, config) { var formatUrl = function formatUrl(linkStr, config) {
var url = linkStr.trim(); var url = linkStr.trim();
@ -28358,6 +28520,13 @@ var formatUrl = function formatUrl(linkStr, config) {
return url; return url;
} }
}; };
/**
* Runs a function
*
* @param {string} functionName A dot seperated path to the function relative to the `window`
* @param {...any} params Parameters to pass to the function
*/
var runFunc = function runFunc(functionName) { var runFunc = function runFunc(functionName) {
var _obj; var _obj;
@ -28377,10 +28546,29 @@ var runFunc = function runFunc(functionName) {
(_obj = obj)[fnName].apply(_obj, params); (_obj = obj)[fnName].apply(_obj, params);
}; };
/**
* @typedef {object} Point A (x, y) point
* @property {number} x The x value
* @property {number} y The y value
*/
/**
* Finds the distance between two points using the Distance Formula
*
* @param {Point} p1 The first point
* @param {Point} p2 The second point
* @returns {number} The distance
*/
var distance = function distance(p1, p2) { var distance = function distance(p1, p2) {
return p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0; return p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0;
}; };
/**
* @param {Point[]} points List of points
* @returns {Point}
* @todo Give this a description
*/
var traverseEdge = function traverseEdge(points) { var traverseEdge = function traverseEdge(points) {
var prevPoint; var prevPoint;
@ -28422,6 +28610,13 @@ var traverseEdge = function traverseEdge(points) {
}); });
return center; return center;
}; };
/**
* Alias for `traverseEdge`
*
* @param {Point[]} points List of points
* @returns {Point} Return result of `transverseEdge`
*/
var calcLabelPosition = function calcLabelPosition(points) { var calcLabelPosition = function calcLabelPosition(points) {
return traverseEdge(points); return traverseEdge(points);
@ -28573,6 +28768,13 @@ var calcTerminalLabelPosition = function calcTerminalLabelPosition(terminalMarke
return cardinalityPosition; return cardinalityPosition;
}; };
/**
* Gets styles from an array of declarations
*
* @param {string[]} arr Declarations
* @returns {{ style: string; labelStyle: string }} The styles grouped as strings
*/
var getStylesFromArray = function getStylesFromArray(arr) { var getStylesFromArray = function getStylesFromArray(arr) {
var style = ''; var style = '';
@ -28627,19 +28829,31 @@ var random = function random(options) {
* effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the * effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the
* config.clobber parameter === true. Example: * config.clobber parameter === true. Example:
* *
* let config_0 = { foo: { bar: 'bar' }, bar: 'foo' }; * ```js
* let config_1 = { foo: 'foo', bar: 'bar' }; * let config_0 = { foo: { bar: 'bar' }, bar: 'foo' };
* let result = assignWithDepth(config_0, config_1); * let config_1 = { foo: 'foo', bar: 'bar' };
* console.log(result); * let result = assignWithDepth(config_0, config_1);
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }<p> * console.log(result);
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }
* ```
* *
* Traditional Object.assign would have clobbered foo in config_0 with foo in config_1.<p> If src is * Traditional Object.assign would have clobbered foo in config_0 with foo in config_1. If src is a
* a destructured array of objects and dst is not an array, assignWithDepth will apply each * destructured array of objects and dst is not an array, assignWithDepth will apply each element
* element of src to dst in order. * of src to dst in order.
* @param dst
* @param src
* @param config
* @param dst
* @param src
* @param config
* @param dst
* @param src
* @param config
* @param {any} dst - The destination of the merge * @param {any} dst - The destination of the merge
* @param {any} src - The source object(s) to merge into destination * @param {any} src - The source object(s) to merge into destination
* @param {{ depth: number; clobber: boolean }} config - Depth: depth to traverse within src and dst * @param {{ depth: number; clobber: boolean }} [config={ depth: 2, clobber: false }] - Depth: depth
* for merging - clobber: should dissimilar types clobber (default: { depth: 2, clobber: false }) * to traverse within src and dst for merging - clobber: should dissimilar types clobber (default:
* { depth: 2, clobber: false }). Default is `{ depth: 2, clobber: false }`
* @returns {any} * @returns {any}
*/ */
@ -28707,6 +28921,25 @@ var getTextObj = function getTextObj() {
valign: undefined valign: undefined
}; };
}; };
/**
* Adds text to an element
*
* @param {SVGElement} elem Element to add text to
* @param {{
* text: string;
* x: number;
* y: number;
* anchor: 'start' | 'middle' | 'end';
* fontFamily: string;
* fontSize: string | number;
* fontWeight: string | number;
* fill: string;
* class: string | undefined;
* textMargin: number;
* }} textData
* @returns {SVGTextElement} Text element with given styling and content
*/
var drawSimpleText = function drawSimpleText(elem, textData) { var drawSimpleText = function drawSimpleText(elem, textData) {
// Remove and ignore br:s // Remove and ignore br:s
var nText = textData.text.replace(_diagrams_common_common__WEBPACK_IMPORTED_MODULE_3__["default"].lineBreakRegex, ' '); var nText = textData.text.replace(_diagrams_common_common__WEBPACK_IMPORTED_MODULE_3__["default"].lineBreakRegex, ' ');
@ -28935,6 +29168,12 @@ var calculateTextDimensions = memoize(function (text, config) {
}, function (text, config) { }, function (text, config) {
return "".concat(text, "-").concat(config.fontSize, "-").concat(config.fontWeight, "-").concat(config.fontFamily); return "".concat(text, "-").concat(config.fontSize, "-").concat(config.fontWeight, "-").concat(config.fontFamily);
}); });
/**
* Applys d3 attributes
*
* @param {any} d3Elem D3 Element to apply the attributes onto
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of attributes
*/
var d3Attrs = function d3Attrs(d3Elem, attrs) { var d3Attrs = function d3Attrs(d3Elem, attrs) {
var _iterator2 = _createForOfIteratorHelper(attrs), var _iterator2 = _createForOfIteratorHelper(attrs),
@ -28951,6 +29190,15 @@ var d3Attrs = function d3Attrs(d3Elem, attrs) {
_iterator2.f(); _iterator2.f();
} }
}; };
/**
* Gives attributes for an SVG's size given arguments
*
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
* @returns {Map<'height' | 'width' | 'style', string>} Attributes for the SVG
*/
var calculateSvgSizeAttrs = function calculateSvgSizeAttrs(height, width, useMaxWidth) { var calculateSvgSizeAttrs = function calculateSvgSizeAttrs(height, width, useMaxWidth) {
var attrs = new Map(); var attrs = new Map();
@ -28965,6 +29213,15 @@ var calculateSvgSizeAttrs = function calculateSvgSizeAttrs(height, width, useMax
return attrs; return attrs;
}; };
/**
* Applies attributes from `calculateSvgSizeAttrs`
*
* @param {SVGSVGElement} svgElem The SVG Element to configure
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
*/
var configureSvgSize = function configureSvgSize(svgElem, height, width, useMaxWidth) { var configureSvgSize = function configureSvgSize(svgElem, height, width, useMaxWidth) {
var attrs = calculateSvgSizeAttrs(height, width, useMaxWidth); var attrs = calculateSvgSizeAttrs(height, width, useMaxWidth);
d3Attrs(svgElem, attrs); d3Attrs(svgElem, attrs);
@ -28987,9 +29244,15 @@ var initIdGeneratior = /*#__PURE__*/function () {
}]); }]);
return iterator; return iterator;
}(); // Source https://github.com/shrpne/entity-decode/blob/master/browser.js }();
var decoder; var decoder;
/**
* Decodes HTML, source: {@link https://github.com/shrpne/entity-decode/blob/v2.0.1/browser.js}
*
* @param {string} html HTML as a string
* @returns Unescaped HTML
*/
var entityDecode = function entityDecode(html) { var entityDecode = function entityDecode(html) {
decoder = decoder || document.createElement('div'); // Escape HTML before decoding for HTML Entities decoder = decoder || document.createElement('div'); // Escape HTML before decoding for HTML Entities
@ -28998,6 +29261,12 @@ var entityDecode = function entityDecode(html) {
decoder.innerHTML = html; decoder.innerHTML = html;
return unescape(decoder.textContent); return unescape(decoder.textContent);
}; };
/**
* Sanitizes directive objects
*
* @param {object} args Directive's JSON
*/
var directiveSanitizer = function directiveSanitizer(args) { var directiveSanitizer = function directiveSanitizer(args) {
_logger__WEBPACK_IMPORTED_MODULE_2__.log.debug('directiveSanitizer called with', args); _logger__WEBPACK_IMPORTED_MODULE_2__.log.debug('directiveSanitizer called with', args);

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/mermaid.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -73,7 +73,7 @@ When deployed within code, init is called before the graph/diagram description.
``` ```
**for example**: **for example**:
``` ```mmd
%%{init: {"theme": "default", "logLevel": 1 }}%% %%{init: {"theme": "default", "logLevel": 1 }}%%
graph LR graph LR
a-->b a-->b

View File

@ -24,7 +24,7 @@ Site-wide themes are still declared via `initialize` by site owners.
Example of `Initalize` call setting `theme` to `base`: Example of `Initalize` call setting `theme` to `base`:
```js ```javascript
mermaidAPI.initialize({ mermaidAPI.initialize({
'securityLevel': 'loose', 'theme': 'base' 'securityLevel': 'loose', 'theme': 'base'
}); });
@ -39,7 +39,7 @@ It is also possible to override site-wide theme settings locally, for a specific
**Following is an example:** **Following is an example:**
``` ```mmd
%%{init: {'theme':'base'}}%% %%{init: {'theme':'base'}}%%
graph TD graph TD
a --> b a --> b
@ -56,7 +56,7 @@ The easiest way to make a custom theme is to start with the base theme, and just
Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`. Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`.
``` ```mmd
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%% %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)

View File

@ -5,7 +5,7 @@ Configuration is the second half of Mermaid, after deployment. Together Deployme
This section will introduce the different methods of configuring of the behaviors and appearances of Mermaid Diagrams. This section will introduce the different methods of configuring of the behaviors and appearances of Mermaid Diagrams.
The Following are the most commonly used methods, and are all tied to Mermaid [Deployment](./n00b-gettingStarted.md) methods. The Following are the most commonly used methods, and are all tied to Mermaid [Deployment](./n00b-gettingStarted.md) methods.
## Configuration Section in the [Live Editor](./Live-Editor.md). ## Configuration Section in the [Live Editor](https://mermaid-js.github.io/mermaid-live-editor).
## The `initialize()` call, for when Mermaid is called via an API, or through a <script> tag. ## The `initialize()` call, for when Mermaid is called via an API, or through a <script> tag.

View File

@ -48,7 +48,7 @@ For a more detailed introduction to Mermaid and some of it's basic uses, refer t
### [Flowchart](./flowchart.md?id=flowcharts-basic-syntax) ### [Flowchart](./flowchart.md?id=flowcharts-basic-syntax)
``` ```mmd
graph TD; graph TD;
A-->B; A-->B;
A-->C; A-->C;
@ -60,7 +60,7 @@ graph TD;
### [Sequence diagram](./sequenceDiagram.md) ### [Sequence diagram](./sequenceDiagram.md)
``` ```mmd
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant Bob participant Bob
@ -78,7 +78,7 @@ sequenceDiagram
### [Gantt diagram](./gantt.md) ### [Gantt diagram](./gantt.md)
``` ```mmd
gantt gantt
dateFormat YYYY-MM-DD dateFormat YYYY-MM-DD
title Adding GANTT diagram to mermaid title Adding GANTT diagram to mermaid
@ -95,7 +95,7 @@ Future task2 : des4, after des3, 5d
### [Class diagram](./classDiagram.md) ### [Class diagram](./classDiagram.md)
``` ```mmd
classDiagram classDiagram
Class01 <|-- AveryLongClass : Cool Class01 <|-- AveryLongClass : Cool
Class03 *-- Class04 Class03 *-- Class04
@ -116,7 +116,7 @@ Class08 <--> C2: Cool label
### Git graph - :exclamation: experimental ### Git graph - :exclamation: experimental
``` ```mmd
gitGraph: gitGraph:
options options
{ {
@ -139,7 +139,7 @@ merge newbranch
### [Entity Relationship Diagram - :exclamation: experimental](./entityRelationshipDiagram.md) ### [Entity Relationship Diagram - :exclamation: experimental](./entityRelationshipDiagram.md)
``` ```mmd
erDiagram erDiagram
CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains ORDER ||--|{ LINE-ITEM : contains
@ -151,7 +151,7 @@ erDiagram
### [User Journey Diagram](./user-journey.md) ### [User Journey Diagram](./user-journey.md)
```markdown ```mmd
journey journey
title My working day title My working day
section Go to work section Go to work
@ -229,19 +229,19 @@ Don't hesitate to contact me if you want to get involved!
### Setup ### Setup
``` ```sh
yarn install yarn install
``` ```
### Build ### Build
``` ```sh
yarn build:watch yarn build:watch
``` ```
### Lint ### Lint
``` ```sh
yarn lint yarn lint
``` ```
@ -250,7 +250,7 @@ We recommend you to install [editor plugins](https://eslint.org/docs/user-guide/
### Test ### Test
``` ```sh
yarn test yarn test
``` ```
Manual test in browser: open `dist/index.html` Manual test in browser: open `dist/index.html`
@ -261,7 +261,7 @@ For those who have the permission to do so:
Update version number in `package.json`. Update version number in `package.json`.
``` ```sh
npm publish npm publish
``` ```

View File

@ -925,17 +925,14 @@ Default value: true
**Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls
to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig)
will reset siteConfig and current Config to the defaultConfig will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this
function \*Default value: At default, will mirror Global Config\*\*
Note: currentConfig is set in this function
Default value: At default, will mirror Global Config
### Parameters ### Parameters
- `conf` **any** The base currentConfig to use as siteConfig - `conf` The base currentConfig to use as siteConfig
Returns **any** The siteConfig Returns **[object][5]** The siteConfig
## parse ## parse
@ -949,13 +946,13 @@ Returns **any**
## getSiteConfig ## getSiteConfig
| Function | Description | Type | Values | | Function | Description | Type | Values |
| ------------- | ------------------------------------------------- | ----------- | --------------------------------- | | ------------- | ------------------------------------------------- | ----------- | -------------------------------- |
| setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in site Config | | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig |
**Notes**: Returns **any** values in siteConfig. **Notes**: Returns **any** values in siteConfig.
Returns **any** Returns **[object][5]** The siteConfig
## setConfig ## setConfig
@ -1002,6 +999,14 @@ options in-place
- `options` **any** The potential setConfig parameter - `options` **any** The potential setConfig parameter
## addDirective
Pushes in a directive to the configuration
### Parameters
- `directive` **[object][5]** The directive to push in
## reset ## reset
## reset ## reset
@ -1021,7 +1026,7 @@ options in-place
Function that renders an svg with a graph from a chart definition. Usage example below. Function that renders an svg with a graph from a chart definition. Usage example below.
```js ```javascript
mermaidAPI.initialize({ mermaidAPI.initialize({
startOnLoad: true, startOnLoad: true,
}); });
@ -1128,3 +1133,5 @@ Returns **any**
[3]: 8.6.0_docs.md [3]: 8.6.0_docs.md
[4]: #mermaidapi-configuration-defaults [4]: #mermaidapi-configuration-defaults
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object

View File

@ -7,32 +7,7 @@ The class diagram is the main building block of object-oriented modeling. It is
Mermaid can render class diagrams. Mermaid can render class diagrams.
``` ```mermaid-example
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
```
```mermaid
classDiagram classDiagram
Animal <|-- Duck Animal <|-- Duck
Animal <|-- Fish Animal <|-- Fish
@ -68,7 +43,7 @@ A single instance of a class in the diagram contains three compartments:
- The middle compartment contains the attributes of the class. They are left-aligned and the first letter is lowercase. - The middle compartment contains the attributes of the class. They are left-aligned and the first letter is lowercase.
The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase. The bottom compartment contains the operations the class can execute. They are also left-aligned and the first letter is lowercase.
``` ```mermaid-example
classDiagram classDiagram
class BankAccount class BankAccount
BankAccount : +String owner BankAccount : +String owner
@ -78,15 +53,6 @@ classDiagram
``` ```
```mermaid
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +BigDecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
```
## Define a class ## Define a class
There are two ways to define a class: There are two ways to define a class:
@ -94,13 +60,7 @@ There are two ways to define a class:
- Explicitly defining a class using keyword **class** like `class Animal`. This defines the Animal class - Explicitly defining a class using keyword **class** like `class Animal`. This defines the Animal class
- Define two classes via a **relationship** between them `Vehicle <|-- Car`. This defines two classes Vehicle and Car along with their relationship. - Define two classes via a **relationship** between them `Vehicle <|-- Car`. This defines two classes Vehicle and Car along with their relationship.
``` ```mermaid-example
classDiagram
class Animal
Vehicle <|-- Car
```
```mermaid
classDiagram classDiagram
class Animal class Animal
Vehicle <|-- Car Vehicle <|-- Car
@ -118,7 +78,8 @@ There are two ways to define the members of a class, and regardless of whichever
- Associate a member of a class using **:** (colon) followed by member name, useful to define one member at a time. For example: - Associate a member of a class using **:** (colon) followed by member name, useful to define one member at a time. For example:
``` ```mermaid-example
classDiagram
class BankAccount class BankAccount
BankAccount : +String owner BankAccount : +String owner
BankAccount : +BigDecimal balance BankAccount : +BigDecimal balance
@ -126,18 +87,10 @@ There are two ways to define the members of a class, and regardless of whichever
BankAccount : +withdrawal(amount) BankAccount : +withdrawal(amount)
``` ```
```mermaid
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +BigDecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
```
- Associate members of a class using **{}** brackets, where members are grouped within curly brackets. Suitable for defining multiple members at once. For example: - Associate members of a class using **{}** brackets, where members are grouped within curly brackets. Suitable for defining multiple members at once. For example:
``` ```mermaid-example
classDiagram
class BankAccount{ class BankAccount{
+String owner +String owner
+BigDecimal balance +BigDecimal balance
@ -146,22 +99,13 @@ class BankAccount{
} }
``` ```
```mermaid
classDiagram
class BankAccount{
+String owner
+BigDecimal balance
+deposit(amount)
+withdrawl(amount)
}
```
#### Return Type #### Return Type
Optionally you can end the method/function definition with the data type that will be returned (note: there must be a space between the final `)` of the method definition and return type Optionally you can end the method/function definition with the data type that will be returned (note: there must be a space between the final `)` of the method definition and return type
example: example:
``` ```mermaid-example
classDiagram
class BankAccount{ class BankAccount{
+String owner +String owner
+BigDecimal balance +BigDecimal balance
@ -170,37 +114,13 @@ class BankAccount{
} }
``` ```
```mermaid
classDiagram
class BankAccount{
+String owner
+BigDecimal balance
+deposit(amount) bool
+withdrawl(amount) int
}
```
#### Generic Types #### Generic Types
Members can be defined using generic types, such as `List<int>`, for fields, parameters and return types by enclosing the type within `~` (**tilde**). Note: **nested** type declarations (such as `List<List<int>>`) are not currently supported Members can be defined using generic types, such as `List<int>`, for fields, parameters and return types by enclosing the type within `~` (**tilde**). Note: **nested** type declarations (such as `List<List<int>>`) are not currently supported
This can be done as part of either class definition method: This can be done as part of either class definition method:
``` ```mermaid-example
classDiagram
class Square~Shape~{
int id
List~int~ position
setPoints(List~int~ points)
getPoints() List~int~
}
Square : -List~string~ messages
Square : +setMessages(List~string~ messages)
Square : +getMessages() List~string~
```
```mermaid
classDiagram classDiagram
class Square~Shape~{ class Square~Shape~{
int id int id
@ -257,20 +177,7 @@ There are different types of relations defined for classes under UML which are c
| ..\|> | Realization | | ..\|> | Realization |
| .. | Link (Dashed) | | .. | Link (Dashed) |
``` ```mermaid-example
classDiagram
classA <|-- classB
classC *-- classD
classE o-- classF
classG <-- classH
classI -- classJ
classK <.. classL
classM <|.. classN
classO .. classP
```
```mermaid
classDiagram classDiagram
classA <|-- classB classA <|-- classB
classC *-- classD classC *-- classD
@ -285,7 +192,7 @@ classO .. classP
We can use the labels to describe nature of relation between two classes. Also, arrowheads can be used in opposite directions as well : We can use the labels to describe nature of relation between two classes. Also, arrowheads can be used in opposite directions as well :
``` ```mermaid-example
classDiagram classDiagram
classA --|> classB : Inheritance classA --|> classB : Inheritance
classC --* classD : Composition classC --* classD : Composition
@ -298,18 +205,6 @@ classO .. classP : Link(Dashed)
``` ```
```mermaid
classDiagram
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI -- classJ : Link(Solid)
classK ..> classL : Dependency
classM ..|> classN : Realization
classO .. classP : Link(Dashed)
```
### Labels on Relations ### Labels on Relations
It is possible to add a label text to a relation: It is possible to add a label text to a relation:
@ -318,25 +213,18 @@ It is possible to add a label text to a relation:
[classA][Arrow][ClassB]:LabelText [classA][Arrow][ClassB]:LabelText
``` ```
``` ```mermaid-example
classDiagram classDiagram
classA <|-- classB : implements classA <|-- classB : implements
classC *-- classD : composition classC *-- classD : composition
classE o-- classF : association classE o-- classF : association
``` ```
```mermaid
classDiagram
classA <|-- classB : implements
classE o-- classF : association
```
### Two-way relations ### Two-way relations
Relations can go in multiple ways: Relations can go in multiple ways:
``` ```mmd
classDiagram classDiagram
Animal <|--|> Zebra Animal <|--|> Zebra
``` ```
@ -388,14 +276,7 @@ Cardinality can be easily defined by placing cardinality text within quotes `"`
[classA] "cardinality1" [Arrow] "cardinality2" [ClassB]:LabelText [classA] "cardinality1" [Arrow] "cardinality2" [ClassB]:LabelText
``` ```
``` ```mermaid-example
classDiagram
Customer "1" --> "*" Ticket
Student "1" --> "1..*" Course
Galaxy --> "many" Star : Contains
```
```mermaid
classDiagram classDiagram
Customer "1" --> "*" Ticket Customer "1" --> "*" Ticket
Student "1" --> "1..*" Course Student "1" --> "1..*" Course
@ -415,13 +296,7 @@ Annotations are defined within the opening `<<` and closing `>>`. There are two
- In a **_separate line_** after a class is defined. For example: - In a **_separate line_** after a class is defined. For example:
``` ```mermaid-example
classDiagram
class Shape
<<interface>> Shape
```
```mermaid
classDiagram classDiagram
class Shape class Shape
<<interface>> Shape <<interface>> Shape
@ -431,7 +306,7 @@ Shape : draw()
- In a **_nested structure_** along with class definition. For example: - In a **_nested structure_** along with class definition. For example:
``` ```mermaid-example
classDiagram classDiagram
class Shape{ class Shape{
<<interface>> <<interface>>
@ -449,28 +324,11 @@ class Color{
``` ```
```mermaid
classDiagram
class Shape{
<<interface>>
noOfVertices
draw()
}
class Color{
<<enumeration>>
RED
BLUE
GREEN
WHITE
BLACK
}
```
## Comments ## Comments
Comments can be entered within a class diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any class diagram syntax Comments can be entered within a class diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any class diagram syntax
``` ```mmd
classDiagram classDiagram
%% This whole line is a comment classDiagram class Shape <<interface>> %% This whole line is a comment classDiagram class Shape <<interface>>
class Shape{ class Shape{
@ -485,25 +343,7 @@ class Shape{
With class diagrams you can use the direction statement to set the direction which the diagram will render like in this example. With class diagrams you can use the direction statement to set the direction which the diagram will render like in this example.
``` ```mermaid-example
classDiagram
direction RL
class Student {
-idCard : IdCard
}
class IdCard{
-id : int
-name : string
}
class Bike{
-id : int
-name : string
}
Student "1" --o "1" IdCard : carries
Student "1" --o "1" Bike : rides
```
This is how this renders
```mermaid
classDiagram classDiagram
direction RL direction RL
class Student { class Student {
@ -542,7 +382,7 @@ click className href "url" "tooltip"
_URL Link:_ _URL Link:_
``` ```mmd
classDiagram classDiagram
class Shape class Shape
link Shape "http://www.github.com" "This is a tooltip for a link" link Shape "http://www.github.com" "This is a tooltip for a link"
@ -552,7 +392,7 @@ click Shape2 href "http://www.github.com" "This is a tooltip for a link"
_Callback:_ _Callback:_
``` ```mmd
classDiagram classDiagram
class Shape class Shape
callback Shape "callbackFunction" "This is a tooltip for a callback" callback Shape "callbackFunction" "This is a tooltip for a callback"
@ -560,7 +400,7 @@ class Shape2
click Shape2 call callbackFunction() "This is a tooltip for a callback" click Shape2 call callbackFunction() "This is a tooltip for a callback"
``` ```
``` ```html
<script> <script>
var callbackFunction = function(){ var callbackFunction = function(){
alert('A callback was triggered'); alert('A callback was triggered');
@ -584,7 +424,7 @@ classDiagram
Beginners tip, a full example using interactive links in an html context: Beginners tip, a full example using interactive links in an html context:
``` ```html
<body> <body>
<div class="mermaid"> <div class="mermaid">
classDiagram classDiagram
@ -658,14 +498,14 @@ It is also possible to attach a class to a list of nodes in one statement:
A shorter form of adding a class is to attach the classname to the node using the `:::` operator as per below: A shorter form of adding a class is to attach the classname to the node using the `:::` operator as per below:
``` ```mmd
classDiagram classDiagram
class Animal:::cssClass class Animal:::cssClass
``` ```
Or: Or:
``` ```mmd
classDiagram classDiagram
class Animal:::cssClass { class Animal:::cssClass {
-int sizeInFeet -int sizeInFeet

View File

@ -78,7 +78,7 @@ When running in CI it will take a snapshot of the rendered diagram and compare i
This is what a rendering test looks like: This is what a rendering test looks like:
``` ```js
it('should render forks and joins', () => { it('should render forks and joins', () => {
imgSnapshotTest( imgSnapshotTest(
` `

View File

@ -11,22 +11,14 @@ This statement declares the direction of the Flowchart.
This declares the graph is oriented from top to bottom (`TD` or `TB`). This declares the graph is oriented from top to bottom (`TD` or `TB`).
``` ```mermaid-example
graph TD
Start --> Stop
```
```mermaid
graph TD graph TD
Start --> Stop Start --> Stop
``` ```
This declares the graph is oriented from left to right (`LR`). This declares the graph is oriented from left to right (`LR`).
``` ```mermaid-example
graph LR
Start --> Stop
```
```mermaid
graph LR graph LR
Start --> Stop Start --> Stop
``` ```
@ -55,12 +47,7 @@ Apart from the graph type, the syntax is the same. This is currently experimenta
### A node (default) ### A node (default)
``` ```mermaid-example
graph LR
id
```
```mermaid
graph LR graph LR
id id
``` ```
@ -73,11 +60,7 @@ It is also possible to set text in the box that differs from the id. If this is
found for the node that will be used. Also if you define edges for the node later on, you can omit text definitions. The found for the node that will be used. Also if you define edges for the node later on, you can omit text definitions. The
one previously defined will be used when rendering the box. one previously defined will be used when rendering the box.
``` ```mermaid-example
graph LR
id1[This is the text in the box]
```
```mermaid
graph LR graph LR
id1[This is the text in the box] id1[This is the text in the box]
``` ```
@ -86,66 +69,42 @@ graph LR
### A node with round edges ### A node with round edges
``` ```mermaid-example
graph LR
id1(This is the text in the box)
```
```mermaid
graph LR graph LR
id1(This is the text in the box) id1(This is the text in the box)
``` ```
### A stadium-shaped node ### A stadium-shaped node
``` ```mermaid-example
graph LR
id1([This is the text in the box])
```
```mermaid
graph LR graph LR
id1([This is the text in the box]) id1([This is the text in the box])
``` ```
### A node in a subroutine shape ### A node in a subroutine shape
``` ```mermaid-example
graph LR
id1[[This is the text in the box]]
```
```mermaid
graph LR graph LR
id1[[This is the text in the box]] id1[[This is the text in the box]]
``` ```
### A node in a cylindrical shape ### A node in a cylindrical shape
``` ```mermaid-example
graph LR
id1[(Database)]
```
```mermaid
graph LR graph LR
id1[(Database)] id1[(Database)]
``` ```
### A node in the form of a circle ### A node in the form of a circle
``` ```mermaid-example
graph LR
id1((This is the text in the circle))
```
```mermaid
graph LR graph LR
id1((This is the text in the circle)) id1((This is the text in the circle))
``` ```
### A node in an asymmetric shape ### A node in an asymmetric shape
``` ```mermaid-example
graph LR
id1>This is the text in the box]
```
```mermaid
graph LR graph LR
id1>This is the text in the box] id1>This is the text in the box]
``` ```
@ -153,69 +112,40 @@ Currently only the shape above is possible and not its mirror. *This might chang
### A node (rhombus) ### A node (rhombus)
``` ```mermaid-example
graph LR
id1{This is the text in the box}
```
```mermaid
graph LR graph LR
id1{This is the text in the box} id1{This is the text in the box}
``` ```
### A hexagon node ### A hexagon node
{% raw %}
```
graph LR
id1{{This is the text in the box}}
```
{% endraw %}
```mermaid ```mermaid-example
{% raw %}
graph LR graph LR
id1{{This is the text in the box}} id1{{This is the text in the box}}
{% endraw %}
``` ```
### Parallelogram ### Parallelogram
``` ```mermaid-example
graph TD graph TD
id1[/This is the text in the box/] id1[/This is the text in the box/]
``` ```
```mermaid
graph TD
id1[/This is the text in the box/]
```
### Parallelogram alt ### Parallelogram alt
``` ```mermaid-example
graph TD
id1[\This is the text in the box\]
```
```mermaid
graph TD graph TD
id1[\This is the text in the box\] id1[\This is the text in the box\]
``` ```
### Trapezoid ### Trapezoid
``` ```mermaid-example
graph TD
A[/Christmas\]
```
```mermaid
graph TD graph TD
A[/Christmas\] A[/Christmas\]
``` ```
### Trapezoid alt ### Trapezoid alt
``` ```mermaid-example
graph TD
B[\Go shopping/]
```
```mermaid
graph TD graph TD
B[\Go shopping/] B[\Go shopping/]
``` ```
@ -226,110 +156,70 @@ Nodes can be connected with links/edges. It is possible to have different types
### A link with arrow head ### A link with arrow head
``` ```mermaid-example
graph LR
A-->B
```
```mermaid
graph LR graph LR
A-->B A-->B
``` ```
### An open link ### An open link
``` ```mermaid-example
graph LR
A --- B
```
```mermaid
graph LR graph LR
A --- B A --- B
``` ```
### Text on links ### Text on links
``` ```mermaid-example
graph LR graph LR
A-- This is the text! ---B A-- This is the text! ---B
``` ```
```mermaid
graph LR
A-- This is the text ---B
```
or or
``` ```mermaid-example
graph LR
A---|This is the text|B
```
```mermaid
graph LR graph LR
A---|This is the text|B A---|This is the text|B
``` ```
### A link with arrow head and text ### A link with arrow head and text
``` ```mermaid-example
graph LR
A-->|text|B
```
```mermaid
graph LR graph LR
A-->|text|B A-->|text|B
``` ```
or or
``` ```mermaid-example
graph LR
A-- text -->B
```
```mermaid
graph LR graph LR
A-- text -->B A-- text -->B
``` ```
### Dotted link ### Dotted link
``` ```mermaid-example
graph LR;
A-.->B;
```
```mermaid
graph LR; graph LR;
A-.->B; A-.->B;
``` ```
### Dotted link with text ### Dotted link with text
``` ```mermaid-example
graph LR
A-. text .-> B
```
```mermaid
graph LR graph LR
A-. text .-> B A-. text .-> B
``` ```
### Thick link ### Thick link
``` ```mermaid-example
graph LR
A ==> B
```
```mermaid
graph LR graph LR
A ==> B A ==> B
``` ```
### Thick link with text ### Thick link with text
``` ```mermaid-example
graph LR
A == text ==> B
```
```mermaid
graph LR graph LR
A == text ==> B A == text ==> B
``` ```
@ -337,31 +227,19 @@ graph LR
### Chaining of links ### Chaining of links
It is possible to declare many links in the same line as per below: It is possible to declare many links in the same line as per below:
``` ```mermaid-example
graph LR
A -- text --> B -- text2 --> C
```
```mermaid
graph LR graph LR
A -- text --> B -- text2 --> C A -- text --> B -- text2 --> C
``` ```
It is also possible to declare multiple nodes links in the same line as per below: It is also possible to declare multiple nodes links in the same line as per below:
``` ```mermaid-example
graph LR
a --> b & c--> d
```
```mermaid
graph LR graph LR
a --> b & c--> d a --> b & c--> d
``` ```
You can then describe dependencies in a very expressive way. Like the one-liner below: You can then describe dependencies in a very expressive way. Like the one-liner below:
``` ```mermaid-example
graph TB
A & B--> C & D
```
```mermaid
graph TB graph TB
A & B--> C & D A & B--> C & D
``` ```
@ -369,7 +247,7 @@ If you describe the same diagram using the the basic syntax, it will take four l
word of warning, one could go overboard with this making the graph harder to read in word of warning, one could go overboard with this making the graph harder to read in
markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little. markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little.
This goes for expressive syntaxes as well. This goes for expressive syntaxes as well.
``` ```mmd
graph TB graph TB
A --> C A --> C
A --> D A --> D
@ -381,13 +259,7 @@ graph TB
When using flowchart instead of graph there are new types of arrows supported as per below: When using flowchart instead of graph there are new types of arrows supported as per below:
``` ```mermaid-example
flowchart LR
A --o B
B --x C
```
```mermaid
flowchart LR flowchart LR
A --o B A --o B
B --x C B --x C
@ -398,14 +270,7 @@ flowchart LR
When using flowchart instead of graph there is the possibility to use multidirectional arrows. When using flowchart instead of graph there is the possibility to use multidirectional arrows.
``` ```mermaid-example
flowchart LR
A o--o B
B <--> C
C x--x D
```
```mermaid
flowchart LR flowchart LR
A o--o B A o--o B
B <--> C B <--> C
@ -423,16 +288,7 @@ than the others by adding extra dashes in the link definition.
In the following example, two extra dashes are added in the link from node _B_ In the following example, two extra dashes are added in the link from node _B_
to node _E_, so that it spans two more ranks than regular links: to node _E_, so that it spans two more ranks than regular links:
``` ```mermaid-example
graph TD
A[Start] --> B{Is it?};
B -->|Yes| C[OK];
C --> D[Rethink];
D --> B;
B ---->|No| E[End];
```
```mermaid
graph TD graph TD
A[Start] --> B{Is it?}; A[Start] --> B{Is it?};
B -->|Yes| C[OK]; B -->|Yes| C[OK];
@ -448,7 +304,7 @@ When the link label is written in the middle of the link, the extra dashes must
be added on the right side of the link. The following example is equivalent to be added on the right side of the link. The following example is equivalent to
the previous one: the previous one:
``` ```mermaid-example
graph TD graph TD
A[Start] --> B{Is it?}; A[Start] --> B{Is it?};
B -- Yes --> C[OK]; B -- Yes --> C[OK];
@ -457,15 +313,6 @@ graph TD
B -- No ----> E[End]; B -- No ----> E[End];
``` ```
```mermaid
graph TD
A[Start] --> B{Is it?};
B -->|Yes| C[OK];
C --> D[Rethink];
D --> B;
B ---->|No| E[End];
```
For dotted or thick links, the characters to add are equals signs or dots, For dotted or thick links, the characters to add are equals signs or dots,
as summed up in the following table: as summed up in the following table:
@ -482,11 +329,7 @@ as summed up in the following table:
It is possible to put text within quotes in order to render more troublesome characters. As in the example below: It is possible to put text within quotes in order to render more troublesome characters. As in the example below:
``` ```mermaid-example
graph LR
id1["This is the (text) in the box"]
```
```mermaid
graph LR graph LR
id1["This is the (text) in the box"] id1["This is the (text) in the box"]
``` ```
@ -495,11 +338,7 @@ graph LR
It is possible to escape characters using the syntax exemplified here. It is possible to escape characters using the syntax exemplified here.
``` ```mermaid-example
graph LR
A["A double quote:#quot;"] -->B["A dec char:#9829;"]
```
```mermaid
graph LR graph LR
A["A double quote:#quot;"] -->B["A dec char:#9829;"] A["A double quote:#quot;"] -->B["A dec char:#9829;"]
``` ```
@ -514,20 +353,7 @@ end
An example below: An example below:
``` ```mermaid-example
graph TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end
```
```mermaid
graph TB graph TB
c1-->a2 c1-->a2
subgraph one subgraph one
@ -543,43 +369,19 @@ graph TB
You can also set an explicit id for the subgraph. You can also set an explicit id for the subgraph.
``` ```mermaid-example
graph TB graph TB
c1-->a2 c1-->a2
subgraph ide1 [one] subgraph ide1 [one]
a1-->a2 a1-->a2
end end
``` ```
```mermaid
graph TB
c1-->a2
subgraph id1 [one]
a1-->a2
end
```
## Beta: flowcharts ## Beta: flowcharts
With the graphtype flowcharts it is also possible to set edges to and from subgraphs as in the graph below. With the graphtype flowcharts it is also possible to set edges to and from subgraphs as in the graph below.
``` ```mermaid-example
flowchart TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end
one --> two
three --> two
two --> c2
```
```mermaid
flowchart TB flowchart TB
c1-->a2 c1-->a2
subgraph one subgraph one
@ -618,7 +420,9 @@ Examples of tooltip usage below:
</script> </script>
``` ```
``` The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class .mermaidTooltip.
```mermaid-example
graph LR; graph LR;
A-->B; A-->B;
B-->C; B-->C;
@ -628,37 +432,12 @@ graph LR;
click A call callback() "Tooltip for a callback" click A call callback() "Tooltip for a callback"
click B href "http://www.github.com" "This is a tooltip for a link" click B href "http://www.github.com" "This is a tooltip for a link"
``` ```
The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class .mermaidTooltip.
```mermaid
graph LR
A-->B;
B-->C;
C-->D;
click A callback "Tooltip"
click B "http://www.github.com" "This is a link"
click C call callback() "Tooltip"
click D href "http://www.github.com" "This is a link"
```
> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. > **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2.
?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/). ?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/).
Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported):
``` ```mermaid-example
graph LR;
A-->B;
B-->C;
C-->D;
D-->E;
click A "http://www.github.com" _blank
click B "http://www.github.com" "Open this in a new tab" _blank
click C href "http://www.github.com" _blank
click D href "http://www.github.com" "Open this in a new tab" _blank
```
```mermaid
graph LR; graph LR;
A-->B; A-->B;
B-->C; B-->C;
@ -707,7 +486,7 @@ Beginners tip, a full example using interactive links in a html context:
Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax
``` ```mmd
graph LR graph LR
%% this is a comment A -- text --> B{node} %% this is a comment A -- text --> B{node}
A -- text --> B -- text2 --> C A -- text --> B -- text2 --> C
@ -751,13 +530,7 @@ linkStyle default interpolate cardinal stroke:#ff3,stroke-width:4px,color:red;
It is possible to apply specific styles such as a thicker border or a different background color to a node. It is possible to apply specific styles such as a thicker border or a different background color to a node.
``` ```mermaid-example
graph LR
id1(Start)-->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
```
```mermaid
graph LR graph LR
id1(Start)-->id2(Stop) id1(Start)-->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px style id1 fill:#f9f,stroke:#333,stroke-width:4px
@ -791,12 +564,7 @@ It is also possible to attach a class to a list of nodes in one statement:
A shorter form of adding a class is to attach the classname to the node using the `:::`operator as per below: A shorter form of adding a class is to attach the classname to the node using the `:::`operator as per below:
``` ```mermaid-example
graph LR
A:::someclass --> B
classDef someclass fill:#f96;
```
```mermaid
graph LR graph LR
A:::someclass --> B A:::someclass --> B
classDef someclass fill:#f96; classDef someclass fill:#f96;
@ -822,13 +590,7 @@ below:
**Example definition** **Example definition**
``` ```mermaid-example
graph LR;
A-->B[AAA<span>BBB</span>];
B-->D;
class A cssClass;
```
```mermaid
graph LR; graph LR;
A-->B[AAA<span>BBB</span>]; A-->B[AAA<span>BBB</span>];
B-->D; B-->D;
@ -851,14 +613,7 @@ It is possible to add icons from fontawesome.
The icons are accessed via the syntax fa:#icon class name#. The icons are accessed via the syntax fa:#icon class name#.
``` ```mermaid-example
graph TD
B["fa:fa-twitter for peace"]
B-->C[fa:fa-ban forbidden]
B-->D(fa:fa-spinner);
B-->E(A fa:fa-camera-retro perhaps?);
```
```mermaid
graph TD graph TD
B["fa:fa-twitter for peace"] B["fa:fa-twitter for peace"]
B-->C[fa:fa-ban forbidden] B-->C[fa:fa-ban forbidden]
@ -875,15 +630,7 @@ graph TD
Below is the new declaration of the graph edges which is also valid along with the old declaration of the graph edges. Below is the new declaration of the graph edges which is also valid along with the old declaration of the graph edges.
``` ```mermaid-example
graph LR
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
```
```mermaid
graph LR graph LR
A[Hard edge] -->|Link text| B(Round edge) A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision} B --> C{Decision}

View File

@ -21,7 +21,7 @@ The json object that is passed as {**argument** } must be valid key value pairs
Valid Key Value pairs can be found in config. Valid Key Value pairs can be found in config.
The init/initialize directive is parsed earlier in the flow, this allows the incorporation of `%%init%%` directives into the mermaid diagram that is being rendered. Example: The init/initialize directive is parsed earlier in the flow, this allows the incorporation of `%%init%%` directives into the mermaid diagram that is being rendered. Example:
``` ```mmd
%%{init: { 'logLevel': 'debug', 'theme': 'dark' } }%% %%{init: { 'logLevel': 'debug', 'theme': 'dark' } }%%
graph > graph >
A-->B A-->B
@ -31,7 +31,7 @@ will set the `logLevel` to `debug` and the `theme` to `dark` for a flowchart dia
Note: 'init' or 'initialize' are both acceptable as init directives. Also note that `%%init%%` and `%%initialize%%` directives will be grouped together after they are parsed. This means: Note: 'init' or 'initialize' are both acceptable as init directives. Also note that `%%init%%` and `%%initialize%%` directives will be grouped together after they are parsed. This means:
``` ```mmd
%%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%% %%{init: { 'logLevel': 'debug', 'theme': 'forest' } }%%
%%{initialize: { 'logLevel': 'fatal', "theme":'dark', 'startOnLoad': true } }%% %%{initialize: { 'logLevel': 'fatal', "theme":'dark', 'startOnLoad': true } }%%
... ...
@ -39,7 +39,7 @@ Note: 'init' or 'initialize' are both acceptable as init directives. Also note t
parsing the above generates the `%%init%%` object below, combining the two directives and carrying over the last value given for `loglevel`: parsing the above generates the `%%init%%` object below, combining the two directives and carrying over the last value given for `loglevel`:
``` ```json5
{ {
logLevel: 'fatal', logLevel: 'fatal',
theme: 'dark', theme: 'dark',
@ -54,7 +54,7 @@ This will then be sent to `mermaid.initialize(...)` for rendering.
In this category are any directives that come after the graph type declaration. Essentially, these directives will only be processed after the init directive. Each individual graph type will handle these directives. As an example: In this category are any directives that come after the graph type declaration. Essentially, these directives will only be processed after the init directive. Each individual graph type will handle these directives. As an example:
``` ```mmd
%%{init: { 'logLevel': 'debug', 'theme': 'dark' } }%% %%{init: { 'logLevel': 'debug', 'theme': 'dark' } }%%
sequenceDiagram sequenceDiagram
%%{config: { 'fontFamily': 'Menlo', 'fontSize': 18, 'fontWeight': 400} }%% %%{config: { 'fontFamily': 'Menlo', 'fontSize': 18, 'fontWeight': 400} }%%

View File

@ -7,14 +7,7 @@ Note that practitioners of ER modelling almost always refer to *entity types* si
Mermaid can render ER diagrams Mermaid can render ER diagrams
```markdown ```mermaid-example
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
```
```mermaid
erDiagram erDiagram
CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains ORDER ||--|{ LINE-ITEM : contains
@ -27,27 +20,7 @@ Relationships between entities are represented by lines with end markers represe
ER diagrams can be used for various purposes, ranging from abstract logical models devoid of any implementation details, through to physical models of relational database tables. It can be useful to include attribute definitions on ER diagrams to aid comprehension of the purpose and meaning of entities. These do not necessarily need to be exhaustive; often a small subset of attributes is enough. Mermaid allows to be defined in terms of their *type* and *name*. ER diagrams can be used for various purposes, ranging from abstract logical models devoid of any implementation details, through to physical models of relational database tables. It can be useful to include attribute definitions on ER diagrams to aid comprehension of the purpose and meaning of entities. These do not necessarily need to be exhaustive; often a small subset of attributes is enough. Mermaid allows to be defined in terms of their *type* and *name*.
```markdown ```mermaid-example
erDiagram
CUSTOMER ||--o{ ORDER : places
CUSTOMER {
string name
string custNumber
string sector
}
ORDER ||--|{ LINE-ITEM : contains
ORDER {
int orderNumber
string deliveryAddress
}
LINE-ITEM {
string productCode
int quantity
float pricePerUnit
}
```
```mermaid
erDiagram erDiagram
CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ ORDER : places
CUSTOMER { CUSTOMER {
@ -75,7 +48,7 @@ When including attributes on ER diagrams, you must decide whether to include for
Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to label the relationship. Each statement consists of the following parts: Mermaid syntax for ER diagrams is compatible with PlantUML, with an extension to label the relationship. Each statement consists of the following parts:
```markdown ```
<first-entity> [<relationship> <second-entity> : <relationship-label>] <first-entity> [<relationship> <second-entity> : <relationship-label>]
``` ```
@ -88,7 +61,7 @@ Where:
For example: For example:
```markdown ```
PROPERTY ||--|{ ROOM : contains PROPERTY ||--|{ ROOM : contains
``` ```
@ -117,7 +90,8 @@ Cardinality is a property that describes how many elements of another entity can
Relationships may be classified as either *identifying* or *non-identifying* and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line: Relationships may be classified as either *identifying* or *non-identifying* and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line:
``` ```mmd
erDiagram
CAR ||--o{ NAMED-DRIVER : allows CAR ||--o{ NAMED-DRIVER : allows
PERSON ||--o{ NAMED-DRIVER : is PERSON ||--o{ NAMED-DRIVER : is
``` ```
@ -126,22 +100,7 @@ Relationships may be classified as either *identifying* or *non-identifying* and
Attributes can be defined for entities by specifying the entity name followed by a block containing multiple `type name` pairs, where a block is delimited by an opening `{` and a closing `}`. For example: Attributes can be defined for entities by specifying the entity name followed by a block containing multiple `type name` pairs, where a block is delimited by an opening `{` and a closing `}`. For example:
``` ```mermaid-example
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
}
```
```mermaid
erDiagram erDiagram
CAR ||--o{ NAMED-DRIVER : allows CAR ||--o{ NAMED-DRIVER : allows
CAR { CAR {
@ -158,22 +117,7 @@ erDiagram
``` ```
The attributes are rendered inside the entity boxes: The attributes are rendered inside the entity boxes:
``` ```mermaid-example
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
}
```
```mermaid
erDiagram erDiagram
CAR ||--o{ NAMED-DRIVER : allows CAR ||--o{ NAMED-DRIVER : allows
CAR { CAR {
@ -195,25 +139,7 @@ The `type` and `name` values must begin with an alphabetic character and may con
Attributes may also have a `key` or comment defined. Keys can be "PK" or "FK", for Primary Key or Foreign Key. And a `comment` is defined by quotes at the end of an attribute. Comments themselves cannot have quote characters in them. Attributes may also have a `key` or comment defined. Keys can be "PK" or "FK", for Primary Key or Foreign Key. And a `comment` is defined by quotes at the end of an attribute. Comments themselves cannot have quote characters in them.
``` ```mermaid-example
erDiagram
CAR ||--o{ NAMED-DRIVER : allows
CAR {
string allowedDriver FK 'The license of the allowed driver'
string registrationNumber
string make
string model
}
PERSON ||--o{ NAMED-DRIVER : is
PERSON {
string driversLicense PK 'The license #'
string firstName
string lastName
int age
}
```
```mermaid
erDiagram erDiagram
CAR ||--o{ NAMED-DRIVER : allows CAR ||--o{ NAMED-DRIVER : allows
CAR { CAR {

View File

@ -8,23 +8,12 @@ This page contains a collection of examples of diagrams and charts that can be c
## Basic Pie Chart ## Basic Pie Chart
``` ```mermaid-example
pie title NETFLIX pie title NETFLIX
"Time spent looking for movie" : 90 "Time spent looking for movie" : 90
"Time spent watching it" : 10 "Time spent watching it" : 10
``` ```
```mermaid ```mermaid-example
pie title NETFLIX
"Time spent looking for movie" : 90
"Time spent watching it" : 10
```
```
pie title What Voldemort doesn't have?
"FRIENDS" : 2
"FAMILY" : 3
"NOSE" : 45
```
```mermaid
pie title What Voldemort doesn't have? pie title What Voldemort doesn't have?
"FRIENDS" : 2 "FRIENDS" : 2
"FAMILY" : 3 "FAMILY" : 3
@ -32,18 +21,7 @@ pie title What Voldemort doesn't have?
``` ```
## Basic sequence diagram ## Basic sequence diagram
``` ```mermaid-example
sequenceDiagram
Alice ->> Bob: Hello Bob, how are you?
Bob-->>John: How about you John?
Bob--x Alice: I am good thanks!
Bob-x John: I am good thanks!
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
Bob-->Alice: Checking with John...
Alice->John: Yes... John, how are you?
```
```mermaid
sequenceDiagram sequenceDiagram
Alice ->> Bob: Hello Bob, how are you? Alice ->> Bob: Hello Bob, how are you?
Bob-->>John: How about you John? Bob-->>John: How about you John?
@ -57,14 +35,7 @@ sequenceDiagram
## Basic flowchart ## Basic flowchart
``` ```mermaid-example
graph LR
A[Square Rect] -- Link text --> B((Circle))
A --> C(Round Rect)
B --> D{Rhombus}
C --> D
```
```mermaid
graph LR graph LR
A[Square Rect] -- Link text --> B((Circle)) A[Square Rect] -- Link text --> B((Circle))
A --> C(Round Rect) A --> C(Round Rect)
@ -75,30 +46,7 @@ graph LR
## Larger flowchart with some styling ## Larger flowchart with some styling
``` ```mermaid-example
graph TB
sq[Square shape] --> ci((Circle shape))
subgraph A
od>Odd shape]-- Two line<br/>edge comment --> ro
di{Diamond with <br/> line break} -.-> ro(Rounded<br>square<br>shape)
di==>ro2(Rounded square shape)
end
%% Notice that no text in shape are added here instead that is appended further down
e --> od3>Really long text with linebreak<br>in an Odd shape]
%% Comments after double percent signs
e((Inner / circle<br>and some odd <br>special characters)) --> f(,.?!+-*ز)
cyr[Cyrillic]-->cyr2((Circle shape Начало));
classDef green fill:#9f6,stroke:#333,stroke-width:2px;
classDef orange fill:#f96,stroke:#333,stroke-width:4px;
class sq,e green
class di orange
```
```mermaid
graph TB graph TB
sq[Square shape] --> ci((Circle shape)) sq[Square shape] --> ci((Circle shape))
@ -125,22 +73,7 @@ graph TB
## SequenceDiagram: Loops, alt and opt ## SequenceDiagram: Loops, alt and opt
``` ```mermaid-example
sequenceDiagram
loop Daily query
Alice->>Bob: Hello Bob, how are you?
alt is sick
Bob->>Alice: Not so good :(
else is well
Bob->>Alice: Feeling fresh like a daisy
end
opt Extra response
Bob->>Alice: Thanks for asking
end
end
```
```mermaid
sequenceDiagram sequenceDiagram
loop Daily query loop Daily query
Alice->>Bob: Hello Bob, how are you? Alice->>Bob: Hello Bob, how are you?
@ -159,20 +92,7 @@ sequenceDiagram
## SequenceDiagram: Message to self in loop ## SequenceDiagram: Message to self in loop
``` ```mermaid-example
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts<br/>prevail...
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
```mermaid
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant Bob participant Bob

View File

@ -10,12 +10,7 @@ It can also accomodate different arrow types, multi directional arrows, and link
Node Node
### A node (default) ### A node (default)
``` ```mermaid-example
flowchart LR
id
```
```mermaid
flowchart LR flowchart LR
id id
``` ```
@ -28,11 +23,7 @@ It is also possible to set text in the box that differs from the id. If this is
found for the node that will be used. Also if you define edges for the node later on, you can omit text definitions. The found for the node that will be used. Also if you define edges for the node later on, you can omit text definitions. The
one previously defined will be used when rendering the box. one previously defined will be used when rendering the box.
``` ```mermaid-example
flowchart LR
id1[This is the text in the box]
```
```mermaid
flowchart LR flowchart LR
id1[This is the text in the box] id1[This is the text in the box]
``` ```
@ -43,22 +34,14 @@ This statement declares the direction of the Flowchart.
This declares the flowchart is oriented from top to bottom (`TD` or `TB`). This declares the flowchart is oriented from top to bottom (`TD` or `TB`).
``` ```mermaid-example
flowchart TD
Start --> Stop
```
```mermaid
flowchart TD flowchart TD
Start --> Stop Start --> Stop
``` ```
This declares the flowchart is oriented from left to right (`LR`). This declares the flowchart is oriented from left to right (`LR`).
``` ```mermaid-example
flowchart LR
Start --> Stop
```
```mermaid
flowchart LR flowchart LR
Start --> Stop Start --> Stop
``` ```
@ -77,66 +60,42 @@ Possible FlowChart orientations are:
### A node with round edges ### A node with round edges
``` ```mermaid-example
flowchart LR
id1(This is the text in the box)
```
```mermaid
flowchart LR flowchart LR
id1(This is the text in the box) id1(This is the text in the box)
``` ```
### A stadium-shaped node ### A stadium-shaped node
``` ```mermaid-example
flowchart LR
id1([This is the text in the box])
```
```mermaid
flowchart LR flowchart LR
id1([This is the text in the box]) id1([This is the text in the box])
``` ```
### A node in a subroutine shape ### A node in a subroutine shape
``` ```mermaid-example
flowchart LR
id1[[This is the text in the box]]
```
```mermaid
flowchart LR flowchart LR
id1[[This is the text in the box]] id1[[This is the text in the box]]
``` ```
### A node in a cylindrical shape ### A node in a cylindrical shape
``` ```mermaid-example
flowchart LR
id1[(Database)]
```
```mermaid
flowchart LR flowchart LR
id1[(Database)] id1[(Database)]
``` ```
### A node in the form of a circle ### A node in the form of a circle
``` ```mermaid-example
flowchart LR
id1((This is the text in the circle))
```
```mermaid
flowchart LR flowchart LR
id1((This is the text in the circle)) id1((This is the text in the circle))
``` ```
### A node in an asymmetric shape ### A node in an asymmetric shape
``` ```mermaid-example
flowchart LR
id1>This is the text in the box]
```
```mermaid
flowchart LR flowchart LR
id1>This is the text in the box] id1>This is the text in the box]
``` ```
@ -144,65 +103,40 @@ Currently only the shape above is possible and not its mirror. *This might chang
### A node (rhombus) ### A node (rhombus)
``` ```mermaid-example
flowchart LR
id1{This is the text in the box}
```
```mermaid
flowchart LR flowchart LR
id1{This is the text in the box} id1{This is the text in the box}
``` ```
### A hexagon node ### A hexagon node
``` ```mermaid-example
flowchart LR
id1{{This is the text in the box}}
```
```mermaid
flowchart LR flowchart LR
id1{{This is the text in the box}} id1{{This is the text in the box}}
``` ```
### Parallelogram ### Parallelogram
``` ```mermaid-example
flowchart TD
id1[/This is the text in the box/]
```
```mermaid
flowchart TD flowchart TD
id1[/This is the text in the box/] id1[/This is the text in the box/]
``` ```
### Parallelogram alt ### Parallelogram alt
``` ```mermaid-example
flowchart TD
id1[\This is the text in the box\]
```
```mermaid
flowchart TD flowchart TD
id1[\This is the text in the box\] id1[\This is the text in the box\]
``` ```
### Trapezoid ### Trapezoid
``` ```mermaid-example
flowchart TD
A[/Christmas\]
```
```mermaid
flowchart TD flowchart TD
A[/Christmas\] A[/Christmas\]
``` ```
### Trapezoid alt ### Trapezoid alt
``` ```mermaid-example
flowchart TD
B[\Go shopping/]
```
```mermaid
flowchart TD flowchart TD
B[\Go shopping/] B[\Go shopping/]
``` ```
@ -213,110 +147,70 @@ Nodes can be connected with links/edges. It is possible to have different types
### A link with arrow head ### A link with arrow head
``` ```mermaid-example
flowchart LR
A-->B
```
```mermaid
flowchart LR flowchart LR
A-->B A-->B
``` ```
### An open link ### An open link
``` ```mermaid-example
flowchart LR
A --- B
```
```mermaid
flowchart LR flowchart LR
A --- B A --- B
``` ```
### Text on links ### Text on links
``` ```mermaid-example
flowchart LR flowchart LR
A-- This is the text! ---B A-- This is the text! ---B
``` ```
```mermaid
flowchart LR
A-- This is the text ---B
```
or or
``` ```mermaid-example
flowchart LR
A---|This is the text|B
```
```mermaid
flowchart LR flowchart LR
A---|This is the text|B A---|This is the text|B
``` ```
### A link with arrow head and text ### A link with arrow head and text
``` ```mermaid-example
flowchart LR
A-->|text|B
```
```mermaid
flowchart LR flowchart LR
A-->|text|B A-->|text|B
``` ```
or or
``` ```mermaid-example
flowchart LR
A-- text -->B
```
```mermaid
flowchart LR flowchart LR
A-- text -->B A-- text -->B
``` ```
### Dotted link ### Dotted link
``` ```mermaid-example
flowchart LR;
A-.->B;
```
```mermaid
flowchart LR; flowchart LR;
A-.->B; A-.->B;
``` ```
### Dotted link with text ### Dotted link with text
``` ```mermaid-example
flowchart LR
A-. text .-> B
```
```mermaid
flowchart LR flowchart LR
A-. text .-> B A-. text .-> B
``` ```
### Thick link ### Thick link
``` ```mermaid-example
flowchart LR
A ==> B
```
```mermaid
flowchart LR flowchart LR
A ==> B A ==> B
``` ```
### Thick link with text ### Thick link with text
``` ```mermaid-example
flowchart LR
A == text ==> B
```
```mermaid
flowchart LR flowchart LR
A == text ==> B A == text ==> B
``` ```
@ -324,31 +218,19 @@ flowchart LR
### Chaining of links ### Chaining of links
It is possible declare many links in the same line as per below: It is possible declare many links in the same line as per below:
``` ```mermaid-example
flowchart LR
A -- text --> B -- text2 --> C
```
```mermaid
flowchart LR flowchart LR
A -- text --> B -- text2 --> C A -- text --> B -- text2 --> C
``` ```
It is also possible to declare multiple nodes links in the same line as per below: It is also possible to declare multiple nodes links in the same line as per below:
``` ```mermaid-example
flowchart LR
a --> b & c--> d
```
```mermaid
flowchart LR flowchart LR
a --> b & c--> d a --> b & c--> d
``` ```
You can then describe dependencies in a very expressive way. Like the one-liner below: You can then describe dependencies in a very expressive way. Like the one-liner below:
``` ```mermaid-example
flowchart TB
A & B--> C & D
```
```mermaid
flowchart TB flowchart TB
A & B--> C & D A & B--> C & D
``` ```
@ -356,7 +238,7 @@ If you describe the same diagram using the the basic syntax, it will take four l
word of warning, one could go overboard with this making the flowchart harder to read in word of warning, one could go overboard with this making the flowchart harder to read in
markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little. markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little.
This goes for expressive syntaxes as well. This goes for expressive syntaxes as well.
``` ```mmd
flowchart TB flowchart TB
A --> C A --> C
A --> D A --> D
@ -368,13 +250,7 @@ flowchart TB
There are new types of arrows supported as per below: There are new types of arrows supported as per below:
``` ```mermaid-example
flowchart LR
A --o B
B --x C
```
```mermaid
flowchart LR flowchart LR
A --o B A --o B
B --x C B --x C
@ -385,14 +261,7 @@ flowchart LR
There is the possibility to use multidirectional arrows. There is the possibility to use multidirectional arrows.
``` ```mermaid-example
flowchart LR
A o--o B
B <--> C
C x--x D
```
```mermaid
flowchart LR flowchart LR
A o--o B A o--o B
B <--> C B <--> C
@ -410,16 +279,7 @@ than the others by adding extra dashes in the link definition.
In the following example, two extra dashes are added in the link from node _B_ In the following example, two extra dashes are added in the link from node _B_
to node _E_, so that it spans two more ranks than regular links: to node _E_, so that it spans two more ranks than regular links:
``` ```mermaid-example
flowchart TD
A[Start] --> B{Is it?};
B -->|Yes| C[OK];
C --> D[Rethink];
D --> B;
B ---->|No| E[End];
```
```mermaid
flowchart TD flowchart TD
A[Start] --> B{Is it?}; A[Start] --> B{Is it?};
B -->|Yes| C[OK]; B -->|Yes| C[OK];
@ -435,7 +295,7 @@ When the link label is written in the middle of the link, the extra dashes must
be added on the right side of the link. The following example is equivalent to be added on the right side of the link. The following example is equivalent to
the previous one: the previous one:
``` ```mermaid-example
flowchart TD flowchart TD
A[Start] --> B{Is it?}; A[Start] --> B{Is it?};
B -- Yes --> C[OK]; B -- Yes --> C[OK];
@ -444,15 +304,6 @@ flowchart TD
B -- No ----> E[End]; B -- No ----> E[End];
``` ```
```mermaid
flowchart TD
A[Start] --> B{Is it?};
B -->|Yes| C[OK];
C --> D[Rethink];
D --> B;
B ---->|No| E[End];
```
For dotted or thick links, the characters to add are equals signs or dots, For dotted or thick links, the characters to add are equals signs or dots,
as summed up in the following table: as summed up in the following table:
@ -469,11 +320,7 @@ as summed up in the following table:
It is possible to put text within quotes in order to render more troublesome characters. As in the example below: It is possible to put text within quotes in order to render more troublesome characters. As in the example below:
``` ```mermaid-example
flowchart LR
id1["This is the (text) in the box"]
```
```mermaid
flowchart LR flowchart LR
id1["This is the (text) in the box"] id1["This is the (text) in the box"]
``` ```
@ -482,11 +329,7 @@ flowchart LR
It is possible to escape characters using the syntax exemplified here. It is possible to escape characters using the syntax exemplified here.
``` ```mermaid-example
flowchart LR
A["A double quote:#quot;"] -->B["A dec char:#9829;"]
```
```mermaid
flowchart LR flowchart LR
A["A double quote:#quot;"] -->B["A dec char:#9829;"] A["A double quote:#quot;"] -->B["A dec char:#9829;"]
``` ```
@ -503,20 +346,7 @@ end
An example below: An example below:
``` ```mermaid-example
flowchart TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end
```
```mermaid
flowchart TB flowchart TB
c1-->a2 c1-->a2
subgraph one subgraph one
@ -532,43 +362,19 @@ flowchart TB
You can also set an explicit id for the subgraph. You can also set an explicit id for the subgraph.
``` ```mermaid-example
flowchart TB flowchart TB
c1-->a2 c1-->a2
subgraph ide1 [one] subgraph ide1 [one]
a1-->a2 a1-->a2
end end
``` ```
```mermaid
flowchart TB
c1-->a2
subgraph id1 [one]
a1-->a2
end
```
## Beta: flowcharts ## Beta: flowcharts
With the graphtype flowcharts it is also possible to set edges to and from subgraphs as in the flowchart below. With the graphtype flowcharts it is also possible to set edges to and from subgraphs as in the flowchart below.
``` ```mermaid-example
flowchart TB
c1-->a2
subgraph one
a1-->a2
end
subgraph two
b1-->b2
end
subgraph three
c1-->c2
end
one --> two
three --> two
two --> c2
```
```mermaid
flowchart TB flowchart TB
c1-->a2 c1-->a2
subgraph one subgraph one
@ -589,7 +395,7 @@ flowchart TB
With the graphtype flowcharts you can use the direction statement to set the direction which the subgraph will render like in this example. With the graphtype flowcharts you can use the direction statement to set the direction which the subgraph will render like in this example.
``` ```mermaid-example
flowchart LR flowchart LR
subgraph TOP subgraph TOP
direction TB direction TB
@ -606,24 +412,6 @@ flowchart LR
B1 --> B2 B1 --> B2
``` ```
```mermaid
flowchart LR
subgraph TOP
direction TB
subgraph B1
direction RL
i1 -->f1
end
subgraph B2
direction BT
i2 -->f2
end
end
A --> TOP --> B
B1 --> B2
```
## Interaction ## Interaction
It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`. It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`.
@ -646,7 +434,9 @@ Examples of tooltip usage below:
</script> </script>
``` ```
``` The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class `.mermaidTooltip`.
```mermaid-example
flowchart LR; flowchart LR;
A-->B; A-->B;
B-->C; B-->C;
@ -657,36 +447,12 @@ flowchart LR;
click B href "http://www.github.com" "This is a tooltip for a link" click B href "http://www.github.com" "This is a tooltip for a link"
``` ```
The tooltip text is surrounded in double quotes. The styles of the tooltip are set by the class .mermaidTooltip.
```mermaid
flowchart LR
A-->B;
B-->C;
C-->D;
click A callback "Tooltip"
click B "http://www.github.com" "This is a link"
click C call callback() "Tooltip"
click D href "http://www.github.com" "This is a link"
```
> **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2. > **Success** The tooltip functionality and the ability to link to urls are available from version 0.5.2.
?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/). ?> Due to limitations with how Docsify handles JavaScript callback functions, an alternate working demo for the above code can be viewed at [this jsfiddle](https://jsfiddle.net/s37cjoau/3/).
Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported): Links are opened in the same browser tab/window by default. It is possible to change this by adding a link target to the click definition (`_self`, `_blank`, `_parent` and `_top` are supported):
``` ```mermaid-example
flowchart LR;
A-->B;
B-->C;
C-->D;
D-->E;
click A "http://www.github.com" _blank
click B "http://www.github.com" "Open this in a new tab" _blank
click C href "http://www.github.com" _blank
click D href "http://www.github.com" "Open this in a new tab" _blank
```
```mermaid
flowchart LR; flowchart LR;
A-->B; A-->B;
B-->C; B-->C;
@ -735,7 +501,7 @@ Beginners tip, a full example using interactive links in a html context:
Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax
``` ```mmd
flowchart LR flowchart LR
%% this is a comment A -- text --> B{node} %% this is a comment A -- text --> B{node}
A -- text --> B -- text2 --> C A -- text --> B -- text2 --> C
@ -759,13 +525,7 @@ linkStyle 3 stroke:#ff3,stroke-width:4px,color:red;
It is possible to apply specific styles such as a thicker border or a different background color to a node. It is possible to apply specific styles such as a thicker border or a different background color to a node.
``` ```mermaid-example
flowchart LR
id1(Start)-->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
```
```mermaid
flowchart LR flowchart LR
id1(Start)-->id2(Stop) id1(Start)-->id2(Stop)
style id1 fill:#f9f,stroke:#333,stroke-width:4px style id1 fill:#f9f,stroke:#333,stroke-width:4px
@ -799,12 +559,7 @@ It is also possible to attach a class to a list of nodes in one statement:
A shorter form of adding a class is to attach the classname to the node using the `:::`operator as per below: A shorter form of adding a class is to attach the classname to the node using the `:::`operator as per below:
``` ```mermaid-example
flowchart LR
A:::someclass --> B
classDef someclass fill:#f96;
```
```mermaid
flowchart LR flowchart LR
A:::someclass --> B A:::someclass --> B
classDef someclass fill:#f96; classDef someclass fill:#f96;
@ -830,13 +585,7 @@ below:
**Example definition** **Example definition**
``` ```mermaid-example
flowchart LR;
A-->B[AAA<span>BBB</span>];
B-->D;
class A cssClass;
```
```mermaid
flowchart LR; flowchart LR;
A-->B[AAA<span>BBB</span>]; A-->B[AAA<span>BBB</span>];
B-->D; B-->D;
@ -859,14 +608,7 @@ It is possible to add icons from fontawesome.
The icons are accessed via the syntax fa:#icon class name#. The icons are accessed via the syntax fa:#icon class name#.
``` ```mermaid-example
flowchart TD
B["fa:fa-twitter for peace"]
B-->C[fa:fa-ban forbidden]
B-->D(fa:fa-spinner);
B-->E(A fa:fa-camera-retro perhaps?);
```
```mermaid
flowchart TD flowchart TD
B["fa:fa-twitter for peace"] B["fa:fa-twitter for peace"]
B-->C[fa:fa-ban forbidden] B-->C[fa:fa-ban forbidden]
@ -883,15 +625,7 @@ flowchart TD
Below is the new declaration of the graph edges which is also valid along with the old declaration of the graph edges. Below is the new declaration of the graph edges which is also valid along with the old declaration of the graph edges.
``` ```mermaid-example
flowchart LR
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
```
```mermaid
flowchart LR flowchart LR
A[Hard edge] -->|Link text| B(Round edge) A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision} B --> C{Decision}

View File

@ -17,18 +17,7 @@
Mermaid can render Gantt diagrams as SVG, PNG or a MarkDown link that can be pasted into docs. Mermaid can render Gantt diagrams as SVG, PNG or a MarkDown link that can be pasted into docs.
``` ```mermaid-example
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
```
```mermaid
gantt gantt
title A Gantt Diagram title A Gantt Diagram
dateFormat YYYY-MM-DD dateFormat YYYY-MM-DD
@ -41,39 +30,7 @@ gantt
``` ```
## Syntax ## Syntax
``` ```mermaid-example
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
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
```
```mermaid
gantt gantt
dateFormat YYYY-MM-DD dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid title Adding GANTT diagram functionality to mermaid
@ -93,6 +50,7 @@ gantt
Future task in critical line :crit, 5d Future task in critical line :crit, 5d
Create tests for renderer :2d Create tests for renderer :2d
Add to mermaid :1d Add to mermaid :1d
Functionality added :milestone, 2014-01-25, 0d
section Documentation section Documentation
Describe gantt syntax :active, a1, after des1, 3d Describe gantt syntax :active, a1, after des1, 3d
@ -106,13 +64,7 @@ gantt
``` ```
It is possible to set multiple dependencies separated by space: It is possible to set multiple dependencies separated by space:
``` ```mermaid-example
gantt
apple :a, 2017-07-20, 1w
banana :crit, b, 2017-07-23, 1d
cherry :active, c, after b a, 1d
```
```
gantt gantt
apple :a, 2017-07-20, 1w apple :a, 2017-07-20, 1w
banana :crit, b, 2017-07-23, 1d banana :crit, b, 2017-07-23, 1d
@ -135,16 +87,7 @@ To do so, start a line with the `section` keyword and give it a name. (Note that
You can add milestones to the diagrams. Milestones differ from tasks as they represent a single instant in time and are identified by the keyword `milestone`. Below is an example on how to use milestones. As you may notice, the exact location of the milestone is determined by the initial date for the milestone and the "duration" of the task this way: *initial date*+*duration*/2. You can add milestones to the diagrams. Milestones differ from tasks as they represent a single instant in time and are identified by the keyword `milestone`. Below is an example on how to use milestones. As you may notice, the exact location of the milestone is determined by the initial date for the milestone and the "duration" of the task this way: *initial date*+*duration*/2.
``` ```mermaid-example
gantt
dateFormat HH:mm
axisFormat %H:%M
Initial milestone : milestone, m1, 17:49,2min
taska2 : 10min
taska3 : 5min
Final milestone : milestone, m2, 18:14, 2min
```
```mermaid
gantt gantt
dateFormat HH:mm dateFormat HH:mm
axisFormat %H:%M axisFormat %H:%M
@ -238,7 +181,7 @@ More info in: https://github.com/mbostock/d3/wiki/Time-Formatting
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
``` ```mmd
gantt gantt
title A Gantt Diagram title A Gantt Diagram
%% this is a comment %% this is a comment

View File

@ -22,6 +22,12 @@
} }
</script> </script>
<script>var require = { paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs' } }</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/loader.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.nls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.29.1/min/vs/editor/editor.main.js"></script>
<script>exports = {};</script>
<script src="https://unpkg.com/monaco-mermaid/browser.js"></script>
<style> <style>
.markdown-section { .markdown-section {
@ -32,6 +38,23 @@
<body> <body>
<div id="app"></div> <div id="app"></div>
<script> <script>
var initEditor = exports.default;
var parser = new DOMParser();
var currentCodeExample = 0;
var colorize = [];
function colorizeEverything(html) {
initEditor(monaco)
return new Promise((resolve, reject) => {
monaco.editor.setTheme('mermaid')
var parsed = parser.parseFromString(html, 'text/html').body
Promise.all([...parsed.querySelectorAll('pre[id*="code"]')].map(codeBlock => monaco.editor.colorize(codeBlock.innerText, 'mermaid'))).then(result => {
parsed.querySelectorAll('pre[id*="code"]').forEach((codeBlock, index) => codeBlock.innerHTML = result[index])
resolve(parsed.innerHTML)
})
})
}
window.$docsify = { window.$docsify = {
search: 'auto', search: 'auto',
name: 'mermaid', name: 'mermaid',
@ -43,10 +66,26 @@
markdown: { markdown: {
renderer: { renderer: {
code: function(code, lang) { code: function(code, lang) {
if (lang === "mermaid") { if (lang.startsWith('mermaid') || lang === 'mmd') {
return ( var resultingHTML = '';
'<div class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + "</div>"
); if (lang === "mmd" || lang === 'mermaid-example') {
currentCodeExample++;
colorize.push(currentCodeExample);
resultingHTML += (
'<pre id="code' + currentCodeExample + '">' + code + '</pre>'
)
}
if (lang === 'mermaid' || lang === 'mermaid-example') {
resultingHTML += (
'<div class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + "</div>"
);
}
if (resultingHTML !== '') {
return resultingHTML;
}
} }
return this.origin.code.apply(this, arguments); return this.origin.code.apply(this, arguments);
} }
@ -59,6 +98,14 @@
var editHtml = '[:memo: Edit this Page](' + url + ')\n' var editHtml = '[:memo: Edit this Page](' + url + ')\n'
return editHtml + html return editHtml + html
}) })
hook.afterEach(function (html, next) {
(async() => {
while (!window.hasOwnProperty("monaco"))
await new Promise(resolve => setTimeout(resolve, 1000));
colorizeEverything(html).then(newHTML => next(newHTML))
})();
})
} }
] ]
} }

View File

@ -152,6 +152,7 @@ They also serve as proof of concept, for the variety of things that can be built
| Mermaid Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil) | - | - | - | - | | Mermaid Diagrams | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil) | - | - | - | - |
|Mermaid Markdown | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-markdown/mboeoikjijmjcjgpccghbcoegikliijg) | - | - | - | - | |Mermaid Markdown | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-markdown/mboeoikjijmjcjgpccghbcoegikliijg) | - | - | - | - |
| Monkeys | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | - | - | - | - | | Monkeys | [🎡🔗](https://chrome.google.com/webstore/detail/monkeys-mermaid-for-githu/cplfdpoajbclbgphaphphcldamfkjlgi) | - | - | - | - |
| Mermaid Previewer | [🎡🔗](https://chrome.google.com/webstore/detail/mermaid-previewer/oidjnlhbegipkcklbdfnbkikplpghfdl) | - | - | - | - |
## Other ## Other

View File

@ -10,18 +10,7 @@ One would notice that all **Diagrams definitions begin** with a declaration of t
**Example** : The code below is for an Entity Relationship Diagram, specified by the `erDiagram` declaration. What follows is the definition of the different `Entities` represented in it. **Example** : The code below is for an Entity Relationship Diagram, specified by the `erDiagram` declaration. What follows is the definition of the different `Entities` represented in it.
``` ```mermaid-example
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
```
```mermaid
erDiagram erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ ORDER : places
@ -62,9 +51,10 @@ Configuration is the third part of Mermaid, after deployment and syntax. It deal
If you are interested in altering and customizing your Mermaid Diagrams, you will find the methods and values available for [Configuration](./Setup.md) here. It includes themes. If you are interested in altering and customizing your Mermaid Diagrams, you will find the methods and values available for [Configuration](./Setup.md) here. It includes themes.
This section will introduce the different methods of configuring the behaviors and appearances of Mermaid Diagrams. This section will introduce the different methods of configuring the behaviors and appearances of Mermaid Diagrams.
The following are the most commonly used methods, and they are all tied to Mermaid [Deployment](./n00b-gettingStarted.md) methods. The following are the most commonly used methods, and they are all tied to Mermaid [Deployment](./n00b-gettingStarted.md) methods.
### Configuration Section in the [Live Editor](https://mermaid-js.github.io/mermaid-live-editor).
### Configuration Section in the [Live Editor](./Live-Editor.md).
Here you can edit certain values to change the behavior and appearance of the diagram. Here you can edit certain values to change the behavior and appearance of the diagram.
### [The initialize() call](https://mermaid-js.github.io/mermaid/#/n00b-gettingStarted?id=_3-calling-the-javascript-api), ### [The initialize() call](https://mermaid-js.github.io/mermaid/#/n00b-gettingStarted?id=_3-calling-the-javascript-api),

View File

@ -17,7 +17,7 @@ For instance:
There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call a object provided to the parser by the user of the parser. This object can be called during parsing for storing data. There are some jison specific sub steps here where the parser stores the data encountered when parsing the diagram, this data is later used by the renderer. You can during the parsing call a object provided to the parser by the user of the parser. This object can be called during parsing for storing data.
``` ```jison
statement statement
: 'participant' actor { $$='actor'; } : 'participant' actor { $$='actor'; }
| signal { $$='signal'; } | signal { $$='signal'; }

View File

@ -5,18 +5,12 @@
Mermaid can render Pie Chart diagrams. Mermaid can render Pie Chart diagrams.
``` ```mermaid-example
pie title Pets adopted by volunteers pie title Pets adopted by volunteers
"Dogs" : 386 "Dogs" : 386
"Cats" : 85 "Cats" : 85
"Rats" : 15 "Rats" : 15
``` ```
```mermaid
pie title Pets adopted by volunteers
"Dogs" : 386
"Cats" : 85
"Rats" : 35
```
## Syntax ## Syntax
@ -37,7 +31,7 @@ Drawing a pie chart is really simple in mermaid.
. .
## Example ## Example
``` ```mermaid-example
pie pie
title Key elements in Product X title Key elements in Product X
"Calcium" : 42.96 "Calcium" : 42.96
@ -45,11 +39,3 @@ pie
"Magnesium" : 10.01 "Magnesium" : 10.01
"Iron" : 5 "Iron" : 5
``` ```
```mermaid
pie
title Key elements in Product X
"Calcium" : 42.96
"Potassium" : 50.05
"Magnesium" : 25.01
"Iron" : 15
```

View File

@ -6,24 +6,7 @@
Rendering requirements is straightforward. Rendering requirements is straightforward.
``` ```mermaid-example
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
element test_entity {
type: simulation
}
test_entity - satisfies -> test_req
```
```mermaid
requirementDiagram requirementDiagram
requirement test_req { requirement test_req {
@ -103,7 +86,7 @@ Each relationship is labeled in the diagram.
## Larger Example ## Larger Example
This example uses all features of the diagram. This example uses all features of the diagram.
```mermaid ```mermaid-example
requirementDiagram requirementDiagram
requirement test_req { requirement test_req {

View File

@ -5,20 +5,13 @@
Mermaid can render sequence diagrams. Mermaid can render sequence diagrams.
``` ```mermaid-example
sequenceDiagram sequenceDiagram
Alice->>John: Hello John, how are you? Alice->>John: Hello John, how are you?
John-->>Alice: Great! John-->>Alice: Great!
Alice-)John: See you later! Alice-)John: See you later!
``` ```
```mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
John-->>Alice: Great!
Alice--)John: See you later!
```
```note ```note
A note on nodes, the word "end" could potentially break the diagram, due to the way that the mermaid language is scripted. A note on nodes, the word "end" could potentially break the diagram, due to the way that the mermaid language is scripted.
@ -34,7 +27,7 @@ rendered in order of appearance in the diagram source text. Sometimes you might
different order than how they appear in the first message. It is possible to specify the actor's order of different order than how they appear in the first message. It is possible to specify the actor's order of
appearance by doing the following: appearance by doing the following:
``` ```mermaid-example
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant Bob participant Bob
@ -42,18 +35,10 @@ sequenceDiagram
Bob->>Alice: Hi Alice Bob->>Alice: Hi Alice
``` ```
```mermaid
sequenceDiagram
participant Alice
participant Bob
Alice->>Bob: Hi Bob
Bob->>Alice: Hi Alice
```
### Actors ### Actors
If you specifically want to use the actor symbol instead of a rectangle with text you can do so by using actor statements as per below. If you specifically want to use the actor symbol instead of a rectangle with text you can do so by using actor statements as per below.
``` ```mermaid-example
sequenceDiagram sequenceDiagram
actor Alice actor Alice
actor Bob actor Bob
@ -61,15 +46,7 @@ sequenceDiagram
Bob->>Alice: Hi Alice Bob->>Alice: Hi Alice
``` ```
```mermaid ```mermaid-example
sequenceDiagram
actor Alice
actor Bob
Alice->>Bob: Hi Bob
Bob->>Alice: Hi Alice
```
```
sequenceDiagram sequenceDiagram
actor Alice actor Alice
actor Bob actor Bob
@ -77,27 +54,11 @@ sequenceDiagram
Bob->>Alice: Hi Alice Bob->>Alice: Hi Alice
``` ```
```mermaid
sequenceDiagram
actor Alice
actor Bob
Alice->>Bob: Hi Bob
Bob->>Alice: Hi Alice
```
### Aliases ### Aliases
The actor can have a convenient identifier and a descriptive label. The actor can have a convenient identifier and a descriptive label.
``` ```mermaid-example
sequenceDiagram
participant A as Alice
participant J as John
A->>J: Hello John, how are you?
J->>A: Great!
```
```mermaid
sequenceDiagram sequenceDiagram
participant A as Alice participant A as Alice
participant J as John participant J as John
@ -130,15 +91,7 @@ There are six types of arrows currently supported:
It is possible to activate and deactivate an actor. (de)activation can be dedicated declarations: It is possible to activate and deactivate an actor. (de)activation can be dedicated declarations:
``` ```mermaid-example
sequenceDiagram
Alice->>John: Hello John, how are you?
activate John
John-->>Alice: Great!
deactivate John
```
```mermaid
sequenceDiagram sequenceDiagram
Alice->>John: Hello John, how are you? Alice->>John: Hello John, how are you?
activate John activate John
@ -148,13 +101,7 @@ sequenceDiagram
There is also a shortcut notation by appending `+`/`-` suffix to the message arrow: There is also a shortcut notation by appending `+`/`-` suffix to the message arrow:
``` ```mermaid-example
sequenceDiagram
Alice->>+John: Hello John, how are you?
John-->>-Alice: Great!
```
```mermaid
sequenceDiagram sequenceDiagram
Alice->>+John: Hello John, how are you? Alice->>+John: Hello John, how are you?
John-->>-Alice: Great! John-->>-Alice: Great!
@ -162,15 +109,7 @@ sequenceDiagram
Activations can be stacked for same actor: Activations can be stacked for same actor:
``` ```mermaid-example
sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
```
```mermaid
sequenceDiagram sequenceDiagram
Alice->>+John: Hello John, how are you? Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me? Alice->>+John: John, can you hear me?
@ -185,13 +124,7 @@ Note [ right of | left of | over ] [Actor]: Text in note content
See the example below: See the example below:
``` ```mermaid-example
sequenceDiagram
participant John
Note right of John: Text in note
```
```mermaid
sequenceDiagram sequenceDiagram
participant John participant John
Note right of John: Text in note Note right of John: Text in note
@ -199,13 +132,7 @@ sequenceDiagram
It is also possible to create notes spanning two participants: It is also possible to create notes spanning two participants:
``` ```mermaid-example
sequenceDiagram
Alice->John: Hello John, how are you?
Note over Alice,John: A typical interaction
```
```mermaid
sequenceDiagram sequenceDiagram
Alice->John: Hello John, how are you? Alice->John: Hello John, how are you?
Note over Alice,John: A typical interaction Note over Alice,John: A typical interaction
@ -223,15 +150,7 @@ end
See the example below: See the example below:
``` ```mermaid-example
sequenceDiagram
Alice->John: Hello John, how are you?
loop Every minute
John-->Alice: Great!
end
```
```mermaid
sequenceDiagram sequenceDiagram
Alice->John: Hello John, how are you? Alice->John: Hello John, how are you?
loop Every minute loop Every minute
@ -261,20 +180,7 @@ end
See the example below: See the example below:
``` ```mermaid-example
sequenceDiagram
Alice->>Bob: Hello Bob, how are you?
alt is sick
Bob->>Alice: Not so good :(
else is well
Bob->>Alice: Feeling fresh like a daisy
end
opt Extra response
Bob->>Alice: Thanks for asking
end
```
```mermaid
sequenceDiagram sequenceDiagram
Alice->>Bob: Hello Bob, how are you? Alice->>Bob: Hello Bob, how are you?
alt is sick alt is sick
@ -305,7 +211,7 @@ end
See the example below: See the example below:
```mermaid ```mermaid-example
sequenceDiagram sequenceDiagram
par Alice to Bob par Alice to Bob
Alice->>Bob: Hello guys! Alice->>Bob: Hello guys!
@ -318,7 +224,7 @@ sequenceDiagram
It is also possible to nest parallel blocks. It is also possible to nest parallel blocks.
```mermaid ```mermaid-example
sequenceDiagram sequenceDiagram
par Alice to Bob par Alice to Bob
Alice->>Bob: Go help John Alice->>Bob: Go help John
@ -352,7 +258,7 @@ end
See the examples below: See the examples below:
```mermaid ```mermaid-example
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant John participant John
@ -375,7 +281,7 @@ sequenceDiagram
Comments can be entered within a sequence diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax Comments can be entered within a sequence diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
``` ```mmd
sequenceDiagram sequenceDiagram
Alice->>John: Hello John, how are you? Alice->>John: Hello John, how are you?
%% this is a comment %% this is a comment
@ -386,12 +292,7 @@ sequenceDiagram
It is possible to escape characters using the syntax exemplified here. It is possible to escape characters using the syntax exemplified here.
``` ```mermaid-example
sequenceDiagram
A->>B: I #9829; you!
B->>A: I #9829; you #infin; times more!
```
```mermaid
sequenceDiagram sequenceDiagram
A->>B: I #9829; you! A->>B: I #9829; you!
B->>A: I #9829; you #infin; times more! B->>A: I #9829; you #infin; times more!
@ -405,7 +306,7 @@ Because semicolons can be used instead of line breaks to define the markup, you
It is possible to get a sequence number attached to each arrow in a sequence diagram. This can be configured when adding mermaid to the website as shown below: It is possible to get a sequence number attached to each arrow in a sequence diagram. This can be configured when adding mermaid to the website as shown below:
``` ```html
<script> <script>
mermaid.initialize({ mermaid.initialize({
sequence: { showSequenceNumbers: true }, sequence: { showSequenceNumbers: true },
@ -415,20 +316,7 @@ It is possible to get a sequence number attached to each arrow in a sequence dia
It can also be be turned on via the diagram code as in the diagram: It can also be be turned on via the diagram code as in the diagram:
``` ```mermaid-example
sequenceDiagram
autonumber
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
```mermaid
sequenceDiagram sequenceDiagram
autonumber autonumber
Alice->>John: Hello John, how are you? Alice->>John: Hello John, how are you?
@ -446,10 +334,10 @@ sequenceDiagram
Actors can have popup-menus containing individualized links to external pages. For example, if an actor represented a web service, useful links might include a link to the service health dashboard, repo containing the code for the service, or a wiki page describing the service. Actors can have popup-menus containing individualized links to external pages. For example, if an actor represented a web service, useful links might include a link to the service health dashboard, repo containing the code for the service, or a wiki page describing the service.
This can be configured by adding one or more link lines with the format: This can be configured by adding one or more link lines with the format:
link <actor>: <link-label> @ <link-url>
``` ```
link <actor>: <link-label> @ <link-url>
```
```mmd
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant John participant John
@ -467,11 +355,13 @@ There is an advanced syntax that relies on JSON formatting. If you are comfortab
This can be configured by adding the links lines with the format: This can be configured by adding the links lines with the format:
links <actor>: <json-formatted link-name link-url pairs> ```
links <actor>: <json-formatted link-name link-url pairs>
```
An example is below: An example is below:
``` ```mmd
sequenceDiagram sequenceDiagram
participant Alice participant Alice
participant John participant John

View File

@ -4,7 +4,7 @@
Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml. Mermaid can render state diagrams. The syntax tries to be compliant with the syntax used in plantUml as this will make it easier for users to share diagrams between mermaid and plantUml.
``` ```mermaid-example
stateDiagram-v2 stateDiagram-v2
[*] --> Still [*] --> Still
Still --> [*] Still --> [*]
@ -15,17 +15,9 @@ stateDiagram-v2
Crash --> [*] Crash --> [*]
``` ```
```mermaid Older renderer:
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving ```mermaid-example
Moving --> Still
Moving --> Crash
Crash --> [*]
```
```mermaid
stateDiagram stateDiagram
[*] --> Still [*] --> Still
Still --> [*] Still --> [*]
@ -42,36 +34,21 @@ In state diagrams systems are described in terms of its states and how the syste
A state can be declared in multiple ways. The simplest way is to define a state id as a description. A state can be declared in multiple ways. The simplest way is to define a state id as a description.
```markdown ```mermaid-example
stateDiagram-v2
s1
```
```mermaid
stateDiagram-v2 stateDiagram-v2
s1 s1
``` ```
Another way is by using the state keyword with a description as per below: Another way is by using the state keyword with a description as per below:
```markdown ```mermaid-example
stateDiagram-v2
state "This is a state description" as s2
```
```mermaid
stateDiagram-v2 stateDiagram-v2
state "This is a state description" as s2 state "This is a state description" as s2
``` ```
Another way to define a state with a description is to define the state id followed by a colon and the description: Another way to define a state with a description is to define the state id followed by a colon and the description:
```markdown ```mermaid-example
stateDiagram-v2
s2 : This is a state description
```
```mermaid
stateDiagram-v2 stateDiagram-v2
s2 : This is a state description s2 : This is a state description
``` ```
@ -82,24 +59,14 @@ Transitions are path/edges when one state passes into another. This is represent
When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way. When you define a transition between two states and the states are not already defined the undefined states are defined with the id from the transition. You can later add descriptions to states defined this way.
``` ```mermaid-example
stateDiagram-v2
s1 --> s2
```
```mermaid
stateDiagram-v2 stateDiagram-v2
s1 --> s2 s1 --> s2
``` ```
It is possible to add text to a transition. To describe what it represents. It is possible to add text to a transition. To describe what it represents.
``` ```mermaid-example
stateDiagram-v2
s1 --> s2: A transition
```
```mermaid
stateDiagram-v2 stateDiagram-v2
s1 --> s2: A transition s1 --> s2: A transition
``` ```
@ -108,13 +75,7 @@ stateDiagram-v2
There are two special states indicating the start and stop of the diagram. These are written with the [\*] syntax and the direction of the transition to it defines it either as a start or a stop state. There are two special states indicating the start and stop of the diagram. These are written with the [\*] syntax and the direction of the transition to it defines it either as a start or a stop state.
``` ```mermaid-example
stateDiagram-v2
[*] --> s1
s1 --> [*]
```
```mermaid
stateDiagram-v2 stateDiagram-v2
[*] --> s1 [*] --> s1
s1 --> [*] s1 --> [*]
@ -127,16 +88,7 @@ have several internal states. These are called composite states in this terminol
In order to define a composite state you need to use the state keyword followed by an id and the body of the composite state between \{\}. See the example below: In order to define a composite state you need to use the state keyword followed by an id and the body of the composite state between \{\}. See the example below:
``` ```mermaid-example
stateDiagram-v2
[*] --> First
state First {
[*] --> second
second --> [*]
}
```
```mermaid
stateDiagram-v2 stateDiagram-v2
[*] --> First [*] --> First
state First { state First {
@ -147,7 +99,7 @@ stateDiagram-v2
You can do this in several layers: You can do this in several layers:
``` ```mermaid-example
stateDiagram-v2 stateDiagram-v2
[*] --> First [*] --> First
@ -166,47 +118,9 @@ stateDiagram-v2
} }
``` ```
```mermaid
stateDiagram-v2
[*] --> First
state First {
[*] --> Second
state Second {
[*] --> second2
second2 --> Third
state Third {
[*] --> third
third --> [*]
}
}
}
```
You can also define transitions also between composite states: You can also define transitions also between composite states:
``` ```mermaid-example
stateDiagram-v2
[*] --> First
First --> Second
First --> Third
state First {
[*] --> fir
fir --> [*]
}
state Second {
[*] --> sec
sec --> [*]
}
state Third {
[*] --> thi
thi --> [*]
}
```
```mermaid
stateDiagram-v2 stateDiagram-v2
[*] --> First [*] --> First
First --> Second First --> Second
@ -232,16 +146,7 @@ stateDiagram-v2
Sometimes you need to model a choice between two or more paths, you can do so using &lt;&lt;choice&gt;&gt;. Sometimes you need to model a choice between two or more paths, you can do so using &lt;&lt;choice&gt;&gt;.
``` ```mermaid-example
stateDiagram-v2
state if_state <<choice>>
[*] --> IsPositive
IsPositive --> if_state
if_state --> False: if n < 0
if_state --> True : if n >= 0
```
```mermaid
stateDiagram-v2 stateDiagram-v2
state if_state <<choice>> state if_state <<choice>>
[*] --> IsPositive [*] --> IsPositive
@ -254,7 +159,7 @@ stateDiagram-v2
It is possible to specify a fork in the diagram using &lt;&lt;fork&gt;&gt; &lt;&lt;join&gt;&gt;. It is possible to specify a fork in the diagram using &lt;&lt;fork&gt;&gt; &lt;&lt;join&gt;&gt;.
``` ```mermaid-example
stateDiagram-v2 stateDiagram-v2
state fork_state <<fork>> state fork_state <<fork>>
[*] --> fork_state [*] --> fork_state
@ -268,28 +173,13 @@ It is possible to specify a fork in the diagram using &lt;&lt;fork&gt;&gt; &lt;&
State4 --> [*] State4 --> [*]
``` ```
```mermaid
stateDiagram-v2
state fork_state <<fork>>
[*] --> fork_state
fork_state --> State2
fork_state --> State3
state join_state <<join>>
State2 --> join_state
State3 --> join_state
join_state --> State4
State4 --> [*]
```
## Notes ## Notes
Sometimes nothing says it better then a Post-it note. That is also the case in state diagrams. Sometimes nothing says it better then a Post-it note. That is also the case in state diagrams.
Here you can choose to put the note to the *right of* or to the *left of* a node. Here you can choose to put the note to the *right of* or to the *left of* a node.
``` ```mermaid-example
stateDiagram-v2 stateDiagram-v2
State1: The state with a note State1: The state with a note
note right of State1 note right of State1
@ -300,42 +190,11 @@ Here you can choose to put the note to the *right of* or to the *left of* a node
note left of State2 : This is the note to the left. note left of State2 : This is the note to the left.
``` ```
```mermaid
stateDiagram-v2
State1: The state with a note
note right of State1
Important information! You can write
notes.
end note
State1 --> State2
note left of State2 : This is the note to the left.
```
## Concurrency ## Concurrency
As in plantUml you can specify concurrency using the -- symbol. As in plantUml you can specify concurrency using the -- symbol.
``` ```mermaid-example
stateDiagram-v2
[*] --> Active
state Active {
[*] --> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
--
[*] --> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
--
[*] --> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvScrollLockPressed
ScrollLockOn --> ScrollLockOff : EvScrollLockPressed
}
```
```mermaid
stateDiagram-v2 stateDiagram-v2
[*] --> Active [*] --> Active
@ -358,20 +217,7 @@ stateDiagram-v2
With state diagrams you can use the direction statement to set the direction which the diagram will render like in this example. With state diagrams you can use the direction statement to set the direction which the diagram will render like in this example.
``` ```mermaid-example
stateDiagram
direction LR
[*] --> A
A --> B
B --> C
state B {
direction LR
a --> b
}
B --> D
```
This is how this renders
```mermaid
stateDiagram stateDiagram
direction LR direction LR
[*] --> A [*] --> A
@ -389,7 +235,7 @@ stateDiagram
Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
``` ```mmd
stateDiagram-v2 stateDiagram-v2
[*] --> Still [*] --> Still
Still --> [*] Still --> [*]

View File

@ -12,7 +12,7 @@ Themes follow and build upon the Levels of Configuration and employ `directives`
Site-wide themes are still declared via `initialize` by site owners. Site-wide themes are still declared via `initialize` by site owners.
Example of `Initalize` call setting `theme` to `base`: Example of `Initalize` call setting `theme` to `base`:
``` ```javascript
mermaidAPI.initialize({ mermaidAPI.initialize({
'securityLevel': 'loose', 'theme': 'base' 'securityLevel': 'loose', 'theme': 'base'
}); });
@ -23,7 +23,7 @@ Example of `Initalize` call setting `theme` to `base`:
When Generating a diagram using on a webpage that supports mermaid. It is also possible to override site-wide theme settings locally, for a specific diagram, using directives, as long as it is not prohibited by the `secure` array. When Generating a diagram using on a webpage that supports mermaid. It is also possible to override site-wide theme settings locally, for a specific diagram, using directives, as long as it is not prohibited by the `secure` array.
``` ```mmd
%%{init: {'theme':'base'}}%% %%{init: {'theme':'base'}}%%
graph TD graph TD
a --> b a --> b
@ -32,7 +32,7 @@ When Generating a diagram using on a webpage that supports mermaid. It is also p
Here is an example of how `%%init%%` can set the theme to 'base', this assumes that `themeVariables` are set to default: Here is an example of how `%%init%%` can set the theme to 'base', this assumes that `themeVariables` are set to default:
```mermaid ```mermaid-example
%%{init: {'theme':'base'}}%% %%{init: {'theme':'base'}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
@ -61,7 +61,7 @@ The easiest way to make a custom theme is to start with the base theme, and just
## Here is an example of overriding `primaryColor` through `themeVariables` and giving everything a different look, using `%%init%%`. ## Here is an example of overriding `primaryColor` through `themeVariables` and giving everything a different look, using `%%init%%`.
``` ```mermaid-example
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%% %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
@ -79,24 +79,6 @@ The easiest way to make a custom theme is to start with the base theme, and just
end end
``` ```
```mermaid
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#00ff00'}}}%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
```
**Notes:** **Notes:**
Leaving it empty will set all variable values to default. Leaving it empty will set all variable values to default.
@ -204,26 +186,7 @@ Variables that are unique to some diagrams can be affected by changes in Theme V
# Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`. # Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`.
``` ```mermaid-example
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
```
```mermaid
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%% %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
@ -248,25 +211,7 @@ Variables that are unique to some diagrams can be affected by changes in Theme V
* make the edge label background differ from the subgraph by setting the edgeLabelBackground * make the edge label background differ from the subgraph by setting the edgeLabelBackground
``` ```mermaid-example
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ffcccc', 'edgeLabelBackground':'#ffffee', 'tertiaryColor': '#fff0f0'}}}%%
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[/Another/]
C ==>|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
```
```mermaid
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ffcccc', 'edgeLabelBackground':'#ffffee', 'tertiaryColor': '#fff0f0'}}}%% %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ffcccc', 'edgeLabelBackground':'#ffffee', 'tertiaryColor': '#fff0f0'}}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
@ -296,7 +241,7 @@ When adjusting a theme it might be helpful to look at how your preferred theme g
In the following examples, the directive `init` is used, with the `theme` being declared as `base`. For more information on using directives, read the documentation for [Version 8.6.0](/8.6.0_docs.md) In the following examples, the directive `init` is used, with the `theme` being declared as `base`. For more information on using directives, read the documentation for [Version 8.6.0](/8.6.0_docs.md)
### Flowchart ### Flowchart
``` ```mmd
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% %%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
graph TD graph TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
@ -332,24 +277,7 @@ In the following examples, the directive `init` is used, with the `theme` being
``` ```
### Flowchart (beta) ### Flowchart (beta)
``` ```mermaid-example
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
B --> G[Another]
C ==>|One| D[Laptop]
C x--x|Two| E[iPhone]
C o--o|Three| F[fa:fa-car Car]
subgraph section
C
D
E
F
G
end
```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% %%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
flowchart TD flowchart TD
A[Christmas] -->|Get money| B(Go shopping) A[Christmas] -->|Get money| B(Go shopping)
@ -368,25 +296,7 @@ In the following examples, the directive `init` is used, with the `theme` being
``` ```
### Sequence diagram ### Sequence diagram
``` ```mermaid-example
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
sequenceDiagram
autonumber
par Action 1
Alice->>John: Hello John, how are you?
and Action 2
Alice->>Bob: Hello Bob, how are you?
end
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
Note right of John: John is perceptive
John-->>-Alice: I feel great!
loop Every minute
John-->Alice: Great!
end
```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% %%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
sequenceDiagram sequenceDiagram
autonumber autonumber
@ -406,7 +316,7 @@ In the following examples, the directive `init` is used, with the `theme` being
``` ```
### Class diagram ### Class diagram
``` ```mermaid-example
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% %%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
classDiagram classDiagram
@ -431,65 +341,9 @@ classDiagram
+run() +run()
} }
``` ```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
classDiagram
Animal "1" <|-- Duck
Animal <|-- Fish
Animal <--o Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
```
### Gantt ### Gantt
``` ```mermaid-example
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid
excludes :excludes the named dates/days from being included in a charted task..
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
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
```
```mermaid
gantt gantt
dateFormat YYYY-MM-DD dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid title Adding GANTT diagram functionality to mermaid
@ -520,36 +374,7 @@ gantt
``` ```
### State diagram ### State diagram
``` ```mermaid-example
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
stateDiagram
[*] --> Active
state Active {
[*] --> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
--
[*] --> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
--
[*] --> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
}
state SomethingElse {
A --> B
B --> A
}
Active --> SomethingElse
note right of SomethingElse : This is the note to the right.
SomethingElse --> [*]
```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% %%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
stateDiagram stateDiagram
[*] --> Active [*] --> Active
@ -581,35 +406,7 @@ gantt
### State diagram (beta) ### State diagram (beta)
``` ```mermaid-example
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
stateDiagram-v2
[*] --> Active
state Active {
[*] --> NumLockOff
NumLockOff --> NumLockOn : EvNumLockPressed
NumLockOn --> NumLockOff : EvNumLockPressed
--
[*] --> CapsLockOff
CapsLockOff --> CapsLockOn : EvCapsLockPressed
CapsLockOn --> CapsLockOff : EvCapsLockPressed
--
[*] --> ScrollLockOff
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
}
state SomethingElse {
A --> B
B --> A
}
Active --> SomethingElse2
note right of SomethingElse2 : This is the note to the right.
SomethingElse2 --> [*]
```
```mermaid
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%% %%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
stateDiagram-v2 stateDiagram-v2
[*] --> Active [*] --> Active
@ -640,18 +437,7 @@ stateDiagram-v2
### Entity Relations diagram ### Entity Relations diagram
``` ```mermaid-example
erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places
CUSTOMER ||--o{ INVOICE : "liable for"
DELIVERY-ADDRESS ||--o{ ORDER : receives
INVOICE ||--|{ ORDER : covers
ORDER ||--|{ ORDER-ITEM : includes
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
```
```mermaid
erDiagram erDiagram
CUSTOMER }|..|{ DELIVERY-ADDRESS : has CUSTOMER }|..|{ DELIVERY-ADDRESS : has
CUSTOMER ||--o{ ORDER : places CUSTOMER ||--o{ ORDER : places
@ -664,19 +450,7 @@ stateDiagram-v2
``` ```
### User journey diagram ### User journey diagram
``` ```mermaid-example
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
```
```mermaid
journey journey
title My working day title My working day
section Go to work section Go to work

View File

@ -269,7 +269,7 @@ renderer.code = function (code, language) {
Another example in coffeescript that also includes the mermaid script tag in the generated markup. Another example in coffeescript that also includes the mermaid script tag in the generated markup.
```js ```coffee
marked = require 'marked' marked = require 'marked'
module.exports = (options) -> module.exports = (options) ->
@ -370,7 +370,7 @@ approach are:
* mermaid.startOnLoad * mermaid.startOnLoad
* mermaid.htmlLabels * mermaid.htmlLabels
```js ```javascript
mermaid.startOnLoad = true; mermaid.startOnLoad = true;
``` ```
@ -401,7 +401,7 @@ To set some configuration via the mermaid object. The two parameters that are su
* mermaid_config.startOnLoad * mermaid_config.startOnLoad
* mermaid_config.htmlLabels * mermaid_config.htmlLabels
``` ```javascript
mermaid_config.startOnLoad = true; mermaid_config.startOnLoad = true;
``` ```

View File

@ -4,18 +4,7 @@
Mermaid can render user journey diagrams: Mermaid can render user journey diagrams:
```markdown ```mermaid-example
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
```
```mermaid
journey journey
title My working day title My working day
section Go to work section Go to work

View File

@ -41,6 +41,7 @@ export const updateCurrentConfig = (siteCfg, _directives) => {
currentConfig = cfg; currentConfig = cfg;
return cfg; return cfg;
}; };
/** /**
* ## setSiteConfig * ## setSiteConfig
* *
@ -50,14 +51,11 @@ export const updateCurrentConfig = (siteCfg, _directives) => {
* *
* **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls * **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls
* to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig) * to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig)
* will reset siteConfig and current Config to the defaultConfig * will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this
* function *Default value: At default, will mirror Global Config**
* *
* Note: currentConfig is set in this function * @param conf - The base currentConfig to use as siteConfig
* * @returns {object} - The siteConfig
* Default value: At default, will mirror Global Config
*
* @param {any} conf - The base currentConfig to use as siteConfig
* @returns {any} - The siteConfig
*/ */
export const setSiteConfig = (conf) => { export const setSiteConfig = (conf) => {
siteConfig = assignWithDepth({}, defaultConfig); siteConfig = assignWithDepth({}, defaultConfig);
@ -84,13 +82,13 @@ export const updateSiteConfig = (conf) => {
/** /**
* ## getSiteConfig * ## getSiteConfig
* *
* | Function | Description | Type | Values | * | Function | Description | Type | Values |
* | ------------- | ------------------------------------------------- | ----------- | --------------------------------- | * | ------------- | ------------------------------------------------- | ----------- | -------------------------------- |
* | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in site Config | * | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig |
* *
* **Notes**: Returns **any** values in siteConfig. * **Notes**: Returns **any** values in siteConfig.
* *
* @returns {any} * @returns {object} - The siteConfig
*/ */
export const getSiteConfig = () => { export const getSiteConfig = () => {
return assignWithDepth({}, siteConfig); return assignWithDepth({}, siteConfig);
@ -185,6 +183,11 @@ export const sanitize = (options) => {
}); });
}; };
/**
* Pushes in a directive to the configuration
*
* @param {object} directive The directive to push in
*/
export const addDirective = (directive) => { export const addDirective = (directive) => {
if (directive.fontFamily) { if (directive.fontFamily) {
if (!directive.themeVariables) { if (!directive.themeVariables) {

View File

@ -26,8 +26,12 @@ const conf = {
/** /**
* Function that adds the vertices found during parsing to the graph to be rendered. * Function that adds the vertices found during parsing to the graph to be rendered.
* *
* @param classes * @param {Object<
* @param g The graph that is to be drawn. * string,
* { cssClasses: string[]; text: string; id: string; type: string; domId: string }
* >} classes
* Object containing the vertices.
* @param {SVGGElement} g The graph that is to be drawn.
*/ */
export const addClasses = function (classes, g) { export const addClasses = function (classes, g) {
// const svg = select(`[id="${svgId}"]`); // const svg = select(`[id="${svgId}"]`);
@ -210,7 +214,8 @@ export const addRelations = function (relations, g) {
edgeData.arrowheadStyle = 'fill: #333'; edgeData.arrowheadStyle = 'fill: #333';
edgeData.labelpos = 'c'; edgeData.labelpos = 'c';
if (getConfig().flowchart.htmlLabels) { // eslint-disable-line if (getConfig().flowchart.htmlLabels) {
// eslint-disable-line
edgeData.labelType = 'html'; edgeData.labelType = 'html';
edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>'; edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>';
} else { } else {
@ -229,19 +234,25 @@ export const addRelations = function (relations, g) {
}); });
}; };
// Todo optimize /**
* Gets the ID with the same label as in the cache
*
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
const getGraphId = function (label) { const getGraphId = function (label) {
const keys = Object.keys(idCache); const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label);
for (let i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/**
* Merges the value of `conf` with the passed `cnf`
*
* @param {object} cnf Config to merge
*/
export const setConf = function (cnf) { export const setConf = function (cnf) {
const keys = Object.keys(cnf); const keys = Object.keys(cnf);
@ -253,8 +264,8 @@ export const setConf = function (cnf) {
/** /**
* 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 text * @param {string} text
* @param id * @param {string} id
*/ */
export const drawOld = function (text, id) { export const drawOld = function (text, id) {
idCache = {}; idCache = {};
@ -502,11 +513,12 @@ export const draw = function (text, id) {
// }); // });
}; };
export default { /**
setConf, * Gets the arrow marker for a type index
draw, *
}; * @param {number} type The type to look for
/** @param type */ * @returns {'aggregation' | 'extension' | 'composition' | 'dependency'} The arrow marker
*/
function getArrowMarker(type) { function getArrowMarker(type) {
let marker; let marker;
switch (type) { switch (type) {
@ -527,3 +539,8 @@ function getArrowMarker(type) {
} }
return marker; return marker;
} }
export default {
setConf,
draw,
};

View File

@ -18,23 +18,24 @@ const conf = {
textHeight: 10, textHeight: 10,
}; };
// Todo optimize /**
* Gets the ID with the same label as in the cache
*
* @param {string} label The label to look for
* @returns {string} The resulting ID
*/
const getGraphId = function (label) { const getGraphId = function (label) {
const keys = Object.keys(idCache); const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label);
for (let i = 0; i < keys.length; i++) { if (foundEntry) {
if (idCache[keys[i]].label === label) { return foundEntry[0];
return keys[i];
}
} }
return undefined;
}; };
/** /**
* Setup arrow head and define the marker. The result is appended to the svg. * Setup arrow head and define the marker. The result is appended to the svg.
* *
* @param elem * @param {SVGSVGElement} elem The SVG element to append to
*/ */
const insertMarkers = function (elem) { const insertMarkers = function (elem) {
elem elem
@ -138,6 +139,11 @@ 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) { export const setConf = function (cnf) {
const keys = Object.keys(cnf); const keys = Object.keys(cnf);
@ -149,8 +155,8 @@ export const setConf = function (cnf) {
/** /**
* 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 text * @param {string} text
* @param id * @param {string} id
*/ */
export const draw = function (text, id) { export const draw = function (text, id) {
idCache = {}; idCache = {};

View File

@ -144,6 +144,11 @@ export const drawEdge = function (elem, path, relation, conf) {
edgeCount++; edgeCount++;
}; };
/**
* Renders a class diagram
* @param {SVGSVGElement} elem The element to draw it into
* @todo Add more information in the JSDOC here
*/
export const drawClass = function (elem, classDef, conf) { export const drawClass = function (elem, classDef, conf) {
log.info('Rendering class ' + classDef); log.info('Rendering class ' + classDef);
@ -382,6 +387,13 @@ const buildLegacyDisplay = function (text) {
}; };
}; };
/**
* Adds a <tspan> for a member in a diagram
* @param {SVGElement} textEl The element to append to
* @param {string} txt The member
* @param {boolean} isFirst
* @param {{ padding: string; textHeight: string; }} conf The configuration for the member
*/
const addTspan = function (textEl, txt, isFirst, conf) { const addTspan = function (textEl, txt, isFirst, conf) {
let member = parseMember(txt); let member = parseMember(txt);
@ -396,6 +408,14 @@ const addTspan = function (textEl, txt, isFirst, conf) {
} }
}; };
/**
* Makes generics in typescript syntax
* @example <caption>Array of array of strings in typescript syntax</caption>
* // returns "Array<Array<string>>"
* parseGenericTypes("Array~Array~string~~");
* @param {string} text The text to convert
* @returns {string} The converted string
*/
const parseGenericTypes = function (text) { const parseGenericTypes = function (text) {
let cleanedText = text; let cleanedText = text;
@ -409,6 +429,11 @@ const parseGenericTypes = function (text) {
} }
}; };
/**
* Gives the styles for a classifier
* @param {"+" | "-" | "#" | "~" | "*" | "$"} classifier The classifier string
* @returns {string} Styling for the classifier
*/
const parseClassifier = function (classifier) { const parseClassifier = function (classifier) {
switch (classifier) { switch (classifier) {
case '*': case '*':

View File

@ -1,5 +1,10 @@
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
/**
* Gets the number of lines in a string
* @param {string | undefined} s The string to check the lines for
* @returns {number} The number of lines in that string
*/
export const getRows = (s) => { export const getRows = (s) => {
if (!s) return 1; if (!s) return 1;
let str = breakToPlaceholder(s); let str = breakToPlaceholder(s);
@ -7,6 +12,11 @@ export const getRows = (s) => {
return str.split('#br#'); return str.split('#br#');
}; };
/**
* Removes script tags from a text
* @param {string} txt The text to sanitize
* @returns {string} The safer text
*/
export const removeScript = (txt) => { export const removeScript = (txt) => {
var rs = ''; var rs = '';
var idx = 0; var idx = 0;
@ -72,20 +82,47 @@ export const sanitizeText = (text, config) => {
export const lineBreakRegex = /<br\s*\/?>/gi; export const lineBreakRegex = /<br\s*\/?>/gi;
/**
* Whether or not a text has any linebreaks
* @param {string} text The text to test
* @returns {boolean} Whether or not the text has breaks
*/
export const hasBreaks = (text) => { export const hasBreaks = (text) => {
return /<br\s*[/]?>/gi.test(text); return lineBreakRegex.test(text);
}; };
/**
* Splits on <br> tags
* @param {string} text Text to split
* @returns {Array<string>} List of lines as strings
*/
export const splitBreaks = (text) => { export const splitBreaks = (text) => {
return text.split(/<br\s*[/]?>/gi); return text.split(lineBreakRegex);
}; };
/**
* Converts placeholders to linebreaks in HTML
* @param {string} s HTML with placeholders
* @returns {string} HTML with breaks instead of placeholders
*/
const placeholderToBreak = (s) => { const placeholderToBreak = (s) => {
return s.replace(/#br#/g, '<br/>'); return s.replace(/#br#/g, '<br/>');
}; };
/**
* Opposite of `placeholderToBreak`, converts breaks to placeholders
* @param {string} s HTML string
* @returns {string} String with placeholders
*/
const breakToPlaceholder = (s) => { const breakToPlaceholder = (s) => {
return s.replace(lineBreakRegex, '#br#'); return s.replace(lineBreakRegex, '#br#');
}; };
/**
* Gets the current URL
* @param {boolean} useAbsolute Whether to return the absolute URL or not
* @returns {string} The current URL
*/
const getUrl = (useAbsolute) => { const getUrl = (useAbsolute) => {
let url = ''; let url = '';
if (useAbsolute) { if (useAbsolute) {
@ -102,6 +139,11 @@ const getUrl = (useAbsolute) => {
return url; return url;
}; };
/**
* Converts a string/boolean into a boolean
* @param {string | boolean} val String or boolean to convert
* @returns {boolean} The result from the input
*/
export const evaluate = (val) => (val === 'false' || val === false ? false : true); export const evaluate = (val) => (val === 'false' || val === false ? false : true);
export default { export default {

View File

@ -1,3 +1,8 @@
/**
* Returns the styles given options
* @param {{ fontFamily: string; nodeTextColor: string; textColor: string; titleColor: string; mainBkg: string; nodeBorder: string; arrowheadColor: string; lineColor: string; edgeLabelBackground: string; clusterBkg: string; clusterBorder: string; tertiaryColor: string; border2: string; }} options The options for the styles
* @returns {string} The resulting styles
*/
const getStyles = (options) => const getStyles = (options) =>
`.label { `.label {
font-family: ${options.fontFamily}; font-family: ${options.fontFamily};
@ -69,9 +74,9 @@ const getStyles = (options) =>
.cluster span { .cluster span {
color: ${options.titleColor}; color: ${options.titleColor};
} }
// .cluster div { /* .cluster div {
// color: ${options.titleColor}; color: ${options.titleColor};
// } } */
div.mermaidTooltip { div.mermaidTooltip {
position: absolute; position: absolute;

View File

@ -3,6 +3,12 @@ import { select } from 'd3';
import { log } from './logger'; import { log } from './logger';
const conf = {}; const conf = {};
/**
* Merges the value of `conf` with the passed `cnf`
*
* @param {object} cnf Config to merge
*/
export const setConf = function (cnf) { export const setConf = function (cnf) {
const keys = Object.keys(cnf); const keys = Object.keys(cnf);
@ -14,8 +20,8 @@ export const setConf = function (cnf) {
/** /**
* 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} id * @param {string} id The text for the error
* @param {any} ver * @param {string} ver The version
*/ */
export const draw = (id, ver) => { export const draw = (id, ver) => {
try { try {

View File

@ -1,5 +1,12 @@
import moment from 'moment-mini'; import moment from 'moment-mini';
/**
* @typedef {"debug" | "info" | "warn" | "error" | "fatal"} LogLevel A log level
*/
/**
* @type {Object<LogLevel, number>}
*/
export const LEVELS = { export const LEVELS = {
debug: 1, debug: 1,
info: 2, info: 2,
@ -16,6 +23,10 @@ export const log = {
fatal: () => {}, fatal: () => {},
}; };
/**
* Sets a log level
* @param {LogLevel} [level="fatal"] The level to set the logging to
*/
export const setLogLevel = function (level = 'fatal') { export const setLogLevel = function (level = 'fatal') {
if (isNaN(level)) { if (isNaN(level)) {
level = level.toLowerCase(); level = level.toLowerCase();
@ -56,6 +67,11 @@ export const setLogLevel = function (level = 'fatal') {
} }
}; };
/**
* Returns a format with the timestamp and the log level
* @param {LogLevel} level The level for the log format
* @returns {string} The format with the timestamp and log level
*/
const format = (level) => { const format = (level) => {
const time = moment().format('ss.SSS'); const time = moment().format('ss.SSS');
return `%c${time} : ${level} : `; return `%c${time} : ${level} : `;

View File

@ -197,7 +197,7 @@ export const decodeEntities = function (text) {
/** /**
* Function that renders an svg with a graph from a chart definition. Usage example below. * Function that renders an svg with a graph from a chart definition. Usage example below.
* *
* ```js * ```javascript
* mermaidAPI.initialize({ * mermaidAPI.initialize({
* startOnLoad: true, * startOnLoad: true,
* }); * });

View File

@ -176,7 +176,11 @@ export const detectDirective = function (text, type = null) {
* g-->h * g-->h
* ``` * ```
* @param {string} text The text defining the graph * @param {string} text The text defining the graph
* @param {any} cnf * @param {{
* class: { defaultRenderer: string } | undefined;
* state: { defaultRenderer: string } | undefined;
* flowchart: { defaultRenderer: string } | undefined;
* }} [cnf]
* @returns {string} A graph definition key * @returns {string} A graph definition key
*/ */
export const detectType = function (text, cnf) { export const detectType = function (text, cnf) {
@ -236,6 +240,13 @@ export const detectType = function (text, cnf) {
return 'flowchart'; return 'flowchart';
}; };
/**
* Caches results of functions based on input
*
* @param {Function} fn Function to run
* @param {Function} resolver Function that resolves to an ID given arguments the `fn` takes
* @returns {Function} An optimized caching function
*/
const memoize = (fn, resolver) => { const memoize = (fn, resolver) => {
let cache = {}; let cache = {};
return (...args) => { return (...args) => {
@ -263,6 +274,13 @@ export const isSubstringInArray = function (str, arr) {
return -1; return -1;
}; };
/**
* Returns a d3 curve given a curve name
*
* @param {string | undefined} interpolate The interpolation name
* @param {any} defaultCurve The default curve to return
* @returns {import('d3-shape').CurveFactory} The curve factory to use
*/
export const interpolateToCurve = (interpolate, defaultCurve) => { export const interpolateToCurve = (interpolate, defaultCurve) => {
if (!interpolate) { if (!interpolate) {
return defaultCurve; return defaultCurve;
@ -271,6 +289,13 @@ export const interpolateToCurve = (interpolate, defaultCurve) => {
return d3CurveTypes[curveName] || defaultCurve; return d3CurveTypes[curveName] || defaultCurve;
}; };
/**
* Formats a URL string
*
* @param {string} linkStr String of the URL
* @param {{ securityLevel: string }} config Configuration passed to MermaidJS
* @returns {string | undefined} The formatted URL
*/
export const formatUrl = (linkStr, config) => { export const formatUrl = (linkStr, config) => {
let url = linkStr.trim(); let url = linkStr.trim();
@ -283,6 +308,12 @@ export const formatUrl = (linkStr, config) => {
} }
}; };
/**
* Runs a function
*
* @param {string} functionName A dot seperated path to the function relative to the `window`
* @param {...any} params Parameters to pass to the function
*/
export const runFunc = (functionName, ...params) => { export const runFunc = (functionName, ...params) => {
const arrPaths = functionName.split('.'); const arrPaths = functionName.split('.');
@ -298,9 +329,27 @@ export const runFunc = (functionName, ...params) => {
obj[fnName](...params); obj[fnName](...params);
}; };
/**
* @typedef {object} Point A (x, y) point
* @property {number} x The x value
* @property {number} y The y value
*/
/**
* Finds the distance between two points using the Distance Formula
*
* @param {Point} p1 The first point
* @param {Point} p2 The second point
* @returns {number} The distance
*/
const distance = (p1, p2) => const distance = (p1, p2) =>
p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0; p1 && p2 ? Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) : 0;
/**
* @param {Point[]} points List of points
* @returns {Point}
* @todo Give this a description
*/
const traverseEdge = (points) => { const traverseEdge = (points) => {
let prevPoint; let prevPoint;
let totalDistance = 0; let totalDistance = 0;
@ -338,6 +387,12 @@ const traverseEdge = (points) => {
return center; return center;
}; };
/**
* Alias for `traverseEdge`
*
* @param {Point[]} points List of points
* @returns {Point} Return result of `transverseEdge`
*/
const calcLabelPosition = (points) => { const calcLabelPosition = (points) => {
return traverseEdge(points); return traverseEdge(points);
}; };
@ -468,6 +523,12 @@ const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => {
return cardinalityPosition; return cardinalityPosition;
}; };
/**
* Gets styles from an array of declarations
*
* @param {string[]} arr Declarations
* @returns {{ style: string; labelStyle: string }} The styles grouped as strings
*/
export const getStylesFromArray = (arr) => { export const getStylesFromArray = (arr) => {
let style = ''; let style = '';
let labelStyle = ''; let labelStyle = '';
@ -518,19 +579,31 @@ export const random = (options) => {
* effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the * effectively merged with src[`k`]<p> Additionally, dissimilar types will not clobber unless the
* config.clobber parameter === true. Example: * config.clobber parameter === true. Example:
* *
* let config_0 = { foo: { bar: 'bar' }, bar: 'foo' }; * ```js
* let config_1 = { foo: 'foo', bar: 'bar' }; * let config_0 = { foo: { bar: 'bar' }, bar: 'foo' };
* let result = assignWithDepth(config_0, config_1); * let config_1 = { foo: 'foo', bar: 'bar' };
* console.log(result); * let result = assignWithDepth(config_0, config_1);
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }<p> * console.log(result);
* //-> result: { foo: { bar: 'bar' }, bar: 'bar' }
* ```
* *
* Traditional Object.assign would have clobbered foo in config_0 with foo in config_1.<p> If src is * Traditional Object.assign would have clobbered foo in config_0 with foo in config_1. If src is a
* a destructured array of objects and dst is not an array, assignWithDepth will apply each * destructured array of objects and dst is not an array, assignWithDepth will apply each element
* element of src to dst in order. * of src to dst in order.
* @param dst
* @param src
* @param config
* @param dst
* @param src
* @param config
* @param dst
* @param src
* @param config
* @param {any} dst - The destination of the merge * @param {any} dst - The destination of the merge
* @param {any} src - The source object(s) to merge into destination * @param {any} src - The source object(s) to merge into destination
* @param {{ depth: number; clobber: boolean }} config - Depth: depth to traverse within src and dst * @param {{ depth: number; clobber: boolean }} [config={ depth: 2, clobber: false }] - Depth: depth
* for merging - clobber: should dissimilar types clobber (default: { depth: 2, clobber: false }) * to traverse within src and dst for merging - clobber: should dissimilar types clobber (default:
* { depth: 2, clobber: false }). Default is `{ depth: 2, clobber: false }`
* @returns {any} * @returns {any}
*/ */
export const assignWithDepth = function (dst, src, config) { export const assignWithDepth = function (dst, src, config) {
@ -587,6 +660,24 @@ export const getTextObj = function () {
}; };
}; };
/**
* Adds text to an element
*
* @param {SVGElement} elem Element to add text to
* @param {{
* text: string;
* x: number;
* y: number;
* anchor: 'start' | 'middle' | 'end';
* fontFamily: string;
* fontSize: string | number;
* fontWeight: string | number;
* fill: string;
* class: string | undefined;
* textMargin: number;
* }} textData
* @returns {SVGTextElement} Text element with given styling and content
*/
export const drawSimpleText = function (elem, textData) { export const drawSimpleText = function (elem, textData) {
// Remove and ignore br:s // Remove and ignore br:s
const nText = textData.text.replace(common.lineBreakRegex, ' '); const nText = textData.text.replace(common.lineBreakRegex, ' ');
@ -777,12 +868,26 @@ export const calculateTextDimensions = memoize(
(text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}` (text, config) => `${text}-${config.fontSize}-${config.fontWeight}-${config.fontFamily}`
); );
/**
* Applys d3 attributes
*
* @param {any} d3Elem D3 Element to apply the attributes onto
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of attributes
*/
const d3Attrs = function (d3Elem, attrs) { const d3Attrs = function (d3Elem, attrs) {
for (let attr of attrs) { for (let attr of attrs) {
d3Elem.attr(attr[0], attr[1]); d3Elem.attr(attr[0], attr[1]);
} }
}; };
/**
* Gives attributes for an SVG's size given arguments
*
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
* @returns {Map<'height' | 'width' | 'style', string>} Attributes for the SVG
*/
export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) { export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) {
let attrs = new Map(); let attrs = new Map();
attrs.set('height', height); attrs.set('height', height);
@ -795,6 +900,14 @@ export const calculateSvgSizeAttrs = function (height, width, useMaxWidth) {
return attrs; return attrs;
}; };
/**
* Applies attributes from `calculateSvgSizeAttrs`
*
* @param {SVGSVGElement} svgElem The SVG Element to configure
* @param {number} height The height of the SVG
* @param {number} width The width of the SVG
* @param {boolean} useMaxWidth Whether or not to use max-width and set width to 100%
*/
export const configureSvgSize = function (svgElem, height, width, useMaxWidth) { export const configureSvgSize = function (svgElem, height, width, useMaxWidth) {
const attrs = calculateSvgSizeAttrs(height, width, useMaxWidth); const attrs = calculateSvgSizeAttrs(height, width, useMaxWidth);
d3Attrs(svgElem, attrs); d3Attrs(svgElem, attrs);
@ -815,8 +928,14 @@ export const initIdGeneratior = class iterator {
} }
}; };
// Source https://github.com/shrpne/entity-decode/blob/master/browser.js
let decoder; let decoder;
/**
* Decodes HTML, source: {@link https://github.com/shrpne/entity-decode/blob/v2.0.1/browser.js}
*
* @param {string} html HTML as a string
* @returns Unescaped HTML
*/
export const entityDecode = function (html) { export const entityDecode = function (html) {
decoder = decoder || document.createElement('div'); decoder = decoder || document.createElement('div');
// Escape HTML before decoding for HTML Entities // Escape HTML before decoding for HTML Entities
@ -826,6 +945,11 @@ export const entityDecode = function (html) {
return unescape(decoder.textContent); return unescape(decoder.textContent);
}; };
/**
* Sanitizes directive objects
*
* @param {object} args Directive's JSON
*/
export const directiveSanitizer = (args) => { export const directiveSanitizer = (args) => {
log.debug('directiveSanitizer called with', args); log.debug('directiveSanitizer called with', args);
if (typeof args === 'object') { if (typeof args === 'object') {