2015-07-17 23:13:40 +02:00
/ * *
2019-09-11 20:03:22 +02:00
* This is the api to be used when optionally handling the integration with the web page , instead of using the default integration provided by mermaid . js .
*
* The core of this api is the [ * * render * * ] ( https : //github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#render) function which, given a graph
* definition as text , renders the graph / diagram and returns an 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 do something completely different .
*
* In addition to the render function , a number of behavioral configuration options are available .
2015-07-17 23:13:40 +02:00
*
2019-07-14 06:07:27 -07:00
* @ name mermaidAPI
2019-09-12 12:59:13 -07:00
* /
import * as d3 from 'd3' ;
import scope from 'scope-css' ;
import pkg from '../package.json' ;
import { setConfig , getConfig } from './config' ;
import { logger , setLogLevel } from './logger' ;
import utils from './utils' ;
import flowRenderer from './diagrams/flowchart/flowRenderer' ;
import flowParser from './diagrams/flowchart/parser/flow' ;
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' ;
import ganttRenderer from './diagrams/gantt/ganttRenderer' ;
import ganttParser from './diagrams/gantt/parser/gantt' ;
import ganttDb from './diagrams/gantt/ganttDb' ;
import classRenderer from './diagrams/class/classRenderer' ;
import classParser from './diagrams/class/parser/classDiagram' ;
import classDb from './diagrams/class/classDb' ;
2019-09-25 21:01:21 +02:00
import stateRenderer from './diagrams/state/stateRenderer' ;
import stateParser from './diagrams/state/parser/stateDiagram' ;
import stateDb from './diagrams/state/stateDb' ;
2019-09-12 12:59:13 -07:00
import gitGraphRenderer from './diagrams/git/gitGraphRenderer' ;
import gitGraphParser from './diagrams/git/parser/gitGraph' ;
import gitGraphAst from './diagrams/git/gitGraphAst' ;
import infoRenderer from './diagrams/info/infoRenderer' ;
import infoParser from './diagrams/info/parser/info' ;
import infoDb from './diagrams/info/infoDb' ;
import pieRenderer from './diagrams/pie/pieRenderer' ;
import pieParser from './diagrams/pie/parser/pie' ;
import pieDb from './diagrams/pie/pieDb' ;
const themes = { } ;
2018-03-13 14:31:56 +08:00
for ( const themeName of [ 'default' , 'forest' , 'dark' , 'neutral' ] ) {
2019-09-12 12:59:13 -07:00
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
/ * *
2019-09-11 20:03:22 +02:00
* These are the default options which can be overridden with the initialization call like so :
* * * Example 1 : * *
* < pre >
2015-07-17 23:13:40 +02:00
* mermaid . initialize ( {
* flowchart : {
2020-01-12 14:38:57 +01:00
* htmlLabels : false
2015-07-17 23:13:40 +02:00
* }
* } ) ;
2019-09-11 20:03:22 +02:00
* < / p r e >
*
* * * Example 2 : * *
* < pre >
2020-01-12 14:38:57 +01:00
* & lt ; script >
2019-09-11 20:03:22 +02:00
* var config = {
* startOnLoad : true ,
* flowchart : {
* useMaxWidth : true ,
* htmlLabels : true ,
* curve : 'cardinal' ,
* } ,
*
* securityLevel : 'loose' ,
* } ;
* mermaid . initialize ( config ) ;
2020-01-12 14:38:57 +01:00
* & lt ; / s c r i p t >
2019-09-11 20:03:22 +02:00
* < / p r e >
* A summary of all options and their defaults is found [ here ] ( https : //github.com/knsv/mermaid/blob/master/docs/mermaidAPI.md#mermaidapi-configuration-defaults). A description of each option follows below.
*
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-12-18 13:32:36 +08:00
/ * * t h e m e , t h e C S S s t y l e s h e e t
2019-09-12 12:59:13 -07:00
*
* * * theme * * - Choose one of the built - in themes :
* * default
* * forest
* * dark
* * neutral .
* To disable any pre - defined mermaid theme , use "null" .
*
* * * themeCSS * * - Use your own CSS . This overrides * * theme * * .
* < pre >
* "theme" : "forest" ,
* "themeCSS" : ".node rect { fill: red; }"
* < / p r e >
* /
2018-03-15 21:22:49 +08:00
theme : 'default' ,
2018-03-15 21:47:53 +08:00
themeCSS : undefined ,
2019-10-13 19:16:35 +02:00
2019-10-12 16:53:21 +02:00
/ * *
* * * fontFamily * * The font to be used for the rendered diagrams . Default value is \ "trebuchet ms\" , verdana , arial ;
* /
fontFamily : '"trebuchet ms", verdana, arial;' ,
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 .
2019-09-11 20:03:22 +02:00
* * * * strict * * : ( * * default * * ) tags in text are encoded , click functionality is disabeled
* * * * loose * * : 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
2020-01-12 14:09:24 +01:00
/ * *
* Defines the spacing between nodes on the same level ( meaning horizontal spacing for
* TB or BT graphs , and the vertical spacing for LR as well as RL graphs ) .
* * * Default value 50 * * .
* /
nodeSpacing : 50 ,
/ * *
* Defines the spacing between nodes on different levels ( meaning vertical spacing for
* TB or BT graphs , and the horizontal spacing for LR as well as RL graphs ) .
* * * Default value 50 * * .
* /
rankSpacing : 50 ,
2019-07-14 06:07:27 -07:00
/ * *
2019-09-11 20:03:22 +02:00
* How mermaid renders curves for flowcharts . Possible values are
* * basis
* * linear * * default * *
* * cardinal
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 : {
2017-04-16 23:24:47 +08:00
/ * *
2019-09-11 20:03:22 +02:00
* margin to the right and left of the sequence diagram .
2019-07-14 06:07:27 -07:00
* * * 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-09-11 20:03:22 +02:00
* Datetime format of the axis . This might need adjustment to match your locale and preferences
2019-07-14 06:07:27 -07:00
* * * 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 : { } ,
2019-10-11 15:39:50 +02:00
git : { } ,
state : {
dividerMargin : 10 ,
sizeUnit : 5 ,
2019-10-27 16:58:32 +01:00
padding : 8 ,
2019-10-11 15:39:50 +02:00
textHeight : 10 ,
titleShift : - 15 ,
noteMargin : 10 ,
forkWidth : 70 ,
forkHeight : 7 ,
// Used
miniPadding : 2 ,
// Font size factor, this is used to guess the width of the edges labels before rendering by dagre
// layout. This might need updating if/when switching font
fontSizeFactor : 5.02 ,
fontSize : 24 ,
labelHeight : 16 ,
edgeLengthFactor : '20' ,
compositTitleSize : 35 ,
radius : 5
}
2019-09-12 12:59:13 -07:00
} ;
2017-04-11 22:14:25 +08:00
2019-09-12 12:59:13 -07:00
setLogLevel ( config . logLevel ) ;
setConfig ( config ) ;
2015-10-04 19:30:53 +02:00
2019-09-12 12:59:13 -07:00
function parse ( text ) {
const graphType = utils . detectType ( text ) ;
let parser ;
2017-04-11 22:14:25 +08:00
2019-09-12 12:59:13 -07: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' :
2019-09-12 12:59:13 -07:00
parser = gitGraphParser ;
parser . parser . yy = gitGraphAst ;
break ;
2018-03-12 21:06:49 +08:00
case 'flowchart' :
2019-09-19 15:00:21 -07:00
flowDb . clear ( ) ;
2019-09-12 12:59:13 -07:00
parser = flowParser ;
parser . parser . yy = flowDb ;
break ;
2018-03-12 21:16:22 +08:00
case 'sequence' :
2019-09-12 12:59:13 -07:00
parser = sequenceParser ;
parser . parser . yy = sequenceDb ;
break ;
2017-04-11 22:14:25 +08:00
case 'gantt' :
2019-09-12 12:59:13 -07:00
parser = ganttParser ;
parser . parser . yy = ganttDb ;
break ;
2018-03-12 21:16:22 +08:00
case 'class' :
2019-09-12 12:59:13 -07:00
parser = classParser ;
parser . parser . yy = classDb ;
break ;
2019-09-25 21:01:21 +02:00
case 'state' :
parser = stateParser ;
parser . parser . yy = stateDb ;
break ;
2019-06-15 14:29:26 +02:00
case 'info' :
2019-09-12 12:59:13 -07:00
logger . debug ( 'info info info' ) ;
parser = infoParser ;
parser . parser . yy = infoDb ;
break ;
2019-09-11 21:20:28 +02:00
case 'pie' :
2019-09-12 12:59:13 -07:00
logger . debug ( 'pie' ) ;
parser = pieParser ;
parser . parser . yy = pieDb ;
break ;
2017-04-11 22:14:25 +08:00
}
2017-09-10 10:10:36 +08:00
parser . parser . yy . parseError = ( str , hash ) => {
2019-09-12 12:59:13 -07:00
const error = { str , hash } ;
throw error ;
} ;
2017-09-10 00:29:22 +08:00
2019-09-12 12:59:13 -07:00
parser . parse ( text ) ;
2017-04-11 22:14:25 +08:00
}
2015-05-26 20:59:23 +02:00
2019-09-12 12:59:13 -07:00
export const encodeEntities = function ( text ) {
let txt = text ;
2017-04-11 22:14:25 +08:00
2019-09-12 12:59:13 -07:00
txt = txt . replace ( /style.*:\S*#.*;/g , function ( s ) {
const innerTxt = s . substring ( 0 , s . length - 1 ) ;
return innerTxt ;
} ) ;
txt = txt . replace ( /classDef.*:\S*#.*;/g , function ( s ) {
const innerTxt = s . substring ( 0 , s . length - 1 ) ;
return innerTxt ;
} ) ;
2017-04-11 22:14:25 +08:00
2019-09-12 12:59:13 -07:00
txt = txt . replace ( /#\w+;/g , function ( s ) {
const innerTxt = s . substring ( 1 , s . length - 1 ) ;
2017-04-11 22:14:25 +08:00
2019-09-12 12:59:13 -07:00
const isInt = /^\+?\d+$/ . test ( innerTxt ) ;
2017-04-11 22:14:25 +08:00
if ( isInt ) {
2019-09-12 12:59:13 -07:00
return 'fl°°' + innerTxt + '¶ß' ;
2017-04-11 22:14:25 +08:00
} else {
2019-09-12 12:59:13 -07:00
return 'fl°' + innerTxt + '¶ß' ;
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
} ) ;
return txt ;
} ;
export const decodeEntities = function ( text ) {
let txt = text ;
txt = txt . replace ( /fl°°/g , function ( ) {
return '&#' ;
} ) ;
txt = txt . replace ( /fl°/g , function ( ) {
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
* /
2019-09-12 12:59:13 -07:00
const render = function ( id , txt , cb , container ) {
2017-04-11 22:14:25 +08:00
if ( typeof container !== 'undefined' ) {
2019-09-12 12:59:13 -07:00
container . innerHTML = '' ;
2016-12-14 12:41:12 +01:00
2019-09-12 12:59:13 -07:00
d3 . select ( container )
. append ( 'div' )
2017-04-16 23:24:47 +08:00
. attr ( 'id' , 'd' + id )
2019-10-12 16:53:21 +02:00
. attr ( 'style' , 'font-family: ' + config . fontFamily )
2017-04-16 23:24:47 +08:00
. append ( 'svg' )
. attr ( 'id' , id )
. attr ( 'width' , '100%' )
. attr ( 'xmlns' , 'http://www.w3.org/2000/svg' )
2019-09-12 12:59:13 -07:00
. append ( 'g' ) ;
2017-04-11 22:14:25 +08:00
} else {
2019-10-15 08:02:41 +02:00
const existingSvg = document . getElementById ( id ) ;
if ( existingSvg ) {
existingSvg . remove ( ) ;
}
2019-09-12 12:59:13 -07:00
const element = document . querySelector ( '#' + 'd' + id ) ;
2017-04-11 22:14:25 +08:00
if ( element ) {
2019-09-12 12:59:13 -07:00
element . innerHTML = '' ;
2015-06-16 10:40:08 +02:00
}
2016-12-14 12:41:12 +01:00
2019-09-12 12:59:13 -07: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' )
2019-09-12 12:59:13 -07:00
. append ( 'g' ) ;
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
window . txt = txt ;
txt = encodeEntities ( txt ) ;
2017-04-11 22:14:25 +08:00
2019-09-12 12:59:13 -07: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
2019-09-12 12:59:13 -07:00
const svg = element . firstChild ;
const firstChild = svg . firstChild ;
2018-03-11 23:47:45 +08:00
2018-03-15 21:47:53 +08:00
// pre-defined theme
2019-09-12 12:59:13 -07:00
let style = themes [ config . theme ] ;
2018-03-15 22:44:00 +08:00
if ( style === undefined ) {
2019-09-12 12:59:13 -07:00
style = '' ;
2018-03-15 22:44:00 +08:00
}
2018-03-15 21:47:53 +08:00
// user provided theme CSS
if ( config . themeCSS !== undefined ) {
2019-09-12 12:59:13 -07:00
style += ` \n ${ config . themeCSS } ` ;
2018-03-15 21:47:53 +08:00
}
2019-10-12 16:53:21 +02:00
// user provided theme CSS
if ( config . fontFamily !== undefined ) {
style += ` \n :root { --mermaid-font-family: ${ config . fontFamily } } ` ;
}
// user provided theme CSS
if ( config . altFontFamily !== undefined ) {
style += ` \n :root { --mermaid-alt-font-family: ${ config . altFontFamily } } ` ;
}
2018-03-15 21:47:53 +08:00
2018-03-14 21:36:10 +08:00
// classDef
if ( graphType === 'flowchart' ) {
2019-09-12 12:59:13 -07:00
const classes = flowRenderer . getClasses ( txt ) ;
2018-03-14 21:36:10 +08:00
for ( const className in classes ) {
2019-09-12 12:59:13 -07:00
style += ` \n . ${ className } > * { ${ classes [ className ] . styles . join (
' !important; '
) } ! important ; } ` ;
2018-03-14 21:36:10 +08:00
}
}
2019-09-12 12:59:13 -07:00
const style1 = document . createElement ( 'style' ) ;
style1 . innerHTML = scope ( style , ` # ${ id } ` ) ;
svg . insertBefore ( style1 , firstChild ) ;
2018-03-11 23:47:45 +08:00
2019-09-12 12:59:13 -07:00
const style2 = document . createElement ( 'style' ) ;
const cs = window . getComputedStyle ( svg ) ;
2018-03-11 23:47:45 +08:00
style2 . innerHTML = ` # ${ id } {
color : $ { cs . color } ;
font : $ { cs . font } ;
2019-09-12 12:59:13 -07:00
} ` ;
svg . insertBefore ( style2 , firstChild ) ;
2017-09-12 22:06:19 +08:00
2018-03-21 21:29:12 +08:00
switch ( graphType ) {
case 'git' :
2019-09-12 12:59:13 -07:00
config . flowchart . arrowMarkerAbsolute = config . arrowMarkerAbsolute ;
gitGraphRenderer . setConf ( config . git ) ;
gitGraphRenderer . draw ( txt , id , false ) ;
break ;
2018-03-21 21:29:12 +08:00
case 'flowchart' :
2019-09-12 12:59:13 -07:00
config . flowchart . arrowMarkerAbsolute = config . arrowMarkerAbsolute ;
flowRenderer . setConf ( config . flowchart ) ;
flowRenderer . draw ( txt , id , false ) ;
break ;
2018-03-21 21:29:12 +08:00
case 'sequence' :
2019-09-12 12:59:13 -07:00
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.'
) ;
2018-03-21 21:29:12 +08:00
} else {
2019-09-12 12:59:13 -07:00
sequenceRenderer . setConf ( config . sequence ) ;
2018-03-21 21:29:12 +08:00
}
2019-09-12 12:59:13 -07:00
sequenceRenderer . draw ( txt , id ) ;
break ;
2018-03-21 21:29:12 +08:00
case 'gantt' :
2019-09-12 12:59:13 -07:00
config . gantt . arrowMarkerAbsolute = config . arrowMarkerAbsolute ;
ganttRenderer . setConf ( config . gantt ) ;
ganttRenderer . draw ( txt , id ) ;
break ;
2018-03-21 21:29:12 +08:00
case 'class' :
2019-09-12 12:59:13 -07:00
config . class . arrowMarkerAbsolute = config . arrowMarkerAbsolute ;
classRenderer . setConf ( config . class ) ;
classRenderer . draw ( txt , id ) ;
break ;
2019-09-25 21:01:21 +02:00
case 'state' :
// config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute;
stateRenderer . setConf ( config . state ) ;
stateRenderer . draw ( txt , id ) ;
break ;
2019-06-15 14:29:26 +02:00
case 'info' :
2019-09-12 12:59:13 -07:00
config . class . arrowMarkerAbsolute = config . arrowMarkerAbsolute ;
infoRenderer . setConf ( config . class ) ;
infoRenderer . draw ( txt , id , pkg . version ) ;
break ;
2019-09-11 21:20:28 +02:00
case 'pie' :
2019-09-12 12:59:13 -07:00
config . class . arrowMarkerAbsolute = config . arrowMarkerAbsolute ;
pieRenderer . setConf ( config . class ) ;
pieRenderer . draw ( txt , id , pkg . version ) ;
break ;
2018-03-21 21:29:12 +08:00
}
2019-09-12 12:59:13 -07:00
d3 . select ( ` [id=" ${ id } "] ` )
. selectAll ( 'foreignobject > *' )
. attr ( 'xmlns' , 'http://www.w3.org/1999/xhtml' ) ;
2017-04-11 22:14:25 +08:00
2019-11-20 19:14:32 +01: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
2019-11-20 19:06:46 +01:00
let svgCode = d3 . select ( '#d' + id ) . node ( ) . innerHTML ;
if ( ! config . arrowMarkerAbsolute || config . arrowMarkerAbsolute === 'false' ) {
2019-11-20 19:14:32 +01:00
svgCode = svgCode . replace ( /marker-end="url\(.*?#/g , 'marker-end="url(#' , 'g' ) ;
2019-11-20 19:06:46 +01:00
}
2015-10-04 21:18:05 +02:00
2019-09-12 12:59:13 -07: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' :
2019-09-12 12:59:13 -07:00
cb ( svgCode , flowDb . bindFunctions ) ;
break ;
2019-08-11 03:26:44 -07:00
case 'gantt' :
2019-09-12 12:59:13 -07:00
cb ( svgCode , ganttDb . bindFunctions ) ;
break ;
2020-01-02 11:04:37 -08:00
case 'class' :
cb ( svgCode , classDb . bindFunctions ) ;
break ;
2019-08-14 18:33:10 +02:00
default :
2019-09-12 12:59:13 -07:00
cb ( svgCode ) ;
2019-08-11 03:26:44 -07:00
}
2017-04-11 22:14:25 +08:00
} else {
2019-09-12 12:59:13 -07:00
logger . debug ( 'CB = undefined!' ) ;
2017-04-11 22:14:25 +08:00
}
2015-06-16 10:40:08 +02:00
2019-09-12 12:59:13 -07:00
const node = d3 . select ( '#d' + id ) . node ( ) ;
2017-04-11 22:14:25 +08:00
if ( node !== null && typeof node . remove === 'function' ) {
2019-09-12 12:59:13 -07:00
d3 . select ( '#d' + id )
. node ( )
. remove ( ) ;
2017-04-11 22:14:25 +08:00
}
2015-11-15 15:06:24 +01:00
2019-09-12 12:59:13 -07:00
return svgCode ;
} ;
2015-05-26 20:59:23 +02:00
2019-09-12 12:59:13 -07:00
const setConf = function ( cnf ) {
2017-04-16 23:24:47 +08:00
// Top level initially mermaid, gflow, sequenceDiagram and gantt
2019-09-12 12:59:13 -07:00
const lvl1Keys = Object . keys ( cnf ) ;
2017-09-14 19:40:38 +08:00
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 ) {
2019-09-12 12:59:13 -07: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 ++ ) {
2019-09-12 12:59:13 -07:00
logger . debug ( 'Setting conf ' , lvl1Keys [ i ] , '-' , lvl2Keys [ j ] ) ;
2017-04-11 22:14:25 +08:00
if ( typeof config [ lvl1Keys [ i ] ] === 'undefined' ) {
2019-09-12 12:59:13 -07:00
config [ lvl1Keys [ i ] ] = { } ;
2015-05-30 17:20:24 +02:00
}
2019-09-12 12:59:13 -07:00
logger . debug (
'Setting config: ' +
lvl1Keys [ i ] +
' ' +
lvl2Keys [ j ] +
' to ' +
cnf [ lvl1Keys [ i ] ] [ lvl2Keys [ j ] ]
) ;
config [ lvl1Keys [ i ] ] [ lvl2Keys [ j ] ] = cnf [ lvl1Keys [ i ] ] [ lvl2Keys [ j ] ] ;
2017-04-11 22:14:25 +08:00
}
} else {
2019-09-12 12:59:13 -07:00
config [ lvl1Keys [ i ] ] = cnf [ lvl1Keys [ i ] ] ;
2015-05-30 17:20:24 +02:00
}
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
} ;
2016-10-30 16:13:06 +01:00
2019-09-12 12:59:13 -07:00
function initialize ( options ) {
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' ) {
2019-09-12 12:59:13 -07:00
setConf ( options ) ;
2017-04-11 22:14:25 +08:00
}
2019-09-12 12:59:13 -07:00
setConfig ( config ) ;
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
2019-09-12 12:59:13 -07:00
} ;
2017-09-10 10:45:38 +08:00
2019-09-12 12:59:13 -07:00
export default mermaidAPI ;
2019-09-11 20:03:22 +02:00
/ * *
* # # mermaidAPI configuration defaults
* < pre >
*
2019-11-07 23:15:53 +01:00
* & lt ; script >
2019-09-11 20:03:22 +02:00
* var config = {
* theme : 'default' ,
* logLevel : 'fatal' ,
* securityLevel : 'strict' ,
* startOnLoad : true ,
* arrowMarkerAbsolute : false ,
*
* flowchart : {
2019-09-18 13:05:08 +02:00
* htmlLabels : true ,
2019-09-11 20:03:22 +02:00
* curve : 'linear' ,
* } ,
* sequence : {
* diagramMarginX : 50 ,
* diagramMarginY : 10 ,
* actorMargin : 50 ,
* width : 150 ,
* height : 65 ,
* boxMargin : 10 ,
* boxTextMargin : 5 ,
* noteMargin : 10 ,
* messageMargin : 35 ,
* mirrorActors : true ,
* bottomMarginAdj : 1 ,
* useMaxWidth : true ,
* rightAngles : false ,
* showSequenceNumbers : false ,
* } ,
* gantt : {
* titleTopMargin : 25 ,
* barHeight : 20 ,
* barGap : 4 ,
* topPadding : 50 ,
* leftPadding : 75 ,
* gridLineStartPadding : 35 ,
* fontSize : 11 ,
* fontFamily : '"Open-Sans", "sans-serif"' ,
* numberSectionStyles : 4 ,
* axisFormat : '%Y-%m-%d' ,
* }
* } ;
* mermaid . initialize ( config ) ;
2019-11-07 23:15:53 +01:00
* & lt ; / s c r i p t >
2019-09-11 20:03:22 +02:00
* < / p r e >
* /