2015-07-17 23:13:40 +02:00
|
|
|
/**
|
2015-09-26 12:09:47 +02:00
|
|
|
* ---
|
|
|
|
* title: mermaidAPI
|
|
|
|
* order: 5
|
|
|
|
* ---
|
2015-10-03 16:30:50 +02:00
|
|
|
* # mermaidAPI
|
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.
|
2017-09-10 00:29:22 +08:00
|
|
|
*/
|
|
|
|
import EventEmitter from 'events'
|
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
var Logger = require('./logger')
|
|
|
|
var log = Logger.Log
|
|
|
|
|
|
|
|
var graph = require('./diagrams/flowchart/graphDb')
|
|
|
|
var utils = require('./utils')
|
|
|
|
var flowRenderer = require('./diagrams/flowchart/flowRenderer')
|
|
|
|
var seq = require('./diagrams/sequenceDiagram/sequenceRenderer')
|
|
|
|
var info = require('./diagrams/example/exampleRenderer')
|
|
|
|
var infoParser = require('./diagrams/example/parser/example')
|
|
|
|
var flowParser = require('./diagrams/flowchart/parser/flow')
|
|
|
|
var dotParser = require('./diagrams/flowchart/parser/dot')
|
|
|
|
var sequenceParser = require('./diagrams/sequenceDiagram/parser/sequenceDiagram')
|
|
|
|
var sequenceDb = require('./diagrams/sequenceDiagram/sequenceDb')
|
|
|
|
var infoDb = require('./diagrams/example/exampleDb')
|
|
|
|
var gantt = require('./diagrams/gantt/ganttRenderer')
|
|
|
|
var ganttParser = require('./diagrams/gantt/parser/gantt')
|
|
|
|
var ganttDb = require('./diagrams/gantt/ganttDb')
|
|
|
|
var classParser = require('./diagrams/classDiagram/parser/classDiagram')
|
|
|
|
var classRenderer = require('./diagrams/classDiagram/classRenderer')
|
|
|
|
var classDb = require('./diagrams/classDiagram/classDb')
|
|
|
|
var gitGraphParser = require('./diagrams/gitGraph/parser/gitGraph')
|
|
|
|
var gitGraphRenderer = require('./diagrams/gitGraph/gitGraphRenderer')
|
|
|
|
var gitGraphAst = require('./diagrams/gitGraph/gitGraphAst')
|
|
|
|
var d3 = require('./d3')
|
|
|
|
|
2017-09-10 00:29:22 +08:00
|
|
|
module.exports.eventEmitter = new EventEmitter()
|
|
|
|
|
2015-06-20 20:58:58 +02:00
|
|
|
/**
|
2015-09-26 12:09:47 +02:00
|
|
|
* ## Configuration
|
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
|
|
|
|
* }
|
|
|
|
* });
|
|
|
|
* ```
|
2015-06-20 20:58:58 +02:00
|
|
|
*/
|
2015-05-30 17:20:24 +02:00
|
|
|
var config = {
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* logLevel , decides the amount of logging to be used.
|
|
|
|
* * debug: 1
|
|
|
|
* * info: 2
|
|
|
|
* * warn: 3
|
|
|
|
* * error: 4
|
|
|
|
* * fatal: 5
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
logLevel: 5,
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* **cloneCssStyles** - This options controls whether or not the css rules should be copied into the generated svg
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
cloneCssStyles: true,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* **startOnLoad** - This options controls whether or mermaid starts when the page loads
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **arrowMarkerAbsolute** - This options controls whether or arrow markers in html code will be absolute paths or
|
|
|
|
* an anchor, #. This matters if you are using base tag settings.
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* ### flowchart
|
|
|
|
* *The object containing configurations specific for flowcharts*
|
|
|
|
*/
|
|
|
|
flowchart: {
|
2015-09-26 12:09:47 +02:00
|
|
|
/**
|
2017-04-16 23:24:47 +08:00
|
|
|
* **htmlLabels** - Flag for setting whether or not a html tag should be used for rendering labels
|
|
|
|
* on the edges
|
2015-09-26 12:09:47 +02:00
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
htmlLabels: true,
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* **useMaxWidth** - Flag for setting whether or not a all available width should be used for
|
|
|
|
* the diagram.
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
useMaxWidth: true
|
|
|
|
},
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* ### sequenceDiagram
|
|
|
|
* The object containing configurations specific for sequence diagrams
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
sequenceDiagram: {
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* **diagramMarginX** - margin to the right and left of the sequence diagram
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **diagramMarginY** - margin to the over and under the sequence diagram
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **actorMargin** - Margin between actors
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **width** - Width of actor boxes
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **height** - Height of actor boxes
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **boxMargin** - Margin around loop boxes
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **boxTextMargin** - margin around the text in loop/alt/opt boxes
|
|
|
|
*/
|
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
|
|
|
/**
|
2015-09-26 12:09:47 +02:00
|
|
|
* **noteMargin** - margin around notes
|
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
|
|
|
/**
|
2015-09-26 12:09:47 +02:00
|
|
|
* **messageMargin** - Space between messages
|
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
|
|
|
/**
|
|
|
|
* **mirrorActors** - mirror actors under diagram
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **bottomMarginAdj** - Depending on css styling this might need adjustment.
|
|
|
|
* Prolongs the edge of the diagram downwards
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **useMaxWidth** - 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
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
useMaxWidth: true
|
|
|
|
},
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/** ### gantt
|
|
|
|
* 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
|
|
|
/**
|
|
|
|
* **titleTopMargin** - margin top for the text over the gantt diagram
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **barHeight** - the height of the bars in the graph
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **barGap** - the margin between the different activities in the gantt diagram
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **topPadding** - margin between title and gantt diagram and between axis and gantt diagram.
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **leftPadding** - the space allocated for the section name to the left of the activities.
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **gridLineStartPadding** - Vertical starting position of the grid lines
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **fontSize** - font size ...
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **fontFamily** - font family ...
|
|
|
|
*/
|
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
|
|
|
/**
|
|
|
|
* **numberSectionStyles** - the number of alternating section styles
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
numberSectionStyles: 3,
|
2015-07-17 23:13:40 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
/**
|
|
|
|
* **axisFormatter** - formatting of the axis, this might need adjustment to match your locale and preferences
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
axisFormatter: [
|
2015-09-26 12:09:47 +02:00
|
|
|
|
2017-04-16 23:24:47 +08:00
|
|
|
// Within a day
|
2017-04-11 22:14:25 +08:00
|
|
|
['%I:%M', function (d) {
|
|
|
|
return d.getHours()
|
|
|
|
}],
|
2017-04-16 23:24:47 +08:00
|
|
|
// Monday a week
|
2017-04-11 22:14:25 +08:00
|
|
|
['w. %U', function (d) {
|
2017-04-11 23:31:59 +08:00
|
|
|
return d.getDay() === 1
|
2017-04-11 22:14:25 +08:00
|
|
|
}],
|
2017-04-16 23:24:47 +08:00
|
|
|
// Day within a week (not monday)
|
2017-04-11 22:14:25 +08:00
|
|
|
['%a %d', function (d) {
|
2017-04-11 23:31:59 +08:00
|
|
|
return d.getDay() && d.getDate() !== 1
|
2017-04-11 22:14:25 +08:00
|
|
|
}],
|
2017-04-16 23:24:47 +08:00
|
|
|
// within a month
|
2017-04-11 22:14:25 +08:00
|
|
|
['%b %d', function (d) {
|
2017-04-11 23:31:59 +08:00
|
|
|
return d.getDate() !== 1
|
2017-04-11 22:14:25 +08:00
|
|
|
}],
|
2017-04-16 23:24:47 +08:00
|
|
|
// Month
|
2017-04-11 22:14:25 +08:00
|
|
|
['%m-%y', function (d) {
|
|
|
|
return d.getMonth()
|
|
|
|
}]
|
|
|
|
]
|
|
|
|
},
|
|
|
|
classDiagram: {},
|
|
|
|
gitGraph: {},
|
|
|
|
info: {}
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger.setLogLevel(config.logLevel)
|
2015-10-04 19:30:53 +02:00
|
|
|
|
2015-05-26 20:59:23 +02:00
|
|
|
/**
|
2015-09-26 12:09:47 +02:00
|
|
|
* ## parse
|
|
|
|
* Function that parses a mermaid diagram definition. If parsing fails the parseError callback is called and an error is
|
2015-05-26 20:59:23 +02:00
|
|
|
* thrown and
|
|
|
|
* @param text
|
|
|
|
*/
|
2017-04-11 22:14:25 +08:00
|
|
|
var parse = function (text) {
|
|
|
|
var graphType = utils.detectType(text)
|
|
|
|
var parser
|
|
|
|
|
|
|
|
switch (graphType) {
|
|
|
|
case 'gitGraph':
|
|
|
|
parser = gitGraphParser
|
|
|
|
parser.parser.yy = gitGraphAst
|
|
|
|
break
|
|
|
|
case 'graph':
|
|
|
|
parser = flowParser
|
|
|
|
parser.parser.yy = graph
|
|
|
|
break
|
|
|
|
case 'dotGraph':
|
|
|
|
parser = dotParser
|
|
|
|
parser.parser.yy = graph
|
|
|
|
break
|
|
|
|
case 'sequenceDiagram':
|
|
|
|
parser = sequenceParser
|
|
|
|
parser.parser.yy = sequenceDb
|
|
|
|
break
|
|
|
|
case 'info':
|
|
|
|
parser = infoParser
|
|
|
|
parser.parser.yy = infoDb
|
|
|
|
break
|
|
|
|
case 'gantt':
|
|
|
|
parser = ganttParser
|
|
|
|
parser.parser.yy = ganttDb
|
|
|
|
break
|
|
|
|
case 'classDiagram':
|
|
|
|
parser = classParser
|
|
|
|
parser.parser.yy = classDb
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2017-09-10 00:29:22 +08:00
|
|
|
parser.parser.yy.parseError = (err, hash) => {
|
|
|
|
module.exports.eventEmitter.emit('parseError', err, hash)
|
|
|
|
}
|
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
try {
|
|
|
|
parser.parse(text)
|
|
|
|
return true
|
|
|
|
} catch (err) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
2017-09-09 17:08:52 +08:00
|
|
|
module.exports.parse = parse
|
2015-05-26 20:59:23 +02:00
|
|
|
|
|
|
|
/**
|
2015-09-26 12:09:47 +02:00
|
|
|
* ## version
|
2015-05-26 20:59:23 +02:00
|
|
|
* Function returning version information
|
|
|
|
* @returns {string} A string containing the version info
|
|
|
|
*/
|
2017-09-09 17:08:52 +08:00
|
|
|
module.exports.version = function () {
|
2017-04-11 22:14:25 +08:00
|
|
|
return require('../package.json').version
|
|
|
|
}
|
|
|
|
|
2017-09-09 17:08:52 +08:00
|
|
|
module.exports.encodeEntities = function (text) {
|
2017-04-11 22:14:25 +08:00
|
|
|
var txt = text
|
|
|
|
|
|
|
|
txt = txt.replace(/style.*:\S*#.*;/g, function (s) {
|
|
|
|
var innerTxt = s.substring(0, s.length - 1)
|
|
|
|
return innerTxt
|
|
|
|
})
|
|
|
|
txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) {
|
|
|
|
var innerTxt = s.substring(0, s.length - 1)
|
|
|
|
return innerTxt
|
|
|
|
})
|
|
|
|
|
2017-04-11 23:31:59 +08:00
|
|
|
txt = txt.replace(/#\w+;/g, function (s) {
|
2017-04-11 22:14:25 +08:00
|
|
|
var innerTxt = s.substring(1, s.length - 1)
|
|
|
|
|
|
|
|
var isInt = /^\+?\d+$/.test(innerTxt)
|
|
|
|
if (isInt) {
|
|
|
|
return 'fl°°' + innerTxt + '¶ß'
|
|
|
|
} else {
|
|
|
|
return 'fl°' + innerTxt + '¶ß'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return txt
|
|
|
|
}
|
|
|
|
|
2017-09-09 17:08:52 +08:00
|
|
|
module.exports.decodeEntities = function (text) {
|
2017-04-11 22:14:25 +08:00
|
|
|
var txt = text
|
|
|
|
|
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-09-26 12:09:47 +02:00
|
|
|
* ##render
|
2015-07-17 23:13:40 +02:00
|
|
|
* Function that renders an svg with a graph from a chart definition. Usage example below.
|
|
|
|
*
|
|
|
|
* ```
|
|
|
|
* mermaidAPI.initialize({
|
|
|
|
* startOnLoad:true
|
|
|
|
* });
|
|
|
|
* $(function(){
|
|
|
|
* var graphDefinition = 'graph TB\na-->b';
|
|
|
|
* var cb = function(svgGraph){
|
|
|
|
* 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-04-11 22:14:25 +08:00
|
|
|
var render = function (id, txt, cb, container) {
|
|
|
|
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-09 17:08:52 +08:00
|
|
|
txt = module.exports.encodeEntities(txt)
|
2017-04-11 22:14:25 +08:00
|
|
|
|
|
|
|
var element = d3.select('#d' + id).node()
|
|
|
|
var graphType = utils.detectType(txt)
|
|
|
|
var classes = {}
|
|
|
|
switch (graphType) {
|
|
|
|
case 'gitGraph':
|
|
|
|
config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
gitGraphRenderer.setConf(config.gitGraph)
|
|
|
|
gitGraphRenderer.draw(txt, id, false)
|
|
|
|
break
|
|
|
|
case 'graph':
|
|
|
|
config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
flowRenderer.setConf(config.flowchart)
|
|
|
|
flowRenderer.draw(txt, id, false)
|
|
|
|
if (config.cloneCssStyles) {
|
|
|
|
classes = flowRenderer.getClasses(txt, false)
|
|
|
|
utils.cloneCssStyles(element.firstChild, classes)
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'dotGraph':
|
|
|
|
config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
flowRenderer.setConf(config.flowchart)
|
|
|
|
flowRenderer.draw(txt, id, true)
|
|
|
|
if (config.cloneCssStyles) {
|
|
|
|
classes = flowRenderer.getClasses(txt, true)
|
|
|
|
utils.cloneCssStyles(element.firstChild, classes)
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'sequenceDiagram':
|
|
|
|
config.sequenceDiagram.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
seq.setConf(config.sequenceDiagram)
|
|
|
|
seq.draw(txt, id)
|
|
|
|
if (config.cloneCssStyles) {
|
|
|
|
utils.cloneCssStyles(element.firstChild, [])
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'gantt':
|
|
|
|
config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
gantt.setConf(config.gantt)
|
|
|
|
gantt.draw(txt, id)
|
|
|
|
if (config.cloneCssStyles) {
|
|
|
|
utils.cloneCssStyles(element.firstChild, [])
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'classDiagram':
|
|
|
|
config.classDiagram.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
|
|
|
classRenderer.setConf(config.classDiagram)
|
|
|
|
classRenderer.draw(txt, id)
|
|
|
|
if (config.cloneCssStyles) {
|
|
|
|
utils.cloneCssStyles(element.firstChild, [])
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'info':
|
|
|
|
config.info.arrowMarkerAbsolute = config.arrowMarkerAbsolute
|
2017-09-09 17:08:52 +08:00
|
|
|
info.draw(txt, id, module.exports.version())
|
2017-04-11 22:14:25 +08:00
|
|
|
if (config.cloneCssStyles) {
|
|
|
|
utils.cloneCssStyles(element.firstChild, [])
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
d3.select('#d' + id).selectAll('foreignobject div').attr('xmlns', 'http://www.w3.org/1999/xhtml')
|
|
|
|
|
|
|
|
var url = ''
|
|
|
|
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-04-11 22:14:25 +08:00
|
|
|
var 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-09 17:08:52 +08:00
|
|
|
svgCode = module.exports.decodeEntities(svgCode)
|
2015-10-04 21:18:05 +02:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
if (typeof cb !== 'undefined') {
|
|
|
|
cb(svgCode, graph.bindFunctions)
|
|
|
|
} else {
|
|
|
|
log.warn('CB = undefined!')
|
|
|
|
}
|
2015-06-16 10:40:08 +02:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
var node = d3.select('#d' + id).node()
|
|
|
|
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-09 17:08:52 +08:00
|
|
|
module.exports.render = function (id, text, cb, containerElement) {
|
2017-04-11 22:14:25 +08:00
|
|
|
try {
|
|
|
|
if (arguments.length === 1) {
|
|
|
|
text = id
|
|
|
|
id = 'mermaidId0'
|
|
|
|
}
|
2015-11-22 18:10:38 +01:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
if (typeof document === 'undefined') {
|
2017-04-16 23:24:47 +08:00
|
|
|
// Todo handle rendering serverside using phantomjs
|
2017-04-11 22:14:25 +08:00
|
|
|
} else {
|
2017-04-16 23:24:47 +08:00
|
|
|
// In browser
|
2017-04-11 22:14:25 +08:00
|
|
|
return render(id, text, cb, containerElement)
|
2015-05-26 20:59:23 +02:00
|
|
|
}
|
2017-04-11 22:14:25 +08:00
|
|
|
} catch (e) {
|
|
|
|
log.warn(e)
|
|
|
|
}
|
|
|
|
}
|
2015-05-26 20:59:23 +02:00
|
|
|
|
2017-04-11 22:14:25 +08:00
|
|
|
var setConf = function (cnf) {
|
2017-04-16 23:24:47 +08:00
|
|
|
// Top level initially mermaid, gflow, sequenceDiagram and gantt
|
2017-04-11 22:14:25 +08:00
|
|
|
var lvl1Keys = Object.keys(cnf)
|
|
|
|
var i
|
|
|
|
for (i = 0; i < lvl1Keys.length; i++) {
|
|
|
|
if (typeof cnf[lvl1Keys[i]] === 'object') {
|
|
|
|
var lvl2Keys = Object.keys(cnf[lvl1Keys[i]])
|
|
|
|
|
|
|
|
var j
|
|
|
|
for (j = 0; j < lvl2Keys.length; j++) {
|
|
|
|
log.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j])
|
|
|
|
if (typeof config[lvl1Keys[i]] === 'undefined') {
|
|
|
|
config[lvl1Keys[i]] = {}
|
2015-05-30 17:20:24 +02:00
|
|
|
}
|
2017-04-11 22:14:25 +08:00
|
|
|
log.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]])
|
|
|
|
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-09 17:08:52 +08:00
|
|
|
module.exports.initialize = function (options) {
|
2017-04-11 22:14:25 +08:00
|
|
|
log.debug('Initializing mermaidAPI')
|
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)
|
|
|
|
}
|
|
|
|
Logger.setLogLevel(config.logLevel)
|
|
|
|
}
|
2017-09-09 17:08:52 +08:00
|
|
|
module.exports.getConfig = function () {
|
2017-04-11 22:14:25 +08:00
|
|
|
return config
|
|
|
|
}
|
|
|
|
|
2017-09-09 17:08:52 +08:00
|
|
|
module.exports.parseError = function (err, hash) {
|
2017-04-11 22:14:25 +08:00
|
|
|
if (typeof mermaid !== 'undefined') {
|
|
|
|
global.mermaid.parseError(err, hash)
|
|
|
|
} else {
|
|
|
|
log.debug('Mermaid Syntax error:')
|
|
|
|
log.debug(err)
|
|
|
|
}
|
|
|
|
}
|
2017-09-10 00:29:22 +08:00
|
|
|
|
2015-05-30 17:20:24 +02:00
|
|
|
global.mermaidAPI = {
|
2017-09-09 17:08:52 +08:00
|
|
|
render: module.exports.render,
|
|
|
|
parse: module.exports.parse,
|
|
|
|
initialize: module.exports.initialize,
|
2017-04-11 22:14:25 +08:00
|
|
|
detectType: utils.detectType,
|
2017-09-09 17:08:52 +08:00
|
|
|
parseError: module.exports.parseError,
|
2017-09-10 00:29:22 +08:00
|
|
|
getConfig: module.exports.getConfig,
|
|
|
|
eventEmitter: module.exports.eventEmitter
|
2017-04-11 22:14:25 +08:00
|
|
|
}
|