2015-07-17 23:13:40 +02:00
|
|
|
/**
|
|
|
|
* This is the api to be used when handling the integration with the web page instead of using the default integration
|
|
|
|
* (mermaid.js).
|
|
|
|
*
|
|
|
|
* The core of this api is the **render** function that given a graph definitionas text renders the graph/diagram and
|
|
|
|
* returns a svg element for the graph. It is is then up to the user of the API to make use of the svg, either insert it
|
|
|
|
* somewhere in the page or something completely different.
|
2019-07-14 06:07:27 -07:00
|
|
|
* @name mermaidAPI
|
2017-09-10 00:29:22 +08:00
|
|
|
*/
|
2018-03-08 21:42:39 +08:00
|
|
|
import * as d3 from 'd3'
|
2018-03-11 21:36:59 +08:00
|
|
|
import scope from 'scope-css'
|
2019-06-15 14:29:26 +02:00
|
|
|
import pkg from '../package.json'
|
2019-07-21 02:09:22 -07:00
|
|
|
import { setConfig, getConfig } from './config'
|
2017-09-10 19:41:34 +08:00
|
|
|
import { logger, setLogLevel } from './logger'
|
|
|
|
import utils from './utils'
|
|
|
|
import flowRenderer from './diagrams/flowchart/flowRenderer'
|
|
|
|
import flowParser from './diagrams/flowchart/parser/flow'
|
2018-03-13 15:28:48 +08:00
|
|
|
import flowDb from './diagrams/flowchart/flowDb'
|
|
|
|
import sequenceRenderer from './diagrams/sequence/sequenceRenderer'
|
|
|
|
import sequenceParser from './diagrams/sequence/parser/sequenceDiagram'
|
|
|
|
import sequenceDb from './diagrams/sequence/sequenceDb'
|
2018-03-12 21:06:49 +08:00
|
|
|
import ganttRenderer from './diagrams/gantt/ganttRenderer'
|
2017-09-10 19:41:34 +08:00
|
|
|
import ganttParser from './diagrams/gantt/parser/gantt'
|
|
|
|
import ganttDb from './diagrams/gantt/ganttDb'
|
2018-03-13 15:28:48 +08:00
|
|
|
import classRenderer from './diagrams/class/classRenderer'
|
|
|
|
import classParser from './diagrams/class/parser/classDiagram'
|
|
|
|
import classDb from './diagrams/class/classDb'
|
|
|
|
import gitGraphRenderer from './diagrams/git/gitGraphRenderer'
|
|
|
|
import gitGraphParser from './diagrams/git/parser/gitGraph'
|
|
|
|
import gitGraphAst from './diagrams/git/gitGraphAst'
|
2019-06-15 14:29:26 +02:00
|
|
|
import infoRenderer from './diagrams/info/infoRenderer'
|
|
|
|
import infoParser from './diagrams/info/parser/info'
|
|
|
|
import infoDb from './diagrams/info/infoDb'
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2018-03-13 14:31:56 +08:00
|
|
|
const themes = {}
|
|
|
|
for (const themeName of ['default', 'forest', 'dark', 'neutral']) {
|
|
|
|
themes[themeName] = require(`./themes/${themeName}/index.scss`)
|
2017-09-12 22:54:50 +08:00
|
|
|
}
|
2017-09-12 22:06:19 +08:00
|
|
|
|
2015-06-20 20:58:58 +02:00
|
|
|
/**
|
2015-07-17 23:13:40 +02:00
|
|
|
* These are the default options which can be overridden with the initialization call as in the example below:
|
|
|
|
* ```
|
|
|
|
* mermaid.initialize({
|
|
|
|
* flowchart:{
|
|
|
|
* htmlLabels: false
|
|
|
|
* }
|
|
|
|
* });
|
|
|
|
* ```
|
2019-07-14 06:07:27 -07:00
|
|
|
* @name Configuration
|
2015-06-20 20:58:58 +02:00
|
|
|
*/
|
2017-09-14 19:40:38 +08:00
|
|
|
const config = {
|
2018-07-15 19:04:42 +02:00
|
|
|
|
2018-12-18 13:32:36 +08:00
|
|
|
/** theme , the CSS style sheet
|
2018-07-15 19:04:42 +02:00
|
|
|
*
|
|
|
|
* **theme** - Choose one of the built-in themes: default, forest, dark or neutral. To disable any pre-defined mermaid theme, use "null".
|
|
|
|
* **themeCSS** - Use your own CSS. This overrides **theme**.
|
|
|
|
*```
|
|
|
|
* "theme": "forest",
|
|
|
|
* "themeCSS": ".node rect { fill: red; }"
|
|
|
|
*```
|
|
|
|
*/
|
|
|
|
|
2018-03-15 21:22:49 +08:00
|
|
|
theme: 'default',
|
2018-03-15 21:47:53 +08:00
|
|
|
themeCSS: undefined,
|
2017-09-12 22:54:50 +08:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* This option decides the amount of logging to be used.
|
2017-04-16 23:24:47 +08:00
|
|
|
* * debug: 1
|
|
|
|
* * info: 2
|
|
|
|
* * warn: 3
|
|
|
|
* * error: 4
|
2019-07-14 06:07:27 -07:00
|
|
|
* * fatal: (**default**) 5
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
logLevel: 5,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2019-07-13 22:50:53 -07:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Sets the level of trust to be used on the parsed diagrams.
|
|
|
|
* * **true**: (**default**) tags in text are encoded, click functionality is disabeled
|
|
|
|
* * **false**: tags in text are allowed, click functionality is enabled
|
2019-07-13 22:50:53 -07:00
|
|
|
*/
|
2019-07-14 06:07:27 -07:00
|
|
|
securityLevel: 'strict',
|
2019-07-13 22:50:53 -07:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* This options controls whether or mermaid starts when the page loads
|
|
|
|
* **Default value true**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
startOnLoad: true,
|
2015-09-26 12:09:47 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* This options controls whether or arrow markers in html code will be absolute paths or
|
2017-04-16 23:24:47 +08:00
|
|
|
* an anchor, #. This matters if you are using base tag settings.
|
2019-07-14 06:07:27 -07:00
|
|
|
* **Default value false**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
arrowMarkerAbsolute: false,
|
2015-11-21 11:51:15 +01:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* The object containing configurations specific for flowcharts
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
|
|
|
flowchart: {
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Flag for setting whether or not a html tag should be used for rendering labels
|
|
|
|
* on the edges.
|
|
|
|
* **Default value true**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
htmlLabels: true,
|
2018-03-17 23:05:14 +08:00
|
|
|
|
2019-07-14 06:07:27 -07:00
|
|
|
/**
|
2019-08-20 20:07:12 +02:00
|
|
|
* How mermaid renders curves for flowcharts. Possibel values are basis, linear and cardinal. **Default value linear**.
|
2019-07-14 06:07:27 -07:00
|
|
|
*/
|
2018-03-17 23:05:14 +08:00
|
|
|
curve: 'linear'
|
2017-04-11 22:14:25 +08:00
|
|
|
},
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* The object containing configurations specific for sequence diagrams
|
|
|
|
*/
|
2018-03-12 21:16:22 +08:00
|
|
|
sequence: {
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* margin to the right and left of the sequence diagram
|
|
|
|
* **Default value 50**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
diagramMarginX: 50,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* margin to the over and under the sequence diagram.
|
|
|
|
* **Default value 10**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
diagramMarginY: 10,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Margin between actors.
|
|
|
|
* **Default value 50**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
actorMargin: 50,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Width of actor boxes
|
|
|
|
* **Default value 150**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
width: 150,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Height of actor boxes
|
|
|
|
* **Default value 65**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
height: 65,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Margin around loop boxes
|
|
|
|
* **Default value 10**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
boxMargin: 10,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* margin around the text in loop/alt/opt boxes
|
|
|
|
* **Default value 5**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
boxTextMargin: 5,
|
2015-05-30 17:20:24 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* margin around notes.
|
|
|
|
* **Default value 10**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
noteMargin: 10,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Space between messages.
|
|
|
|
* **Default value 35**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
messageMargin: 35,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* mirror actors under diagram.
|
|
|
|
* **Default value true**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
mirrorActors: true,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Depending on css styling this might need adjustment.
|
|
|
|
* Prolongs the edge of the diagram downwards.
|
|
|
|
* **Default value 1**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
bottomMarginAdj: 1,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* when this flag is set the height and width is set to 100% and is then scaling with the
|
|
|
|
* available space if not the absolute space required is used.
|
|
|
|
* **Default value true**.
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2018-08-17 10:56:15 -04:00
|
|
|
useMaxWidth: true,
|
|
|
|
|
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* This will display arrows that start and begin at the same node as right angles, rather than a curve
|
|
|
|
* **Default value false**.
|
2018-08-17 10:56:15 -04:00
|
|
|
*/
|
2019-06-30 16:14:59 +02:00
|
|
|
rightAngles: false,
|
2018-08-16 13:44:59 -04:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* This will show the node numbers
|
|
|
|
* **Default value false**.
|
2018-08-16 13:44:59 -04:00
|
|
|
*/
|
|
|
|
showSequenceNumbers: false
|
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
},
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2019-07-14 06:07:27 -07:00
|
|
|
/**
|
2017-04-16 23:24:47 +08:00
|
|
|
* The object containing configurations specific for gantt diagrams*
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
gantt: {
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Margin top for the text over the gantt diagram
|
|
|
|
* **Default value 25**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
titleTopMargin: 25,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* The height of the bars in the graph
|
|
|
|
* **Default value 20**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
barHeight: 20,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* The margin between the different activities in the gantt diagram.
|
|
|
|
* **Default value 4**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
barGap: 4,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Margin between title and gantt diagram and between axis and gantt diagram.
|
|
|
|
* **Default value 50**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
topPadding: 50,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* The space allocated for the section name to the left of the activities.
|
|
|
|
* **Default value 75**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
leftPadding: 75,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Vertical starting position of the grid lines.
|
|
|
|
* **Default value 35**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
gridLineStartPadding: 35,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Font size ...
|
|
|
|
* **Default value 11**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
fontSize: 11,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* font family ...
|
|
|
|
* **Default value '"Open-Sans", "sans-serif"'**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
fontFamily: '"Open-Sans", "sans-serif"',
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* The number of alternating section styles.
|
|
|
|
* **Default value 4**.
|
2017-04-16 23:24:47 +08:00
|
|
|
*/
|
2018-03-13 21:17:32 +08:00
|
|
|
numberSectionStyles: 4,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
2019-07-14 06:07:27 -07:00
|
|
|
* Datetime format of the axis, this might need adjustment to match your locale and preferences
|
|
|
|
* **Default value '%Y-%m-%d'**.
|
2018-03-12 21:33:02 +08:00
|
|
|
*/
|
|
|
|
axisFormat: '%Y-%m-%d'
|
2017-04-11 22:14:25 +08:00
|
|
|
},
|
2018-03-12 21:16:22 +08:00
|
|
|
class: {},
|
2018-03-13 15:19:24 +08:00
|
|
|
git: {}
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
|
|
|
|
2017-09-10 19:41:34 +08:00
|
|
|
setLogLevel(config.logLevel)
|
2019-07-13 22:50:53 -07:00
|
|
|
setConfig(config)
|
2015-10-04 19:30:53 +02:00
|
|
|
|
2017-09-10 10:45:38 +08:00
|
|
|
function parse (text) {
|
2017-09-14 19:40:38 +08:00
|
|
|
const graphType = utils.detectType(text)
|
|
|
|
let parser
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2019-06-15 14:29:26 +02:00
|
|
|
logger.debug('Type ' + graphType)
|
2017-04-11 22:14:25 +08:00
|
|
|
switch (graphType) {
|
2018-03-12 21:16:22 +08:00
|
|
|
case 'git':
|
2017-04-11 22:14:25 +08:00
|
|
|
parser = gitGraphParser
|
|
|
|
parser.parser.yy = gitGraphAst
|
|
|
|
break
|
2018-03-12 21:06:49 +08:00
|
|
|
case 'flowchart':
|
2017-04-11 22:14:25 +08:00
|
|
|
parser = flowParser
|
2018-03-12 20:52:06 +08:00
|
|
|
parser.parser.yy = flowDb
|
2017-04-11 22:14:25 +08:00
|
|
|
break
|
2018-03-12 21:16:22 +08:00
|
|
|
case 'sequence':
|
2017-04-11 22:14:25 +08:00
|
|
|
parser = sequenceParser
|
|
|
|
parser.parser.yy = sequenceDb
|
|
|
|
break
|
|
|
|
case 'gantt':
|
|
|
|
parser = ganttParser
|
|
|
|
parser.parser.yy = ganttDb
|
|
|
|
break
|
2018-03-12 21:16:22 +08:00
|
|
|
case 'class':
|
2017-04-11 22:14:25 +08:00
|
|
|
parser = classParser
|
|
|
|
parser.parser.yy = classDb
|
|
|
|
break
|
2019-06-15 14:29:26 +02:00
|
|
|
case 'info':
|
|
|
|
logger.debug('info info info')
|
2019-08-20 20:07:12 +02:00
|
|
|
console.warn('In API', pkg.version)
|
|
|
|
|
2019-06-15 14:29:26 +02:00
|
|
|
parser = infoParser
|
|
|
|
parser.parser.yy = infoDb
|
|
|
|
break
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
|
|
|
|
2017-09-10 10:10:36 +08:00
|
|
|
parser.parser.yy.parseError = (str, hash) => {
|
|
|
|
const error = { str, hash }
|
|
|
|
throw error
|
2017-09-10 00:29:22 +08:00
|
|
|
}
|
|
|
|
|
2017-09-10 10:10:36 +08:00
|
|
|
parser.parse(text)
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
2015-05-26 20:59:23 +02:00
|
|
|
|
2017-09-10 21:23:04 +08:00
|
|
|
export const encodeEntities = function (text) {
|
2017-09-14 19:40:38 +08:00
|
|
|
let txt = text
|
2017-04-11 22:14:25 +08:00
|
|
|
|
|
|
|
txt = txt.replace(/style.*:\S*#.*;/g, function (s) {
|
2017-09-14 19:40:38 +08:00
|
|
|
const innerTxt = s.substring(0, s.length - 1)
|
2017-04-11 22:14:25 +08:00
|
|
|
return innerTxt
|
|
|
|
})
|
|
|
|
txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) {
|
2017-09-14 19:40:38 +08:00
|
|
|
const innerTxt = s.substring(0, s.length - 1)
|
2017-04-11 22:14:25 +08:00
|
|
|
return innerTxt
|
|
|
|
})
|
|
|
|
|
2017-04-11 23:31:59 +08:00
|
|
|
txt = txt.replace(/#\w+;/g, function (s) {
|
2017-09-14 19:40:38 +08:00
|
|
|
const innerTxt = s.substring(1, s.length - 1)
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2017-09-14 19:40:38 +08:00
|
|
|
const isInt = /^\+?\d+$/.test(innerTxt)
|
2017-04-11 22:14:25 +08:00
|
|
|
if (isInt) {
|
|
|
|
return 'fl°°' + innerTxt + '¶ß'
|
|
|
|
} else {
|
|
|
|
return 'fl°' + innerTxt + '¶ß'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return txt
|
|
|
|
}
|
|
|
|
|
2017-09-10 21:23:04 +08:00
|
|
|
export const decodeEntities = function (text) {
|
2017-09-14 19:40:38 +08:00
|
|
|
let txt = text
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2017-04-11 23:31:59 +08:00
|
|
|
txt = txt.replace(/fl°°/g, function () {
|
2017-04-11 22:14:25 +08:00
|
|
|
return '&#'
|
|
|
|
})
|
2017-04-11 23:31:59 +08:00
|
|
|
txt = txt.replace(/fl°/g, function () {
|
2017-04-11 22:14:25 +08:00
|
|
|
return '&'
|
|
|
|
})
|
|
|
|
txt = txt.replace(/¶ß/g, function () {
|
|
|
|
return ';'
|
|
|
|
})
|
|
|
|
|
|
|
|
return txt
|
|
|
|
}
|
2015-07-15 11:39:46 +02:00
|
|
|
/**
|
2015-07-17 23:13:40 +02:00
|
|
|
* Function that renders an svg with a graph from a chart definition. Usage example below.
|
|
|
|
*
|
2019-07-14 06:07:27 -07:00
|
|
|
* ```js
|
2015-07-17 23:13:40 +02:00
|
|
|
* mermaidAPI.initialize({
|
|
|
|
* startOnLoad:true
|
|
|
|
* });
|
|
|
|
* $(function(){
|
2017-09-14 19:40:38 +08:00
|
|
|
* const graphDefinition = 'graph TB\na-->b';
|
|
|
|
* const cb = function(svgGraph){
|
2015-07-17 23:13:40 +02:00
|
|
|
* console.log(svgGraph);
|
|
|
|
* };
|
|
|
|
* mermaidAPI.render('id1',graphDefinition,cb);
|
|
|
|
* });
|
|
|
|
*```
|
|
|
|
* @param id the id of the element to be rendered
|
|
|
|
* @param txt the graph definition
|
|
|
|
* @param cb callback which is called after rendering is finished with the svg code as inparam.
|
|
|
|
* @param container selector to element in which a div with the graph temporarily will be inserted. In one is
|
|
|
|
* provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is
|
|
|
|
* completed.
|
2015-07-15 11:39:46 +02:00
|
|
|
*/
|
2017-09-14 19:40:38 +08:00
|
|
|
const render = function (id, txt, cb, container) {
|
2017-04-11 22:14:25 +08:00
|
|
|
if (typeof container !== 'undefined') {
|
|
|
|
container.innerHTML = ''
|
2016-12-14 12:41:12 +01:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
d3.select(container).append('div')
|
2017-04-16 23:24:47 +08:00
|
|
|
.attr('id', 'd' + id)
|
|
|
|
.append('svg')
|
|
|
|
.attr('id', id)
|
|
|
|
.attr('width', '100%')
|
|
|
|
.attr('xmlns', 'http://www.w3.org/2000/svg')
|
|
|
|
.append('g')
|
2017-04-11 22:14:25 +08:00
|
|
|
} else {
|
2017-04-11 23:31:59 +08:00
|
|
|
const element = document.querySelector('#' + 'd' + id)
|
2017-04-11 22:14:25 +08:00
|
|
|
if (element) {
|
|
|
|
element.innerHTML = ''
|
2015-06-16 10:40:08 +02:00
|
|
|
}
|
2016-12-14 12:41:12 +01:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
d3.select('body').append('div')
|
2017-04-16 23:24:47 +08:00
|
|
|
.attr('id', 'd' + id)
|
|
|
|
.append('svg')
|
|
|
|
.attr('id', id)
|
|
|
|
.attr('width', '100%')
|
|
|
|
.attr('xmlns', 'http://www.w3.org/2000/svg')
|
|
|
|
.append('g')
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
window.txt = txt
|
2017-09-10 21:23:04 +08:00
|
|
|
txt = encodeEntities(txt)
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2017-09-14 19:40:38 +08:00
|
|
|
const element = d3.select('#d' + id).node()
|
|
|
|
const graphType = utils.detectType(txt)
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2017-09-12 22:06:19 +08:00
|
|
|
// insert inline style into svg
|
|
|
|
const svg = element.firstChild
|
2018-03-11 23:47:45 +08:00
|
|
|
const firstChild = svg.firstChild
|
|
|
|
|
2018-03-15 21:47:53 +08:00
|
|
|
// pre-defined theme
|
2018-03-15 22:44:00 +08:00
|
|
|
let style = themes[config.theme]
|
|
|
|
if (style === undefined) {
|
|
|
|
style = ''
|
|
|
|
}
|
2018-03-15 21:47:53 +08:00
|
|
|
|
|
|
|
// user provided theme CSS
|
|
|
|
if (config.themeCSS !== undefined) {
|
|
|
|
style += `\n${config.themeCSS}`
|
|
|
|
}
|
|
|
|
|
2018-03-14 21:36:10 +08:00
|
|
|
// classDef
|
|
|
|
if (graphType === 'flowchart') {
|
|
|
|
const classes = flowRenderer.getClasses(txt)
|
|
|
|
for (const className in classes) {
|
2018-03-14 21:38:29 +08:00
|
|
|
style += `\n.${className} > * { ${classes[className].styles.join(' !important; ')} !important; }`
|
2018-03-14 21:36:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-11 23:47:45 +08:00
|
|
|
const style1 = document.createElement('style')
|
2018-03-14 21:36:10 +08:00
|
|
|
style1.innerHTML = scope(style, `#${id}`)
|
2018-03-11 23:47:45 +08:00
|
|
|
svg.insertBefore(style1, firstChild)
|
|
|
|
|
|
|
|
const style2 = document.createElement('style')
|
|
|
|
const cs = window.getComputedStyle(svg)
|
|
|
|
style2.innerHTML = `#${id} {
|
|
|
|
color: ${cs.color};
|
|
|
|
font: ${cs.font};
|
|
|
|
}`
|
|
|
|
svg.insertBefore(style2, firstChild)
|
2017-09-12 22:06:19 +08:00
|
|
|
|
2018-03-21 21:29:12 +08:00
|
|
|
switch (graphType) {
|
|
|
|
case 'git':
|
|
|
|
config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
gitGraphRenderer.setConf(config.git)
|
|
|
|
gitGraphRenderer.draw(txt, id, false)
|
|
|
|
break
|
|
|
|
case 'flowchart':
|
|
|
|
config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
flowRenderer.setConf(config.flowchart)
|
|
|
|
flowRenderer.draw(txt, id, false)
|
|
|
|
break
|
|
|
|
case 'sequence':
|
|
|
|
config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
if (config.sequenceDiagram) { // backwards compatibility
|
|
|
|
sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram))
|
|
|
|
console.error('`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.')
|
|
|
|
} else {
|
|
|
|
sequenceRenderer.setConf(config.sequence)
|
|
|
|
}
|
|
|
|
sequenceRenderer.draw(txt, id)
|
|
|
|
break
|
|
|
|
case 'gantt':
|
|
|
|
config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
ganttRenderer.setConf(config.gantt)
|
|
|
|
ganttRenderer.draw(txt, id)
|
|
|
|
break
|
|
|
|
case 'class':
|
|
|
|
config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
classRenderer.setConf(config.class)
|
|
|
|
classRenderer.draw(txt, id)
|
|
|
|
break
|
2019-06-15 14:29:26 +02:00
|
|
|
case 'info':
|
|
|
|
config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
infoRenderer.setConf(config.class)
|
|
|
|
infoRenderer.draw(txt, id, pkg.version)
|
|
|
|
break
|
2018-03-21 21:29:12 +08:00
|
|
|
}
|
|
|
|
|
2018-03-17 09:10:10 +08:00
|
|
|
d3.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', 'http://www.w3.org/1999/xhtml')
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2017-09-14 19:40:38 +08:00
|
|
|
let url = ''
|
2017-04-11 22:14:25 +08:00
|
|
|
if (config.arrowMarkerAbsolute) {
|
|
|
|
url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
|
|
|
|
url = url.replace(/\(/g, '\\(')
|
|
|
|
url = url.replace(/\)/g, '\\)')
|
|
|
|
}
|
2015-05-26 20:59:23 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
// Fix for when the base tag is used
|
2017-09-14 19:40:38 +08:00
|
|
|
let svgCode = d3.select('#d' + id).node().innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g')
|
2015-10-04 21:18:05 +02:00
|
|
|
|
2017-09-10 21:23:04 +08:00
|
|
|
svgCode = decodeEntities(svgCode)
|
2015-10-04 21:18:05 +02:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
if (typeof cb !== 'undefined') {
|
2019-08-14 18:33:10 +02:00
|
|
|
switch (graphType) {
|
2019-08-11 03:26:44 -07:00
|
|
|
case 'flowchart':
|
|
|
|
cb(svgCode, flowDb.bindFunctions)
|
2019-08-14 18:33:10 +02:00
|
|
|
break
|
2019-08-11 03:26:44 -07:00
|
|
|
case 'gantt':
|
|
|
|
cb(svgCode, ganttDb.bindFunctions)
|
2019-08-14 18:33:10 +02:00
|
|
|
break
|
|
|
|
default:
|
2019-08-14 19:25:52 +02:00
|
|
|
cb(svgCode)
|
2019-08-11 03:26:44 -07:00
|
|
|
}
|
2017-04-11 22:14:25 +08:00
|
|
|
} else {
|
2019-08-11 03:26:44 -07:00
|
|
|
logger.debug('CB = undefined!')
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
2015-06-16 10:40:08 +02:00
|
|
|
|
2017-09-14 19:40:38 +08:00
|
|
|
const node = d3.select('#d' + id).node()
|
2017-04-11 22:14:25 +08:00
|
|
|
if (node !== null && typeof node.remove === 'function') {
|
|
|
|
d3.select('#d' + id).node().remove()
|
|
|
|
}
|
2015-11-15 15:06:24 +01:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
return svgCode
|
|
|
|
}
|
2015-05-26 20:59:23 +02:00
|
|
|
|
2017-09-14 19:40:38 +08:00
|
|
|
const setConf = function (cnf) {
|
2017-04-16 23:24:47 +08:00
|
|
|
// Top level initially mermaid, gflow, sequenceDiagram and gantt
|
2017-09-14 19:40:38 +08:00
|
|
|
const lvl1Keys = Object.keys(cnf)
|
|
|
|
for (let i = 0; i < lvl1Keys.length; i++) {
|
2018-03-15 22:44:00 +08:00
|
|
|
if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) {
|
2017-09-14 19:40:38 +08:00
|
|
|
const lvl2Keys = Object.keys(cnf[lvl1Keys[i]])
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2017-09-14 19:40:38 +08:00
|
|
|
for (let j = 0; j < lvl2Keys.length; j++) {
|
2017-09-10 19:41:34 +08:00
|
|
|
logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j])
|
2017-04-11 22:14:25 +08:00
|
|
|
if (typeof config[lvl1Keys[i]] === 'undefined') {
|
|
|
|
config[lvl1Keys[i]] = {}
|
2015-05-30 17:20:24 +02:00
|
|
|
}
|
2017-09-10 19:41:34 +08:00
|
|
|
logger.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]])
|
2017-04-11 22:14:25 +08:00
|
|
|
config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]]
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
config[lvl1Keys[i]] = cnf[lvl1Keys[i]]
|
2015-05-30 17:20:24 +02:00
|
|
|
}
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
|
|
|
}
|
2016-10-30 16:13:06 +01:00
|
|
|
|
2017-09-10 10:45:38 +08:00
|
|
|
function initialize (options) {
|
2019-06-15 14:29:26 +02:00
|
|
|
logger.debug('Initializing mermaidAPI ', pkg.version)
|
2019-07-21 02:09:22 -07:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
// Update default config with options supplied at initialization
|
2017-04-11 22:14:25 +08:00
|
|
|
if (typeof options === 'object') {
|
|
|
|
setConf(options)
|
|
|
|
}
|
2019-07-21 02:09:22 -07:00
|
|
|
setConfig(config)
|
2017-09-10 19:41:34 +08:00
|
|
|
setLogLevel(config.logLevel)
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
2017-09-10 10:45:38 +08:00
|
|
|
|
2019-07-21 02:09:22 -07:00
|
|
|
// function getConfig () {
|
|
|
|
// console.warn('get config')
|
|
|
|
// return config
|
|
|
|
// }
|
2017-04-11 22:14:25 +08:00
|
|
|
|
2017-09-10 10:45:38 +08:00
|
|
|
const mermaidAPI = {
|
2018-03-11 22:23:26 +08:00
|
|
|
render,
|
2017-09-10 10:45:38 +08:00
|
|
|
parse,
|
|
|
|
initialize,
|
|
|
|
getConfig
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|
2017-09-10 10:45:38 +08:00
|
|
|
|
|
|
|
export default mermaidAPI
|