From a694f61003ae50921e21d79fb6f1682938c78be1 Mon Sep 17 00:00:00 2001 From: knsv Date: Wed, 28 Oct 2015 08:12:47 +0100 Subject: [PATCH] 1st version parsing for class diagrams, fetching data from parsing --- src/diagrams/classDiagram/classDb.js | 102 ++++++++++-------- .../classDiagram/classDiagram.spec.js | 19 +++- src/diagrams/classDiagram/classRenderer.js | 90 +++++++++++++++- .../classDiagram/parser/classDiagram.jison | 34 +++--- .../classDiagram/parser/classDiagram.js | 51 +++++++-- 5 files changed, 221 insertions(+), 75 deletions(-) diff --git a/src/diagrams/classDiagram/classDb.js b/src/diagrams/classDiagram/classDb.js index f0af6b226..8b126575b 100644 --- a/src/diagrams/classDiagram/classDb.js +++ b/src/diagrams/classDiagram/classDb.js @@ -14,54 +14,62 @@ var funs = []; * @param type * @param style */ -exports.addClass = function (id, text, type, style) { - var txt; - - if(typeof id === 'undefined'){ - return; - } - if(id.trim().length === 0){ - return; - } - - if (typeof vertices[id] === 'undefined') { - vertices[id] = {id: id, styles: [], classes:[]}; - } - if (typeof text !== 'undefined') { - txt = text.trim(); - - // strip quotes if string starts and exnds with a quote - if(txt[0] === '"' && txt[txt.length-1] === '"'){ - txt = txt.substring(1,txt.length-1); - } - - vertices[id].text = txt; - } - if (typeof type !== 'undefined') { - vertices[id].type = type; - } - if (typeof type !== 'undefined') { - vertices[id].type = type; - } - if (typeof style !== 'undefined') { - if (style !== null) { - style.forEach(function (s) { - vertices[id].styles.push(s); - }); - } +exports.addClass = function (id) { + console.log('Adding: '+id); + if(typeof classes.id === 'undefined'){ + classes[id] = { + id:id, + methods:[] + }; } }; -exports.addRelation = function (id1, id2, type1, type2, relationTitle1, relationTitle2, title) { - log.debug('Got edge', start, end); - var edge = { - id1: id1, - id2: id2, - type1: type1, - type2: type2, - relationTitle1:relationTitle1, - relationTitle2:relationTitle2, - title:title - }; - relations.push(edge); +exports.clear = function () { + relations = []; + classes = {}; +}; + +module.exports.getClass = function (id) { + return classes[id]; +}; + +exports.addRelation = function (relation) { + console.log('Adding relation: ' + JSON.stringify(relation)); + exports.addClass(relation.id1); + exports.addClass(relation.id2); + + //var id1, id2, type1, type2, relationTitle1, relationTitle2, title,label; + //id1=tuple.id1; + //id2=tuple.id2; + //type1=tuple.type1; + //type2=tuple.type2; + //relationTitle1=tuple.relationTitle1; + //relationTitle2=tuple.relationTitle1; + // + //log.debug('Got edge', start, end); + //var edge = { + // id1: id1, + // id2: id2, + // type1: type1, + // type2: type2, + // relationTitle1:relationTitle1, + // relationTitle2:relationTitle2, + // title:title + //}; + relations.push(relation); +}; + +exports.addMembers = function (className, MembersArr) { +}; + +exports.lineType = { + LINE:0, + DOTTED_LINE:1 +}; + +exports.relationType = { + AGGREGATION:0, + EXTENSION:1, + COMPOSITION:2, + DEPENDENCY:3 }; \ No newline at end of file diff --git a/src/diagrams/classDiagram/classDiagram.spec.js b/src/diagrams/classDiagram/classDiagram.spec.js index 4f0dd226c..20807b56a 100644 --- a/src/diagrams/classDiagram/classDiagram.spec.js +++ b/src/diagrams/classDiagram/classDiagram.spec.js @@ -6,7 +6,7 @@ describe('class diagram, ', function () { var ex, cd; beforeEach(function () { cd = require('./parser/classDiagram').parser; - //cd.yy = require('./classeDb'); + cd.yy = require('./classDb'); }); it('should handle relation definitions', function () { @@ -105,4 +105,21 @@ class User { }); }); + + describe('when fetchiing data an classDiagram graph it', function () { + var ex, cd; + beforeEach(function () { + cd = require('./parser/classDiagram').parser; + cd.yy = require('./classDb'); + cd.yy.clear(); + }); + it('should handle relation definitions', function () { + var str = `classDiagram +Class01 <|-- Class02`; + + cd.parse(str); + expect(cd.yy.getClass('Class01').id).toBe('Class01'); + expect(cd.yy.getClass('Class02').id).toBe('Class02'); + }); + }); }); \ No newline at end of file diff --git a/src/diagrams/classDiagram/classRenderer.js b/src/diagrams/classDiagram/classRenderer.js index 05fbc2968..78c07e132 100644 --- a/src/diagrams/classDiagram/classRenderer.js +++ b/src/diagrams/classDiagram/classRenderer.js @@ -1,3 +1,91 @@ /** - * Created by knut on 2015-10-24. + * Created by knut on 14-11-23. */ + +var cd = require('./parser/classDiagram').parser; +sq.yy = require('./classDb'); +var d3 = require('../../d3'); +import * as Logger from '../../logger'; +var log = new Logger.Log(); + + +var conf = { + +}; + + + +/** + * Draws an actor in the diagram with the attaced line + * @param center - The center of the the actor + * @param pos The position if the actor in the liost of actors + * @param description The text in the box + */ +var drawClass = function(elem, startx, verticalPos, msg){ + var rect = svgDraw.getNoteRect(); + rect.x = startx; + rect.y = verticalPos; + rect.width = conf.width; + rect.class = 'note'; + + var g = elem.append('g'); + var rectElem = svgDraw.drawRect(g, rect); + + var textObj = svgDraw.getTextObj(); + textObj.x = startx-4; + textObj.y = verticalPos-13; + textObj.textMargin = conf.noteMargin; + textObj.dy = '1em'; + textObj.text = msg.message; + textObj.class = 'noteText'; + + var textElem = svgDraw.drawText(g,textObj, conf.width-conf.noteMargin); + + var textHeight = textElem[0][0].getBBox().height; + if(textHeight > conf.width){ + textElem.remove(); + g = elem.append('g'); + + //textObj.x = textObj.x - conf.width; + //textElem = svgDraw.drawText(g,textObj, 2*conf.noteMargin); + textElem = svgDraw.drawText(g,textObj, 2*conf.width-conf.noteMargin); + textHeight = textElem[0][0].getBBox().height; + rectElem.attr('width',2*conf.width); + exports.bounds.insert(startx, verticalPos, startx + 2*conf.width, verticalPos + 2*conf.noteMargin + textHeight); + }else{ + exports.bounds.insert(startx, verticalPos, startx + conf.width, verticalPos + 2*conf.noteMargin + textHeight); + } + + rectElem.attr('height',textHeight+ 2*conf.noteMargin); + exports.bounds.bumpVerticalPos(textHeight+ 2*conf.noteMargin); +}; + + + +module.exports.setConf = function(cnf){ + var keys = Object.keys(cnf); + + 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 + */ +module.exports.draw = function (text, id) { + cd.yy.clear(); + cd.parse(text+'\n'); + + var width = box.stopx-box.startx+2*conf.diagramMarginX; + if(conf.useMaxWidth) { + diagram.attr('height', '100%'); + diagram.attr('width', '100%'); + diagram.attr('style', 'max-width:' + (width) + 'px;'); + }else{ + diagram.attr('height',height); + diagram.attr('width', width ); + } + diagram.attr('viewBox', (box.startx-conf.diagramMarginX) + ' -' +conf.diagramMarginY + ' ' + width + ' ' + height); +}; diff --git a/src/diagrams/classDiagram/parser/classDiagram.jison b/src/diagrams/classDiagram/parser/classDiagram.jison index a9ed67825..f3dc4ccd4 100644 --- a/src/diagrams/classDiagram/parser/classDiagram.jison +++ b/src/diagrams/classDiagram/parser/classDiagram.jison @@ -137,15 +137,15 @@ className ; statement - : relationStatement - | relationStatement LABEL {/*console.log('Label found',$2);*/} + : relationStatement { yy.addRelation($1); } + | relationStatement LABEL { $1.title = $2; yy.addRelation($1); } | classStatement | methodStatement ; classStatement : CLASS className - | CLASS className STRUCT_START members STRUCT_STOP {/*console.log($2,JSON.stringify($4));*/yy.addMembers();} + | CLASS className STRUCT_START members STRUCT_STOP {/*console.log($2,JSON.stringify($4));*/yy.addMembers($2,$4);} ; members @@ -161,29 +161,29 @@ methodStatement ; relationStatement - : className relation className {/*console.log('Rel found:',$1,' , ',$2,' , ',$3);*/} - | className STR relation className {/*console.log('Rel found:',$1,' , ',$2,' , ',$3);*/} - | className relation STR className {/*console.log('Rel found:',$1,' , ',$2,' , ',$3);*/} - | className STR relation STR className {/*console.log('Str rel found:',$1,' , ',$2,' , ',$3);*/} + : className relation className { $$ = {'id1':$1,'id2':$3, relation:$2, relationTitle1:'none', relationTitle2:'none'}; } + | className STR relation className { $$ = {id1:$1, id2:$4, relation:$3, relationTitle1:$2, relationTitle2:'none'}} + | className relation STR className { $$ = {id1:$1, id2:$4, relation:$2, relationTitle1:'none', relationTitle2:$3}; } + | className STR relation STR className { $$ = {id1:$1, id2:$5, relation:$3, relationTitle1:$2, relationTitle2:$4} } ; relation - : relationType lineType relationType { $$=$1+$2+$3; } - | lineType relationType { $$=$1+$2; } - | relationType lineType { $$=$1+$2; } - | lineType { $$=$1; } + : relationType lineType relationType { $$={type1:$1,type2:$2,lineType:$3}; } + | lineType relationType { $$={type1:'none',type2:$2,lineType:$1}; } + | relationType lineType { $$={type1:$1,type2:'none',lineType:$2}; } + | lineType { $$={type1:'none',type2:'none',lineType:$1}; } ; relationType - : AGGREGATION - | EXTENSION - | COMPOSITION - | DEPENDENCY + : AGGREGATION { $$=yy.relationType.AGGREGATION;} + | EXTENSION { $$=yy.relationType.EXTENSION;} + | COMPOSITION { $$=yy.relationType.COMPOSITION;} + | DEPENDENCY { $$=yy.relationType.DEPENDENCY;} ; lineType - : LINE - | DOTTED_LINE + : LINE {$$=yy.lineType.LINE;} + | DOTTED_LINE {$$=yy.lineType.DOTTED_LINE;} ; commentToken : textToken | graphCodeTokens ; diff --git a/src/diagrams/classDiagram/parser/classDiagram.js b/src/diagrams/classDiagram/parser/classDiagram.js index 11a5e0ab1..bed6c6fc2 100644 --- a/src/diagrams/classDiagram/parser/classDiagram.js +++ b/src/diagrams/classDiagram/parser/classDiagram.js @@ -83,17 +83,20 @@ performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* actio var $0 = $$.length - 1; switch (yystate) { -case 5: case 24: case 25: +case 5: this.$=$$[$0-1]+$$[$0]; break; -case 6: case 26: +case 6: this.$=$$[$0]; break; +case 7: + yy.addRelation($$[$0]); +break; case 8: -/*console.log('Label found',$$[$0]);*/ + $$[$0-1].title = $$[$0]; yy.addRelation($$[$0-1]); break; case 12: -console.log($$[$0-3],JSON.stringify($$[$0-1])); +/*console.log($$[$0-3],JSON.stringify($$[$0-1]));*/yy.addMembers($$[$0-3],$$[$0-1]); break; case 13: this.$ = [$$[$0]]; @@ -108,16 +111,46 @@ case 18: /*console.log('sep found',$$[$0]);*/ break; case 19: -/*console.log('Rel found:',$$[$0-2],' , ',$$[$0-1],' , ',$$[$0]);*/ + this.$ = {'id1':$$[$0-2],'id2':$$[$0], relation:$$[$0-1], relationTitle1:'none', relationTitle2:'none'}; break; -case 20: case 21: -/*console.log('Rel found:',$$[$0-3],' , ',$$[$0-2],' , ',$$[$0-1]);*/ +case 20: + this.$ = {id1:$$[$0-3], id2:$$[$0], relation:$$[$0-1], relationTitle1:$$[$0-2], relationTitle2:'none'} +break; +case 21: + this.$ = {id1:$$[$0-3], id2:$$[$0], relation:$$[$0-2], relationTitle1:'none', relationTitle2:$$[$0-1]}; break; case 22: -/*console.log('Str rel found:',$$[$0-4],' , ',$$[$0-3],' , ',$$[$0-2]);*/ + this.$ = {id1:$$[$0-4], id2:$$[$0], relation:$$[$0-2], relationTitle1:$$[$0-3], relationTitle2:$$[$0-1]} break; case 23: - this.$=$$[$0-2]+$$[$0-1]+$$[$0]; + this.$={type1:$$[$0-2],type2:$$[$0-1],lineType:$$[$0]}; +break; +case 24: + this.$={type1:'none',type2:$$[$0],lineType:$$[$0-1]}; +break; +case 25: + this.$={type1:$$[$0-1],type2:'none',lineType:$$[$0]}; +break; +case 26: + this.$={type1:'none',type2:'none',lineType:$$[$0]}; +break; +case 27: + this.$=yy.relationType.AGGREGATION; +break; +case 28: + this.$=yy.relationType.EXTENSION; +break; +case 29: + this.$=yy.relationType.COMPOSITION; +break; +case 30: + this.$=yy.relationType.DEPENDENCY; +break; +case 31: +this.$=yy.lineType.LINE; +break; +case 32: +this.$=yy.lineType.DOTTED_LINE; break; } },