Merge branch 'develop' of github.com:mermaid-js/mermaid into develop

This commit is contained in:
Knut Sveidqvist
2020-02-05 19:40:18 +01:00
6 changed files with 123 additions and 83 deletions

View File

@@ -512,7 +512,7 @@ describe('Flowchart', () => {
); );
}); });
it('24.1: Keep node label text (if already defined) when a style is applied', () => { it('24: Keep node label text (if already defined) when a style is applied', () => {
imgSnapshotTest( imgSnapshotTest(
`graph LR `graph LR
A(( )) -->|step 1| B(( )) A(( )) -->|step 1| B(( ))
@@ -524,7 +524,7 @@ describe('Flowchart', () => {
{ flowchart: { htmlLabels: false } } { flowchart: { htmlLabels: false } }
); );
}); });
it('24.2: Handle link click events (link, anchor, mailto, other protocol, script)', () => { it('25: Handle link click events (link, anchor, mailto, other protocol, script)', () => {
imgSnapshotTest( imgSnapshotTest(
`graph TB `graph TB
TITLE["Link Click Events<br>(click the nodes below)"] TITLE["Link Click Events<br>(click the nodes below)"]
@@ -544,11 +544,15 @@ it('24.2: Handle link click events (link, anchor, mailto, other protocol, script
); );
}); });
it('25: Set node text color according to style when html labels are enabled', () => { it('26: Set text color of nodes and links according to styles when html labels are enabled', () => {
imgSnapshotTest( imgSnapshotTest(
`graph LR `graph LR
A[red<br>text] --> B(blue<br>text) A[red<br>text] -->|red<br>text| B(blue<br>text)
C[/red<br/>text/] --> D{blue<br/>text} C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
E{{default<br />style}} -->|default<br />style| F([default<br />style])
linkStyle default color:Sienna;
linkStyle 0 color:red;
linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
style A color:red; style A color:red;
style B color:blue; style B color:blue;
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000 style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
@@ -560,11 +564,15 @@ it('24.2: Handle link click events (link, anchor, mailto, other protocol, script
); );
}); });
it('26: Set node text color according to style when html labels are disabled', () => { it('27: Set text color of nodes and links according to styles when html labels are disabled', () => {
imgSnapshotTest( imgSnapshotTest(
`graph LR `graph LR
A[red<br>text] --> B(blue<br>text) A[red<br>text] -->|red<br>text| B(blue<br>text)
C[/red<br/>text/] --> D{blue<br/>text} C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
E{{default<br />style}} -->|default<br />style| F([default<br />style])
linkStyle default color:Sienna;
linkStyle 0 color:red;
linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
style A color:red; style A color:red;
style B color:blue; style B color:blue;
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000 style C stroke:#ff0000,fill:#ffcccc,color:#ff0000

8
dist/index.html vendored
View File

@@ -371,8 +371,12 @@ graph TB
<hr/> <hr/>
<div class="mermaid"> <div class="mermaid">
graph LR graph LR
A[red<br>text] --> B(blue<br>text) A[red<br>text] -->|red<br>text| B(blue<br>text)
C[/red<br/>text/] --> D{blue<br/>text} C[/red<br/>text/] -->|blue<br/>text| D{blue<br/>text}
E{{default<br />style}} -->|default<br />style| F([default<br />style])
linkStyle default color:Sienna;
linkStyle 0 color:red;
linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
style A color:red; style A color:red;
style B color:blue; style B color:blue;
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000 style C stroke:#ff0000,fill:#ffcccc,color:#ff0000

View File

@@ -497,7 +497,7 @@ Instead of ids, the order number of when the link was defined in the graph is us
defined in the linkStyle statement will belong to the fourth link in the graph: defined in the linkStyle statement will belong to the fourth link in the graph:
``` ```
linkStyle 3 stroke:#ff3,stroke-width:4px; linkStyle 3 stroke:#ff3,stroke-width:4px,color:red;
``` ```

View File

@@ -8,7 +8,7 @@ import { getConfig } from '../../config';
import dagreD3 from 'dagre-d3'; import dagreD3 from 'dagre-d3';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { logger } from '../../logger'; import { logger } from '../../logger';
import { interpolateToCurve } from '../../utils'; import { interpolateToCurve, getStylesFromArray } from '../../utils';
import flowChartShapes from './flowChartShapes'; import flowChartShapes from './flowChartShapes';
const conf = {}; const conf = {};
@@ -28,25 +28,6 @@ export const addVertices = function(vert, g, svgId) {
const svg = d3.select(`[id="${svgId}"]`); const svg = d3.select(`[id="${svgId}"]`);
const keys = Object.keys(vert); const keys = Object.keys(vert);
const styleFromStyleArr = function(styleStr, arr, { label }) {
if (!label) {
// Create a compound style definition from the style definitions found for the node in the graph definition
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] !== 'undefined') {
styleStr = styleStr + arr[i] + ';';
}
}
} else {
// create the style definition for the text, if property is a text-property
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] !== 'undefined') {
if (arr[i].match('^color:|^text-align:')) styleStr = styleStr + arr[i] + ';';
}
}
}
return styleStr;
};
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition // Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
keys.forEach(function(id) { keys.forEach(function(id) {
const vertex = vert[id]; const vertex = vert[id];
@@ -60,15 +41,7 @@ export const addVertices = function(vert, g, svgId) {
classStr = vertex.classes.join(' '); classStr = vertex.classes.join(' ');
} }
/** const styles = getStylesFromArray(vertex.styles);
* Variable for storing the extracted style for the vertex
* @type {string}
*/
let style = '';
// Create a compound style definition from the style definitions found for the node in the graph definition
style = styleFromStyleArr(style, vertex.styles, { label: false });
let labelStyle = '';
labelStyle = styleFromStyleArr(labelStyle, vertex.styles, { label: true });
// Use vertex id as text in the box if no text is provided by the graph definition // Use vertex id as text in the box if no text is provided by the graph definition
let vertexText = vertex.text !== undefined ? vertex.text : vertex.id; let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
@@ -87,7 +60,7 @@ export const addVertices = function(vert, g, svgId) {
vertexNode.parentNode.removeChild(vertexNode); vertexNode.parentNode.removeChild(vertexNode);
} else { } else {
const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text'); const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text');
svgLabel.setAttribute('style', labelStyle.replace('color:', 'fill:')); svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
const rows = vertexText.split(/<br\s*\/?>/gi); const rows = vertexText.split(/<br\s*\/?>/gi);
@@ -158,13 +131,13 @@ export const addVertices = function(vert, g, svgId) {
// Add the node // Add the node
g.setNode(vertex.id, { g.setNode(vertex.id, {
labelType: 'svg', labelType: 'svg',
labelStyle: labelStyle, labelStyle: styles.labelStyle,
shape: _shape, shape: _shape,
label: vertexNode, label: vertexNode,
rx: radious, rx: radious,
ry: radious, ry: radious,
class: classStr, class: classStr,
style: style, style: styles.style,
id: vertex.id id: vertex.id
}); });
}); });
@@ -179,8 +152,12 @@ export const addEdges = function(edges, g) {
let cnt = 0; let cnt = 0;
let defaultStyle; let defaultStyle;
let defaultLabelStyle;
if (typeof edges.defaultStyle !== 'undefined') { if (typeof edges.defaultStyle !== 'undefined') {
defaultStyle = edges.defaultStyle.toString().replace(/,/g, ';'); const defaultStyles = getStylesFromArray(edges.defaultStyle);
defaultStyle = defaultStyles.style;
defaultLabelStyle = defaultStyles.labelStyle;
} }
edges.forEach(function(edge) { edges.forEach(function(edge) {
@@ -195,10 +172,12 @@ export const addEdges = function(edges, g) {
} }
let style = ''; let style = '';
let labelStyle = '';
if (typeof edge.style !== 'undefined') { if (typeof edge.style !== 'undefined') {
edge.style.forEach(function(s) { const styles = getStylesFromArray(edge.style);
style = style + s + ';'; style = styles.style;
}); labelStyle = styles.labelStyle;
} else { } else {
switch (edge.stroke) { switch (edge.stroke) {
case 'normal': case 'normal':
@@ -206,6 +185,9 @@ export const addEdges = function(edges, g) {
if (typeof defaultStyle !== 'undefined') { if (typeof defaultStyle !== 'undefined') {
style = defaultStyle; style = defaultStyle;
} }
if (typeof defaultLabelStyle !== 'undefined') {
labelStyle = defaultLabelStyle;
}
break; break;
case 'dotted': case 'dotted':
style = 'fill:none;stroke-width:2px;stroke-dasharray:3;'; style = 'fill:none;stroke-width:2px;stroke-dasharray:3;';
@@ -215,7 +197,9 @@ export const addEdges = function(edges, g) {
break; break;
} }
} }
edgeData.style = style; edgeData.style = style;
edgeData.labelStyle = labelStyle;
if (typeof edge.interpolate !== 'undefined') { if (typeof edge.interpolate !== 'undefined') {
edgeData.curve = interpolateToCurve(edge.interpolate, d3.curveLinear); edgeData.curve = interpolateToCurve(edge.interpolate, d3.curveLinear);
@@ -243,6 +227,8 @@ export const addEdges = function(edges, g) {
if (typeof edge.style === 'undefined') { if (typeof edge.style === 'undefined') {
edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none'; edgeData.style = edgeData.style || 'stroke: #333; stroke-width: 1.5px;fill:none';
} }
edgeData.labelStyle = edgeData.labelStyle.replace('color:', 'fill:');
} }
} }
// Add the edge to the graph // Add the edge to the graph

View File

@@ -92,17 +92,12 @@ describe('the flowchart renderer', function() {
expect(addedNodes[0][1].label.lastChild.innerHTML).toEqual('Line'); // <tspan> node, line 2 expect(addedNodes[0][1].label.lastChild.innerHTML).toEqual('Line'); // <tspan> node, line 2
}); });
}); });
});
[ [
[['fill:#fff'], 'fill:#fff;', ''], [['fill:#fff'], 'fill:#fff;', ''],
[['color:#ccc'], 'color:#ccc;', 'color:#ccc;'], [['color:#ccc'], '', 'color:#ccc;'],
[['fill:#fff', 'color:#ccc'], 'fill:#fff;color:#ccc;', 'color:#ccc;'], [['fill:#fff', 'color:#ccc'], 'fill:#fff;', 'color:#ccc;'],
[ [['fill:#fff', 'color:#ccc', 'text-align:center'], 'fill:#fff;', 'color:#ccc;text-align:center;']
['fill:#fff', 'color:#ccc', 'text-align:center'],
'fill:#fff;color:#ccc;text-align:center;',
'color:#ccc;text-align:center;'
]
].forEach(function([style, expectedStyle, expectedLabelStyle]) { ].forEach(function([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function() { it(`should add the styles to style and/or labelStyle for style ${style}`, function() {
const addedNodes = []; const addedNodes = [];
@@ -132,6 +127,7 @@ describe('the flowchart renderer', function() {
expect(addedNodes[0][1]).toHaveProperty('labelStyle', expectedLabelStyle); expect(addedNodes[0][1]).toHaveProperty('labelStyle', expectedLabelStyle);
}); });
}); });
});
describe('when adding edges to a graph', function() { describe('when adding edges to a graph', function() {
it('should handle multiline texts and set centered label position', function() { it('should handle multiline texts and set centered label position', function() {
@@ -161,5 +157,32 @@ describe('the flowchart renderer', function() {
expect(edge).toHaveProperty('labelpos', 'c'); expect(edge).toHaveProperty('labelpos', 'c');
}); });
}); });
[
[['stroke:DarkGray'], 'stroke:DarkGray;', ''],
[['color:red'], '', 'fill:red;'],
[['stroke:DarkGray', 'color:red'], 'stroke:DarkGray;', 'fill:red;'],
[['stroke:DarkGray', 'color:red', 'stroke-width:2px'], 'stroke:DarkGray;stroke-width:2px;', 'fill:red;']
].forEach(function([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function() {
const addedEdges = [];
const mockG = {
setEdge: function(s, e, data, c) {
addedEdges.push(data);
}
};
addEdges(
[
{ style: style, text: 'styling' }
],
mockG,
'svg-id'
);
expect(addedEdges).toHaveLength(1);
expect(addedEdges[0]).toHaveProperty('style', expectedStyle);
expect(addedEdges[0]).toHaveProperty('labelStyle', expectedLabelStyle);
});
});
}); });
}); });

View File

@@ -201,6 +201,24 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition)
return cardinalityPosition; return cardinalityPosition;
}; };
export const getStylesFromArray = arr => {
let style = '';
let labelStyle = '';
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] !== 'undefined') {
// add text properties to label style definition
if (arr[i].startsWith('color:') || arr[i].startsWith('text-align:')) {
labelStyle = labelStyle + arr[i] + ';';
} else {
style = style + arr[i] + ';';
}
}
}
return { style: style, labelStyle: labelStyle };
};
export default { export default {
detectType, detectType,
isSubstringInArray, isSubstringInArray,
@@ -208,5 +226,6 @@ export default {
calcLabelPosition, calcLabelPosition,
calcCardinalityPosition, calcCardinalityPosition,
sanitize, sanitize,
formatUrl formatUrl,
getStylesFromArray
}; };