mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-15 13:29:40 +02:00
Merge branch 'develop' of github.com:mermaid-js/mermaid into develop
This commit is contained in:
@@ -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
8
dist/index.html
vendored
@@ -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
|
||||||
|
@@ -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;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -92,44 +92,40 @@ 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;', ''],
|
|
||||||
[['color:#ccc'], 'color:#ccc;', 'color:#ccc;'],
|
|
||||||
[['fill:#fff', 'color:#ccc'], 'fill:#fff;color:#ccc;', 'color:#ccc;'],
|
|
||||||
[
|
[
|
||||||
['fill:#fff', 'color:#ccc', 'text-align:center'],
|
[['fill:#fff'], 'fill:#fff;', ''],
|
||||||
'fill:#fff;color:#ccc;text-align:center;',
|
[['color:#ccc'], '', 'color:#ccc;'],
|
||||||
'color:#ccc;text-align:center;'
|
[['fill:#fff', 'color:#ccc'], 'fill:#fff;', 'color:#ccc;'],
|
||||||
]
|
[['fill:#fff', 'color:#ccc', 'text-align:center'], 'fill:#fff;', '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 = [];
|
||||||
const mockG = {
|
const mockG = {
|
||||||
setNode: function(id, object) {
|
setNode: function(id, object) {
|
||||||
addedNodes.push([id, object]);
|
addedNodes.push([id, object]);
|
||||||
}
|
|
||||||
};
|
|
||||||
addVertices(
|
|
||||||
{
|
|
||||||
v1: {
|
|
||||||
type: 'rect',
|
|
||||||
id: 'my-node-id',
|
|
||||||
classes: [],
|
|
||||||
styles: style,
|
|
||||||
text: 'my vertex text'
|
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
mockG,
|
addVertices(
|
||||||
'svg-id'
|
{
|
||||||
);
|
v1: {
|
||||||
expect(addedNodes).toHaveLength(1);
|
type: 'rect',
|
||||||
expect(addedNodes[0][0]).toEqual('my-node-id');
|
id: 'my-node-id',
|
||||||
expect(addedNodes[0][1]).toHaveProperty('id', 'my-node-id');
|
classes: [],
|
||||||
expect(addedNodes[0][1]).toHaveProperty('labelType', 'svg');
|
styles: style,
|
||||||
expect(addedNodes[0][1]).toHaveProperty('style', expectedStyle);
|
text: 'my vertex text'
|
||||||
expect(addedNodes[0][1]).toHaveProperty('labelStyle', expectedLabelStyle);
|
}
|
||||||
|
},
|
||||||
|
mockG,
|
||||||
|
'svg-id'
|
||||||
|
);
|
||||||
|
expect(addedNodes).toHaveLength(1);
|
||||||
|
expect(addedNodes[0][0]).toEqual('my-node-id');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('id', 'my-node-id');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('labelType', 'svg');
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('style', expectedStyle);
|
||||||
|
expect(addedNodes[0][1]).toHaveProperty('labelStyle', expectedLabelStyle);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
21
src/utils.js
21
src/utils.js
@@ -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
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user