diff --git a/src/diagrams/class/classDb.js b/src/diagrams/class/classDb.js index 227d95875..94ec0e21e 100644 --- a/src/diagrams/class/classDb.js +++ b/src/diagrams/class/classDb.js @@ -1,8 +1,7 @@ +import { logger } from '../../logger'; -import { logger } from '../../logger' - -let relations = [] -let classes = {} +let relations = []; +let classes = {}; /** * Function called by parser when a node definition has been found. @@ -11,75 +10,75 @@ let classes = {} * @param type * @param style */ -export const addClass = function (id) { +export const addClass = function(id) { if (typeof classes[id] === 'undefined') { classes[id] = { id: id, methods: [], members: [] - } + }; } -} +}; -export const clear = function () { - relations = [] - classes = {} -} +export const clear = function() { + relations = []; + classes = {}; +}; -export const getClass = function (id) { - return classes[id] -} -export const getClasses = function () { - return classes -} +export const getClass = function(id) { + return classes[id]; +}; +export const getClasses = function() { + return classes; +}; -export const getRelations = function () { - return relations -} +export const getRelations = function() { + return relations; +}; -export const addRelation = function (relation) { - logger.debug('Adding relation: ' + JSON.stringify(relation)) - addClass(relation.id1) - addClass(relation.id2) - relations.push(relation) -} +export const addRelation = function(relation) { + logger.debug('Adding relation: ' + JSON.stringify(relation)); + addClass(relation.id1); + addClass(relation.id2); + relations.push(relation); +}; -export const addMember = function (className, member) { - const theClass = classes[className] +export const addMember = function(className, member) { + const theClass = classes[className]; if (typeof member === 'string') { if (member.substr(-1) === ')') { - theClass.methods.push(member) + theClass.methods.push(member); } else { - theClass.members.push(member) + theClass.members.push(member); } } -} +}; -export const addMembers = function (className, MembersArr) { +export const addMembers = function(className, MembersArr) { if (Array.isArray(MembersArr)) { - MembersArr.forEach(member => addMember(className, member)) + MembersArr.forEach(member => addMember(className, member)); } -} +}; -export const cleanupLabel = function (label) { +export const cleanupLabel = function(label) { if (label.substring(0, 1) === ':') { - return label.substr(2).trim() + return label.substr(2).trim(); } else { - return label.trim() + return label.trim(); } -} +}; export const lineType = { LINE: 0, DOTTED_LINE: 1 -} +}; export const relationType = { AGGREGATION: 0, EXTENSION: 1, COMPOSITION: 2, DEPENDENCY: 3 -} +}; export default { addClass, @@ -93,4 +92,4 @@ export default { cleanupLabel, lineType, relationType -} +}; diff --git a/src/diagrams/class/classDiagram.spec.js b/src/diagrams/class/classDiagram.spec.js index 38657e11d..154898907 100644 --- a/src/diagrams/class/classDiagram.spec.js +++ b/src/diagrams/class/classDiagram.spec.js @@ -1,208 +1,211 @@ /* eslint-env jasmine */ -import { parser } from './parser/classDiagram' -import classDb from './classDb' +import { parser } from './parser/classDiagram'; +import classDb from './classDb'; -describe('class diagram, ', function () { - describe('when parsing an info graph it', function () { - beforeEach(function () { - parser.yy = classDb - }) +describe('class diagram, ', function() { + describe('when parsing an info graph it', function() { + beforeEach(function() { + parser.yy = classDb; + }); - 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' + 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'; - 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' + 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'; - parser.parse(str) - }) + 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' + 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'; - 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' + 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'; - parser.parse(str) - }) + 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()' + it('should handle method statements', function() { + const str = + 'classDiagram\n' + + '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' + -'}' + 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' + + '}'; - parser.parse(str) - }) + 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' + - '}' + 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' + + '}'; - parser.parse(str) - }) - }) + parser.parse(str); + }); + }); - describe('when fetching data from an classDiagram graph it', function () { - beforeEach(function () { - parser.yy = classDb - parser.yy.clear() - }) - it('should handle relation definitions EXTENSION', function () { - const str = 'classDiagram\n' + - 'Class01 <|-- Class02' + describe('when fetching data from an classDiagram graph it', function() { + beforeEach(function() { + parser.yy = classDb; + parser.yy.clear(); + }); + it('should handle relation definitions EXTENSION', function() { + const str = 'classDiagram\n' + 'Class01 <|-- Class02'; - parser.parse(str) + parser.parse(str); - const relations = parser.yy.getRelations() + const relations = parser.yy.getRelations(); - expect(parser.yy.getClass('Class01').id).toBe('Class01') - expect(parser.yy.getClass('Class02').id).toBe('Class02') - 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) - }) - it('should handle relation definitions AGGREGATION and dotted line', function () { - const str = 'classDiagram\n' + - 'Class01 o.. Class02' + expect(parser.yy.getClass('Class01').id).toBe('Class01'); + expect(parser.yy.getClass('Class02').id).toBe('Class02'); + 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); + }); + it('should handle relation definitions AGGREGATION and dotted line', function() { + const str = 'classDiagram\n' + 'Class01 o.. Class02'; - parser.parse(str) + parser.parse(str); - const relations = parser.yy.getRelations() + const relations = parser.yy.getRelations(); - expect(parser.yy.getClass('Class01').id).toBe('Class01') - expect(parser.yy.getClass('Class02').id).toBe('Class02') - expect(relations[0].relation.type1).toBe(classDb.relationType.AGGREGATION) - expect(relations[0].relation.type2).toBe('none') - expect(relations[0].relation.lineType).toBe(classDb.lineType.DOTTED_LINE) - }) - it('should handle relation definitions COMPOSITION on both sides', function () { - const str = 'classDiagram\n' + - 'Class01 *--* Class02' + expect(parser.yy.getClass('Class01').id).toBe('Class01'); + expect(parser.yy.getClass('Class02').id).toBe('Class02'); + expect(relations[0].relation.type1).toBe(classDb.relationType.AGGREGATION); + expect(relations[0].relation.type2).toBe('none'); + expect(relations[0].relation.lineType).toBe(classDb.lineType.DOTTED_LINE); + }); + it('should handle relation definitions COMPOSITION on both sides', function() { + const str = 'classDiagram\n' + 'Class01 *--* Class02'; - parser.parse(str) + parser.parse(str); - const relations = parser.yy.getRelations() + const relations = parser.yy.getRelations(); - expect(parser.yy.getClass('Class01').id).toBe('Class01') - expect(parser.yy.getClass('Class02').id).toBe('Class02') - expect(relations[0].relation.type1).toBe(classDb.relationType.COMPOSITION) - expect(relations[0].relation.type2).toBe(classDb.relationType.COMPOSITION) - expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE) - }) - it('should handle relation definitions no types', function () { - const str = 'classDiagram\n' + - 'Class01 -- Class02' + expect(parser.yy.getClass('Class01').id).toBe('Class01'); + expect(parser.yy.getClass('Class02').id).toBe('Class02'); + expect(relations[0].relation.type1).toBe(classDb.relationType.COMPOSITION); + expect(relations[0].relation.type2).toBe(classDb.relationType.COMPOSITION); + expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE); + }); + it('should handle relation definitions no types', function() { + const str = 'classDiagram\n' + 'Class01 -- Class02'; - parser.parse(str) + parser.parse(str); - const relations = parser.yy.getRelations() + const relations = parser.yy.getRelations(); - expect(parser.yy.getClass('Class01').id).toBe('Class01') - expect(parser.yy.getClass('Class02').id).toBe('Class02') - expect(relations[0].relation.type1).toBe('none') - expect(relations[0].relation.type2).toBe('none') - expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE) - }) - it('should handle relation definitions with type only on right side', function () { - const str = 'classDiagram\n' + - 'Class01 --|> Class02' + expect(parser.yy.getClass('Class01').id).toBe('Class01'); + expect(parser.yy.getClass('Class02').id).toBe('Class02'); + expect(relations[0].relation.type1).toBe('none'); + expect(relations[0].relation.type2).toBe('none'); + expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE); + }); + it('should handle relation definitions with type only on right side', function() { + const str = 'classDiagram\n' + 'Class01 --|> Class02'; - parser.parse(str) + parser.parse(str); - const relations = parser.yy.getRelations() + const relations = parser.yy.getRelations(); - expect(parser.yy.getClass('Class01').id).toBe('Class01') - expect(parser.yy.getClass('Class02').id).toBe('Class02') - expect(relations[0].relation.type1).toBe('none') - expect(relations[0].relation.type2).toBe(classDb.relationType.EXTENSION) - expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE) - }) + expect(parser.yy.getClass('Class01').id).toBe('Class01'); + expect(parser.yy.getClass('Class02').id).toBe('Class02'); + expect(relations[0].relation.type1).toBe('none'); + expect(relations[0].relation.type2).toBe(classDb.relationType.EXTENSION); + expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE); + }); - 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' + 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'; - parser.parse(str) + parser.parse(str); - const relations = parser.yy.getRelations() + const relations = parser.yy.getRelations(); - expect(parser.yy.getClass('Class01').id).toBe('Class01') - expect(parser.yy.getClass('Class10').id).toBe('Class10') + expect(parser.yy.getClass('Class01').id).toBe('Class01'); + expect(parser.yy.getClass('Class10').id).toBe('Class10'); - expect(relations.length).toBe(5) + expect(relations.length).toBe(5); - 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) - expect(relations[3].relation.type1).toBe('none') - expect(relations[3].relation.type2).toBe('none') - expect(relations[3].relation.lineType).toBe(classDb.lineType.DOTTED_LINE) - }) - }) -}) + 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); + expect(relations[3].relation.type1).toBe('none'); + expect(relations[3].relation.type2).toBe('none'); + expect(relations[3].relation.lineType).toBe(classDb.lineType.DOTTED_LINE); + }); + }); +}); diff --git a/src/diagrams/class/classRenderer.js b/src/diagrams/class/classRenderer.js index a64bae1be..37a6629ae 100644 --- a/src/diagrams/class/classRenderer.js +++ b/src/diagrams/class/classRenderer.js @@ -1,38 +1,38 @@ -import * as d3 from 'd3' -import dagre from 'dagre-layout' -import graphlib from 'graphlibrary' -import { logger } from '../../logger' -import classDb from './classDb' -import { parser } from './parser/classDiagram' +import * as d3 from 'd3'; +import dagre from 'dagre-layout'; +import graphlib from 'graphlibrary'; +import { logger } from '../../logger'; +import classDb from './classDb'; +import { parser } from './parser/classDiagram'; -parser.yy = classDb +parser.yy = classDb; -const idCache = {} +const idCache = {}; -let classCnt = 0 +let classCnt = 0; const conf = { dividerMargin: 10, padding: 5, textHeight: 10 -} +}; // Todo optimize -const getGraphId = function (label) { - const keys = Object.keys(idCache) +const getGraphId = function(label) { + const keys = Object.keys(idCache); for (let i = 0; i < keys.length; i++) { if (idCache[keys[i]].label === label) { - return keys[i] + return keys[i]; } } - return undefined -} + return undefined; +}; /** * Setup arrow head and define the marker. The result is appended to the svg. */ -const insertMarkers = function (elem) { +const insertMarkers = function(elem) { elem .append('defs') .append('marker') @@ -44,7 +44,7 @@ const insertMarkers = function (elem) { .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 1,7 L18,13 V 1 Z') + .attr('d', 'M 1,7 L18,13 V 1 Z'); elem .append('defs') @@ -56,7 +56,7 @@ const insertMarkers = function (elem) { .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', 'M 1,1 V 13 L18,7 Z'); // this is actual shape for arrowhead elem .append('defs') @@ -69,7 +69,7 @@ const insertMarkers = function (elem) { .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z'); elem .append('defs') @@ -81,7 +81,7 @@ const insertMarkers = function (elem) { .attr('markerHeight', 28) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z'); elem .append('defs') @@ -94,7 +94,7 @@ const insertMarkers = function (elem) { .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z'); elem .append('defs') @@ -106,7 +106,7 @@ const insertMarkers = function (elem) { .attr('markerHeight', 28) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z') + .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z'); elem .append('defs') @@ -119,7 +119,7 @@ const insertMarkers = function (elem) { .attr('markerHeight', 240) .attr('orient', 'auto') .append('path') - .attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z') + .attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z'); elem .append('defs') @@ -131,96 +131,86 @@ const insertMarkers = function (elem) { .attr('markerHeight', 28) .attr('orient', 'auto') .append('path') - .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z') -} + .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z'); +}; -let edgeCount = 0 -let total = 0 -const drawEdge = function (elem, path, relation) { - const getRelationType = function (type) { +let edgeCount = 0; +let total = 0; +const drawEdge = function(elem, path, relation) { + const getRelationType = function(type) { switch (type) { case classDb.relationType.AGGREGATION: - return 'aggregation' + return 'aggregation'; case classDb.relationType.EXTENSION: - return 'extension' + return 'extension'; case classDb.relationType.COMPOSITION: - return 'composition' + return 'composition'; case classDb.relationType.DEPENDENCY: - return 'dependency' + return 'dependency'; } - } + }; - path.points = path.points.filter(p => !Number.isNaN(p.y)) + path.points = path.points.filter(p => !Number.isNaN(p.y)); // The data for our line - const lineData = path.points + const lineData = path.points; // This is the accessor function we talked about above const lineFunction = d3 .line() - .x(function (d) { - return d.x + .x(function(d) { + return d.x; }) - .y(function (d) { - return d.y + .y(function(d) { + return d.y; }) - .curve(d3.curveBasis) + .curve(d3.curveBasis); const svgPath = elem .append('path') .attr('d', lineFunction(lineData)) .attr('id', 'edge' + edgeCount) - .attr('class', 'relation') - let url = '' + .attr('class', 'relation'); + let url = ''; if (conf.arrowMarkerAbsolute) { url = window.location.protocol + '//' + window.location.host + window.location.pathname + - window.location.search - url = url.replace(/\(/g, '\\(') - url = url.replace(/\)/g, '\\)') + window.location.search; + url = url.replace(/\(/g, '\\('); + url = url.replace(/\)/g, '\\)'); } if (relation.relation.type1 !== 'none') { svgPath.attr( 'marker-start', - 'url(' + - url + - '#' + - getRelationType(relation.relation.type1) + - 'Start' + - ')' - ) + 'url(' + url + '#' + getRelationType(relation.relation.type1) + 'Start' + ')' + ); } if (relation.relation.type2 !== 'none') { svgPath.attr( 'marker-end', - 'url(' + - url + - '#' + - getRelationType(relation.relation.type2) + - 'End' + - ')' - ) + 'url(' + url + '#' + getRelationType(relation.relation.type2) + 'End' + ')' + ); } - let x, y - const l = path.points.length + let x, y; + const l = path.points.length; if (l % 2 !== 0 && l > 1) { - const p1 = path.points[Math.floor(l / 2)] - const p2 = path.points[Math.ceil(l / 2)] - x = (p1.x + p2.x) / 2 - y = (p1.y + p2.y) / 2 + const p1 = path.points[Math.floor(l / 2)]; + const p2 = path.points[Math.ceil(l / 2)]; + x = (p1.x + p2.x) / 2; + y = (p1.y + p2.y) / 2; } else { - const p = path.points[Math.floor(l / 2)] - x = p.x - y = p.y + const p = path.points[Math.floor(l / 2)]; + x = p.x; + y = p.y; } if (typeof relation.title !== 'undefined') { - const g = elem.append('g').attr('class', 'classLabel') + const g = elem.append('g').attr('class', 'classLabel'); const label = g .append('text') .attr('class', 'label') @@ -228,189 +218,177 @@ const drawEdge = function (elem, path, relation) { .attr('y', y) .attr('fill', 'red') .attr('text-anchor', 'middle') - .text(relation.title) + .text(relation.title); - window.label = label - const bounds = label.node().getBBox() + window.label = label; + const bounds = label.node().getBBox(); g.insert('rect', ':first-child') .attr('class', 'box') .attr('x', bounds.x - conf.padding / 2) .attr('y', bounds.y - conf.padding / 2) .attr('width', bounds.width + conf.padding) - .attr('height', bounds.height + conf.padding) + .attr('height', bounds.height + conf.padding); } - edgeCount++ -} + edgeCount++; +}; -const drawClass = function (elem, classDef) { - logger.info('Rendering class ' + classDef) +const drawClass = function(elem, classDef) { + logger.info('Rendering class ' + classDef); - const addTspan = function (textEl, txt, isFirst) { + const addTspan = function(textEl, txt, isFirst) { const tSpan = textEl .append('tspan') .attr('x', conf.padding) - .text(txt) + .text(txt); if (!isFirst) { - tSpan.attr('dy', conf.textHeight) + tSpan.attr('dy', conf.textHeight); } - } + }; - const id = 'classId' + (classCnt % total) + const id = 'classId' + (classCnt % total); const classInfo = { id: id, label: classDef.id, width: 0, height: 0 - } + }; const g = elem .append('g') .attr('id', id) - .attr('class', 'classGroup') + .attr('class', 'classGroup'); const title = g .append('text') .attr('x', conf.padding) .attr('y', conf.textHeight + conf.padding) - .text(classDef.id) + .text(classDef.id); - const titleHeight = title.node().getBBox().height + const titleHeight = title.node().getBBox().height; const membersLine = g .append('line') // text label for the x axis .attr('x1', 0) .attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2) - .attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2) + .attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2); const members = g .append('text') // text label for the x axis .attr('x', conf.padding) .attr('y', titleHeight + conf.dividerMargin + conf.textHeight) .attr('fill', 'white') - .attr('class', 'classText') + .attr('class', 'classText'); - let isFirst = true - classDef.members.forEach(function (member) { - addTspan(members, member, isFirst) - isFirst = false - }) + let isFirst = true; + classDef.members.forEach(function(member) { + addTspan(members, member, isFirst); + isFirst = false; + }); - const membersBox = members.node().getBBox() + const membersBox = members.node().getBBox(); const methodsLine = g .append('line') // text label for the x axis .attr('x1', 0) - .attr( - 'y1', - conf.padding + titleHeight + conf.dividerMargin + membersBox.height - ) - .attr( - 'y2', - conf.padding + titleHeight + conf.dividerMargin + membersBox.height - ) + .attr('y1', conf.padding + titleHeight + conf.dividerMargin + membersBox.height) + .attr('y2', conf.padding + titleHeight + conf.dividerMargin + membersBox.height); const methods = g .append('text') // text label for the x axis .attr('x', conf.padding) - .attr( - 'y', - titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight - ) + .attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight) .attr('fill', 'white') - .attr('class', 'classText') + .attr('class', 'classText'); - isFirst = true + isFirst = true; - classDef.methods.forEach(function (method) { - addTspan(methods, method, isFirst) - isFirst = false - }) + classDef.methods.forEach(function(method) { + addTspan(methods, method, isFirst); + isFirst = false; + }); - const classBox = g.node().getBBox() + const classBox = g.node().getBBox(); g.insert('rect', ':first-child') .attr('x', 0) .attr('y', 0) .attr('width', classBox.width + 2 * conf.padding) - .attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin) + .attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin); - membersLine.attr('x2', classBox.width + 2 * conf.padding) - methodsLine.attr('x2', classBox.width + 2 * conf.padding) + membersLine.attr('x2', classBox.width + 2 * conf.padding); + methodsLine.attr('x2', classBox.width + 2 * conf.padding); - classInfo.width = classBox.width + 2 * conf.padding - classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin + classInfo.width = classBox.width + 2 * conf.padding; + classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin; - idCache[id] = classInfo - classCnt++ - return classInfo -} + idCache[id] = classInfo; + classCnt++; + return classInfo; +}; -export const setConf = function (cnf) { - const keys = Object.keys(cnf) +export const setConf = function(cnf) { + const keys = Object.keys(cnf); - keys.forEach(function (key) { - conf[key] = cnf[key] - }) -} + keys.forEach(function(key) { + conf[key] = cnf[key]; + }); +}; /** * Draws a flowchart in the tag with id: id based on the graph definition in text. * @param text * @param id */ -export const draw = function (text, id) { - parser.yy.clear() - parser.parse(text) +export const draw = function(text, id) { + parser.yy.clear(); + parser.parse(text); - logger.info('Rendering diagram ' + text) + logger.info('Rendering diagram ' + text); /// / Fetch the default direction, use TD if none was found - const diagram = d3.select(`[id='${id}']`) - insertMarkers(diagram) + const diagram = d3.select(`[id='${id}']`); + insertMarkers(diagram); // Layout graph, Create a new directed graph const g = new graphlib.Graph({ multigraph: true - }) + }); // Set an object for the graph label g.setGraph({ isMultiGraph: true - }) + }); // Default to assigning a new object as a label for each new edge. - g.setDefaultEdgeLabel(function () { - return {} - }) + g.setDefaultEdgeLabel(function() { + return {}; + }); - const classes = classDb.getClasses() - const keys = Object.keys(classes) - total = keys.length + const classes = classDb.getClasses(); + const keys = Object.keys(classes); + total = keys.length; for (let i = 0; i < keys.length; i++) { - const classDef = classes[keys[i]] - const node = drawClass(diagram, classDef) + const classDef = classes[keys[i]]; + const node = drawClass(diagram, classDef); // Add nodes to the graph. The first argument is the node id. The second is // metadata about the node. In this case we're going to add labels to each of // our nodes. - g.setNode(node.id, node) - logger.info('Org height: ' + node.height) + g.setNode(node.id, node); + logger.info('Org height: ' + node.height); } - const relations = classDb.getRelations() - relations.forEach(function (relation) { + const relations = classDb.getRelations(); + relations.forEach(function(relation) { logger.info( - 'tjoho' + - getGraphId(relation.id1) + - getGraphId(relation.id2) + - JSON.stringify(relation) - ) + 'tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation) + ); g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), { relation: relation - }) - }) - dagre.layout(g) - g.nodes().forEach(function (v) { + }); + }); + dagre.layout(g); + g.nodes().forEach(function(v) { if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') { - logger.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))) + logger.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))); d3.select('#' + v).attr( 'transform', 'translate(' + @@ -418,27 +396,22 @@ export const draw = function (text, id) { ',' + (g.node(v).y - g.node(v).height / 2) + ' )' - ) + ); } - }) - g.edges().forEach(function (e) { + }); + g.edges().forEach(function(e) { if (typeof e !== 'undefined' && typeof g.edge(e) !== 'undefined') { - logger.debug( - 'Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e)) - ) - drawEdge(diagram, g.edge(e), g.edge(e).relation) + logger.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e))); + drawEdge(diagram, g.edge(e), g.edge(e).relation); } - }) + }); - diagram.attr('height', '100%') - diagram.attr('width', '100%') - diagram.attr( - 'viewBox', - '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20) - ) -} + diagram.attr('height', '100%'); + diagram.attr('width', '100%'); + diagram.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20)); +}; export default { setConf, draw -} +};