diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js index 94843de35..b62c3ecbe 100644 --- a/src/diagrams/flowchart/flowRenderer.js +++ b/src/diagrams/flowchart/flowRenderer.js @@ -8,7 +8,7 @@ import { getConfig } from '../../config'; import dagreD3 from 'dagre-d3'; import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js'; import { logger } from '../../logger'; -import { interpolateToCurve } from '../../utils'; +import { interpolateToCurve, getStylesFromArray } from '../../utils'; import flowChartShapes from './flowChartShapes'; const conf = {}; @@ -28,25 +28,6 @@ export const addVertices = function(vert, g, svgId) { const svg = d3.select(`[id="${svgId}"]`); 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 keys.forEach(function(id) { const vertex = vert[id]; @@ -60,15 +41,7 @@ export const addVertices = function(vert, g, svgId) { classStr = vertex.classes.join(' '); } - /** - * 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 }); + const styles = getStylesFromArray(vertex.styles); // 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; @@ -87,7 +60,7 @@ export const addVertices = function(vert, g, svgId) { vertexNode.parentNode.removeChild(vertexNode); } else { 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(//gi); @@ -158,13 +131,13 @@ export const addVertices = function(vert, g, svgId) { // Add the node g.setNode(vertex.id, { labelType: 'svg', - labelStyle: labelStyle, + labelStyle: styles.labelStyle, shape: _shape, label: vertexNode, rx: radious, ry: radious, class: classStr, - style: style, + style: styles.style, id: vertex.id }); }); @@ -176,25 +149,6 @@ export const addVertices = function(vert, g, svgId) { * @param {Object} g The graph object */ export const addEdges = function(edges, g) { - 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].startsWith('color:')) styleStr = styleStr + arr[i] + ';'; - } - } - } - return styleStr; - }; - let cnt = 0; let defaultStyle; @@ -217,8 +171,9 @@ export const addEdges = function(edges, g) { let labelStyle = ''; if (typeof edge.style !== 'undefined') { - style = styleFromStyleArr(style, edge.style, { label: false }); - labelStyle = styleFromStyleArr(labelStyle, edge.style, { label: true }); + const styles = getStylesFromArray(edge.style); + style = styles.style; + labelStyle = styles.labelStyle; } else { switch (edge.stroke) { case 'normal': diff --git a/src/diagrams/flowchart/flowRenderer.spec.js b/src/diagrams/flowchart/flowRenderer.spec.js index d691840ed..e3980ef1f 100644 --- a/src/diagrams/flowchart/flowRenderer.spec.js +++ b/src/diagrams/flowchart/flowRenderer.spec.js @@ -92,44 +92,40 @@ describe('the flowchart renderer', function() { expect(addedNodes[0][1].label.lastChild.innerHTML).toEqual('Line'); // 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;color:#ccc;text-align:center;', - 'color:#ccc;text-align:center;' - ] - ].forEach(function([style, expectedStyle, expectedLabelStyle]) { - it(`should add the styles to style and/or labelStyle for style ${style}`, function() { - const addedNodes = []; - const mockG = { - setNode: function(id, object) { - addedNodes.push([id, object]); - } - }; - addVertices( - { - v1: { - type: 'rect', - id: 'my-node-id', - classes: [], - styles: style, - text: 'my vertex text' + [['fill:#fff'], '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;'] + ].forEach(function([style, expectedStyle, expectedLabelStyle]) { + it(`should add the styles to style and/or labelStyle for style ${style}`, function() { + const addedNodes = []; + const mockG = { + setNode: function(id, object) { + addedNodes.push([id, object]); } - }, - 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); + }; + addVertices( + { + v1: { + type: 'rect', + id: 'my-node-id', + classes: [], + styles: style, + text: 'my vertex text' + } + }, + 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'); }); }); + + [ + [['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); + }); + }); }); }); diff --git a/src/utils.js b/src/utils.js index 38010c41f..002dcc8b7 100644 --- a/src/utils.js +++ b/src/utils.js @@ -201,6 +201,24 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition) 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 { detectType, isSubstringInArray, @@ -208,5 +226,6 @@ export default { calcLabelPosition, calcCardinalityPosition, sanitize, - formatUrl + formatUrl, + getStylesFromArray };