diff --git a/cypress/integration/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js index 66fd1c51f..eea11aaf3 100644 --- a/cypress/integration/rendering/classDiagram-v2.spec.js +++ b/cypress/integration/rendering/classDiagram-v2.spec.js @@ -370,7 +370,21 @@ describe('Class diagram V2', () => { ); cy.get('svg'); }); - it('16: should handle the direction statemment with TB', () => { + + it('16a: should render a simple class diagram with static field', () => { + imgSnapshotTest( + ` + classDiagram-v2 + Foo { + +String bar$ + } + `, + {logLevel : 1, flowchart: { "htmlLabels": false },} + ); + cy.get('svg'); + }); + + it('16b: should handle the direction statemnent with TB', () => { imgSnapshotTest( ` classDiagram @@ -394,55 +408,8 @@ describe('Class diagram V2', () => { ); cy.get('svg'); }); - it('17: should handle the direction statemment with BT', () => { - imgSnapshotTest( - ` - classDiagram - direction BT - class Student { - -idCard : IdCard - } - class IdCard{ - -id : int - -name : string - } - class Bike{ - -id : int - -name : string - } - Student "1" --o "1" IdCard : carries - Student "1" --o "1" Bike : rides - - `, - {logLevel : 1, flowchart: { "htmlLabels": false },} - ); - cy.get('svg'); - }); - it('17: should handle the direction statemment with RL', () => { - imgSnapshotTest( - ` - classDiagram - direction RL - class Student { - -idCard : IdCard - } - class IdCard{ - -id : int - -name : string - } - class Bike{ - -id : int - -name : string - } - Student "1" --o "1" IdCard : carries - Student "1" --o "1" Bike : rides - - `, - {logLevel : 1, flowchart: { "htmlLabels": false },} - ); - cy.get('svg'); - }); - it('18: should handle the direction statemment with LR', () => { + + it('18: should handle the direction statemnent with LR', () => { imgSnapshotTest( ` classDiagram @@ -466,4 +433,52 @@ describe('Class diagram V2', () => { ); cy.get('svg'); }); + it('17a: should handle the direction statemnent with BT', () => { + imgSnapshotTest( + ` + classDiagram + direction BT + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + {logLevel : 1, flowchart: { "htmlLabels": false },} + ); + cy.get('svg'); + }); + it('17b: should handle the direction statemment with RL', () => { + imgSnapshotTest( + ` + classDiagram + direction RL + class Student { + -idCard : IdCard + } + class IdCard{ + -id : int + -name : string + } + class Bike{ + -id : int + -name : string + } + Student "1" --o "1" IdCard : carries + Student "1" --o "1" Bike : rides + + `, + {logLevel : 1, flowchart: { "htmlLabels": false },} + ); + cy.get('svg'); + }); }); diff --git a/docs/classDiagram.md b/docs/classDiagram.md index 21ea40856..46082fe6f 100644 --- a/docs/classDiagram.md +++ b/docs/classDiagram.md @@ -228,10 +228,14 @@ To specify the visibility of a class member (i.e. any attribute or method), thes - `~` Package/Internal > _note_ you can also include additional _classifiers_ to a method definition by adding the following notations to the end of the method, i.e.: after the `()`: - > - `*` Abstract e.g.: `someAbstractMethod()*` > - `$` Static e.g.: `someStaticMethod()$` +> _note_ you can also include additional _classifiers_ to a field definition by adding the following notations to the end of the field name: +> - `*` Static e.g.: `String someField$` + + + ## Defining Relationship A relationship is a general term covering the specific types of logical connections found on class and object diagrams. diff --git a/src/dagre-wrapper/nodes.js b/src/dagre-wrapper/nodes.js index dca4fd225..507b493db 100644 --- a/src/dagre-wrapper/nodes.js +++ b/src/dagre-wrapper/nodes.js @@ -672,13 +672,21 @@ const class_box = (parent, node) => { } const classAttributes = []; node.classData.members.forEach((str) => { - let parsedText = parseMember(str).displayText; + const parsedInfo = parseMember(str); + let parsedText = parsedInfo.displayText; if (getConfig().flowchart.htmlLabels) { parsedText = parsedText.replace(//g, '>'); } const lbl = labelContainer .node() - .appendChild(createLabel(parsedText, node.labelStyle, true, true)); + .appendChild( + createLabel( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); let bbox = lbl.getBBox(); if (evaluate(getConfig().flowchart.htmlLabels)) { const div = lbl.children[0]; diff --git a/src/diagrams/class/svgDraw.js b/src/diagrams/class/svgDraw.js index 5c58d0578..d9cd52161 100644 --- a/src/diagrams/class/svgDraw.js +++ b/src/diagrams/class/svgDraw.js @@ -274,7 +274,7 @@ export const drawClass = function (elem, classDef, conf) { }; export const parseMember = function (text) { - const fieldRegEx = /(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)/; + const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+) *(\*|\$)?$/; const methodRegEx = /^([+|\-|~|#])?(\w+) *\( *(.*)\) *(\*|\$)? *(\w*[~|[\]]*\s*\w*~?)$/; let fieldMatch = text.match(fieldRegEx); @@ -290,6 +290,7 @@ export const parseMember = function (text) { }; const buildFieldDisplay = function (parsedText) { + let cssStyle = ''; let displayText = ''; try { @@ -297,15 +298,17 @@ const buildFieldDisplay = function (parsedText) { let fieldType = parsedText[2] ? parsedText[2].trim() : ''; let genericType = parsedText[3] ? parseGenericTypes(parsedText[3].trim()) : ''; let fieldName = parsedText[4] ? parsedText[4].trim() : ''; + let classifier = parsedText[5] ? parsedText[5].trim() : ''; displayText = visibility + fieldType + genericType + ' ' + fieldName; + cssStyle = parseClassifier(classifier); } catch (err) { displayText = parsedText; } return { displayText: displayText, - cssStyle: '', + cssStyle: cssStyle, }; }; @@ -321,7 +324,6 @@ const buildMethodDisplay = function (parsedText) { let returnType = parsedText[5] ? ' : ' + parseGenericTypes(parsedText[5]).trim() : ''; displayText = visibility + methodName + '(' + parameters + ')' + returnType; - cssStyle = parseClassifier(classifier); } catch (err) { displayText = parsedText; diff --git a/src/diagrams/class/svgDraw.spec.js b/src/diagrams/class/svgDraw.spec.js index b6e26dbf8..ae5882349 100644 --- a/src/diagrams/class/svgDraw.spec.js +++ b/src/diagrams/class/svgDraw.spec.js @@ -51,7 +51,7 @@ describe('class member Renderer, ', function () { expect(actual.cssStyle).toBe(''); }); - it('should handle abstract classifier', function () { + it('should handle abstract method classifier', function () { const str = 'foo()*'; let actual = svgDraw.parseMember(str); @@ -59,7 +59,7 @@ describe('class member Renderer, ', function () { expect(actual.cssStyle).toBe('font-style:italic;'); }); - it('should handle static classifier', function () { + it('should handle static method classifier', function () { const str = 'foo()$'; let actual = svgDraw.parseMember(str); @@ -156,5 +156,13 @@ describe('class member Renderer, ', function () { expect(actual.displayText).toBe('List ids'); expect(actual.cssStyle).toBe(''); }); + + it('should handle static field classifier', function () { + const str = 'String foo$'; + let actual = svgDraw.parseMember(str); + + expect(actual.displayText).toBe('String foo'); + expect(actual.cssStyle).toBe('text-decoration:underline;'); + }); }); });