diff --git a/.gitignore b/.gitignore index f2c5e76995..e89efdc5b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +# ignore this file on macOS .DS_Store node_modules/ @@ -6,4 +7,8 @@ coverage/ dist/*.js dist/*.map -yarn-error.log +# ignore all log files +*.log + +# ignore IDE files +.idea diff --git a/src/diagrams/class/classDiagram.spec.js b/src/diagrams/class/classDiagram.spec.js index 38657e11d2..8d5fad745c 100644 --- a/src/diagrams/class/classDiagram.spec.js +++ b/src/diagrams/class/classDiagram.spec.js @@ -1,5 +1,5 @@ /* eslint-env jasmine */ -import { parser } from './parser/classDiagram' +import {parser} from './parser/classDiagram' import classDb from './classDb' describe('class diagram, ', function () { @@ -10,95 +10,95 @@ describe('class diagram, ', function () { it('should handle relation definitions', function () { const str = 'classDiagram\n' + -'Class01 <|-- Class02\n' + -'Class03 *-- Class04\n' + -'Class05 o-- Class06\n' + -'Class07 .. Class08\n' + -'Class09 -- Class1' + 'Class01 <|-- Class02\n' + + 'Class03 *-- Class04\n' + + 'Class05 o-- Class06\n' + + 'Class07 .. Class08\n' + + 'Class09 -- Class1' parser.parse(str) }) it('should handle relation definition of different types and directions', function () { const str = 'classDiagram\n' + -'Class11 <|.. Class12\n' + -'Class13 --> Class14\n' + -'Class15 ..> Class16\n' + -'Class17 ..|> Class18\n' + -'Class19 <--* Class20' + 'Class11 <|.. Class12\n' + + 'Class13 --> Class14\n' + + 'Class15 ..> Class16\n' + + 'Class17 ..|> Class18\n' + + 'Class19 <--* Class20' parser.parse(str) }) it('should handle cardinality and labels', function () { const str = 'classDiagram\n' + -'Class01 "1" *-- "many" Class02 : contains\n' + -'Class03 o-- Class04 : aggregation\n' + -'Class05 --> "1" Class06' + 'Class01 "1" *-- "many" Class02 : contains\n' + + 'Class03 o-- Class04 : aggregation\n' + + 'Class05 --> "1" Class06' parser.parse(str) }) it('should handle class definitions', function () { const str = 'classDiagram\n' + -'class Car\n' + -'Driver -- Car : drives >\n' + -'Car *-- Wheel : have 4 >\n' + -'Car -- Person : < owns' + 'class Car\n' + + 'Driver -- Car : drives >\n' + + 'Car *-- Wheel : have 4 >\n' + + 'Car -- Person : < owns' parser.parse(str) }) it('should handle method statements', function () { const str = 'classDiagram\n' + -'Object <|-- ArrayList\n' + -'Object : equals()\n' + -'ArrayList : Object[] elementData\n' + -'ArrayList : size()' + 'Object <|-- ArrayList\n' + + 'Object : equals()\n' + + 'ArrayList : Object[] elementData\n' + + 'ArrayList : size()' parser.parse(str) }) it('should handle parsing of method statements grouped by brackets', function () { const str = 'classDiagram\n' + -'class Dummy {\n' + -'String data\n' + -' void methods()\n' + -'}\n' + -'\n' + -'class Flight {\n' + -' flightNumber : Integer\n' + -' departureTime : Date\n' + -'}' + 'class Dummy {\n' + + 'String data\n' + + ' void methods()\n' + + '}\n' + + '\n' + + 'class Flight {\n' + + ' flightNumber : Integer\n' + + ' departureTime : Date\n' + + '}' parser.parse(str) }) it('should handle parsing of separators', function () { const str = 'classDiagram\n' + - 'class Foo1 {\n' + - ' You can use\n' + - ' several lines\n' + - '..\n' + - 'as you want\n' + - 'and group\n' + - '==\n' + - 'things together.\n' + - '__\n' + - 'You can have as many groups\n' + - 'as you want\n' + - '--\n' + - 'End of class\n' + - '}\n' + - '\n' + - 'class User {\n' + - '.. Simple Getter ..\n' + - '+ getName()\n' + - '+ getAddress()\n' + - '.. Some setter ..\n' + - '+ setName()\n' + - '__ private data __\n' + - 'int age\n' + - '-- encrypted --\n' + - 'String password\n' + - '}' + 'class Foo1 {\n' + + ' You can use\n' + + ' several lines\n' + + '..\n' + + 'as you want\n' + + 'and group\n' + + '==\n' + + 'things together.\n' + + '__\n' + + 'You can have as many groups\n' + + 'as you want\n' + + '--\n' + + 'End of class\n' + + '}\n' + + '\n' + + 'class User {\n' + + '.. Simple Getter ..\n' + + '+ getName()\n' + + '+ getAddress()\n' + + '.. Some setter ..\n' + + '+ setName()\n' + + '__ private data __\n' + + 'int age\n' + + '-- encrypted --\n' + + 'String password\n' + + '}' parser.parse(str) }) @@ -109,9 +109,9 @@ describe('class diagram, ', function () { parser.yy = classDb parser.yy.clear() }) - it('should handle relation definitions EXTENSION', function () { + it('should handle relation definitions EXTENSION (right to left)', function () { const str = 'classDiagram\n' + - 'Class01 <|-- Class02' + 'Class01 <|-- Class02' parser.parse(str) @@ -122,10 +122,11 @@ describe('class diagram, ', function () { expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION) expect(relations[0].relation.type2).toBe('none') expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE) + console.log(relations) }) it('should handle relation definitions AGGREGATION and dotted line', function () { const str = 'classDiagram\n' + - 'Class01 o.. Class02' + 'Class01 o.. Class02' parser.parse(str) @@ -139,7 +140,7 @@ describe('class diagram, ', function () { }) it('should handle relation definitions COMPOSITION on both sides', function () { const str = 'classDiagram\n' + - 'Class01 *--* Class02' + 'Class01 *--* Class02' parser.parse(str) @@ -153,7 +154,7 @@ describe('class diagram, ', function () { }) it('should handle relation definitions no types', function () { const str = 'classDiagram\n' + - 'Class01 -- Class02' + 'Class01 -- Class02' parser.parse(str) @@ -167,7 +168,7 @@ describe('class diagram, ', function () { }) it('should handle relation definitions with type only on right side', function () { const str = 'classDiagram\n' + - 'Class01 --|> Class02' + 'Class01 --|> Class02' parser.parse(str) @@ -182,11 +183,11 @@ describe('class diagram, ', function () { it('should handle multiple classes and relation definitions', function () { const str = 'classDiagram\n' + - 'Class01 <|-- Class02\n' + - 'Class03 *-- Class04\n' + - 'Class05 o-- Class06\n' + - 'Class07 .. Class08\n' + - 'Class09 -- Class10' + 'Class01 <|-- Class02\n' + + 'Class03 *-- Class04\n' + + 'Class05 o-- Class06\n' + + 'Class07 .. Class08\n' + + 'Class09 -- Class10' parser.parse(str) diff --git a/src/diagrams/class/classRenderer.js b/src/diagrams/class/classRenderer.js index 5169fce4bf..922e2cedd0 100644 --- a/src/diagrams/class/classRenderer.js +++ b/src/diagrams/class/classRenderer.js @@ -30,6 +30,18 @@ const getGraphId = function (label) { return undefined } +/** + * List of basic shapes used for paths + * @namespace + */ +const shapes = { + diamond: 'M 18,7 L9,13 L1,7 L9,1 Z', + thinArrowLeft: 'M 5,7 L9,13 L1,7 L9,1 Z', + thinArrowRight: 'M 18,7 L9,13 L14,7 L9,1 Z', + triangleLeft: 'M 1,7 L18,13 V 1 Z', + triangleRight: 'M 1,1 V 13 L18,7 Z' +} + /** * Setup arrow head and define the marker. The result is appended to the svg. */ @@ -43,80 +55,84 @@ const insertMarkers = function (elem) { .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 1,7 L18,13 V 1 Z') + .attr('d', shapes.triangleLeft) elem.append('defs').append('marker') .attr('id', 'extensionEnd') + .attr('class', 'extension') .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) .attr('orient', 'auto') .append('path') - .attr('d', 'M 1,1 V 13 L18,7 Z') // this is actual shape for arrowhead + .attr('d', shapes.triangleRight) // this is actual shape for arrowhead elem.append('defs').append('marker') .attr('id', 'compositionStart') - .attr('class', 'extension') + .attr('class', 'composition') .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', shapes.diamond) elem.append('defs').append('marker') .attr('id', 'compositionEnd') + .attr('class', 'composition') .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', shapes.diamond) elem.append('defs').append('marker') .attr('id', 'aggregationStart') - .attr('class', 'extension') + .attr('class', 'aggregation') .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', shapes.diamond) elem.append('defs').append('marker') .attr('id', 'aggregationEnd') + .attr('class', 'aggregation') .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', shapes.diamond) elem.append('defs').append('marker') .attr('id', 'dependencyStart') - .attr('class', 'extension') + .attr('class', 'dependency') .attr('refX', 0) .attr('refY', 7) .attr('markerWidth', 190) .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z') + .attr('d', shapes.thinArrowLeft) elem.append('defs').append('marker') .attr('id', 'dependencyEnd') + .attr('class', 'dependency') .attr('refX', 19) .attr('refY', 7) .attr('markerWidth', 20) .attr('markerHeight', 28) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z') + .attr('d', shapes.thinArrowRight) } let edgeCount = 0 diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index d40c336c42..0a7c9c2248 100644 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -374,14 +374,6 @@ const render = function (id, txt, cb, container) { style1.innerHTML = scope(style, `#${id}`) svg.insertBefore(style1, firstChild) - const style2 = document.createElement('style') - const cs = window.getComputedStyle(svg) - style2.innerHTML = `#${id} { - color: ${cs.color}; - font: ${cs.font}; - }` - svg.insertBefore(style2, firstChild) - switch (graphType) { case 'git': config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute