From 5b2f9351c77b26a539fcf323d239d93de0aa5d38 Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Mon, 9 Dec 2019 18:13:06 -0800 Subject: [PATCH] Add support for abstract methods Added logic to allow rendering of a method name with italics or underline based on modifier at beginning of name to set css style --- .../rendering/classDiagram.spec.js | 4 +-- docs/classDiagram.md | 6 ++-- src/diagrams/class/classDb.js | 2 +- src/diagrams/class/classDiagram.spec.js | 8 ++--- src/diagrams/class/classRenderer.js | 30 +++++++++++-------- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index b2a0f6e0a..b4ec832e3 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -169,7 +169,7 @@ describe('Class diagram', () => { ` classDiagram Class01 <|-- AveryLongClass : Cool - Class01 : |someMethod() + Class01 : someMethod()* `, {} ); @@ -181,7 +181,7 @@ describe('Class diagram', () => { ` classDiagram Class01 <|-- AveryLongClass : Cool - Class01 : $someMethod() + Class01 : someMethod()$ `, {} ); diff --git a/docs/classDiagram.md b/docs/classDiagram.md index c86685baf..dc61f79cf 100644 --- a/docs/classDiagram.md +++ b/docs/classDiagram.md @@ -155,9 +155,9 @@ To specify the visibility of a class member (i.e. any attribute or method), thes - `#` Protected - `~` Package ->_note_ you can also add additional _classifers_ to a method definition using the following notations (similar to visibliity above): -> - `|` Abstract e.g.: `|someAbstractMethod()` -> - `$` Static e.g.: `$someStaticMethod()` +>_note_ you can also include additional _classifers_ 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()$` ## Defining Relationship diff --git a/src/diagrams/class/classDb.js b/src/diagrams/class/classDb.js index 6cfbcf3f4..c04c3a78b 100644 --- a/src/diagrams/class/classDb.js +++ b/src/diagrams/class/classDb.js @@ -72,7 +72,7 @@ export const addMember = function(className, member) { if (memberString.startsWith('<<') && memberString.endsWith('>>')) { // Remove leading and trailing brackets theClass.annotations.push(memberString.substring(2, memberString.length - 2)); - } else if (memberString.endsWith(')')) { + } else if (memberString.indexOf(')') > 0) { theClass.methods.push(memberString); } else if (memberString) { theClass.members.push(memberString); diff --git a/src/diagrams/class/classDiagram.spec.js b/src/diagrams/class/classDiagram.spec.js index 7c9252dc7..ebdf381b0 100644 --- a/src/diagrams/class/classDiagram.spec.js +++ b/src/diagrams/class/classDiagram.spec.js @@ -402,25 +402,25 @@ describe('class diagram, ', function () { }); it('should handle abstract methods', function () { - const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : |someMethod()'; + const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()*'; parser.parse(str); const testClass = parser.yy.getClass('Class1'); expect(testClass.annotations.length).toBe(0); expect(testClass.members.length).toBe(0); expect(testClass.methods.length).toBe(1); - expect(testClass.methods[0]).toBe('|someMethod()'); + expect(testClass.methods[0]).toBe('someMethod()*'); }); it('should handle static methods', function () { - const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : $someMethod()'; + const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()$'; parser.parse(str); const testClass = parser.yy.getClass('Class1'); expect(testClass.annotations.length).toBe(0); expect(testClass.members.length).toBe(0); expect(testClass.methods.length).toBe(1); - expect(testClass.methods[0]).toBe('$someMethod()'); + expect(testClass.methods[0]).toBe('someMethod()$'); }); }); }); diff --git a/src/diagrams/class/classRenderer.js b/src/diagrams/class/classRenderer.js index 78a4c4332..9184574dd 100644 --- a/src/diagrams/class/classRenderer.js +++ b/src/diagrams/class/classRenderer.js @@ -283,24 +283,28 @@ const drawClass = function(elem, classDef) { const addTspan = function(textEl, txt, isFirst) { let displayText = txt; let cssStyle = ''; - let classifier = txt.substring(0 , 1); - - switch (classifier) { - case '|': - cssStyle = 'font-style:italic;'; - displayText = txt.substring(1); - break; - case '$': - cssStyle = 'text-decoration:underline;'; - displayText = txt.substring(1); - break; + let methodEnd = txt.indexOf(')') + 1; + + if (methodEnd > 1 && methodEnd <= txt.length) { + let classifier = txt.substring(methodEnd); + + switch (classifier) { + case '*': + cssStyle = 'font-style:italic;'; + break; + case '$': + cssStyle = 'text-decoration:underline;'; + break; + } + + displayText = txt.substring(0, methodEnd); } - + const tSpan = textEl .append('tspan') .attr('x', conf.padding) .text(displayText); - + if (cssStyle !== '') { tSpan.attr('style', cssStyle); }