2014-12-20 08:40:48 +01:00
|
|
|
/**
|
|
|
|
* Created by knut on 14-12-20.
|
|
|
|
*/
|
2015-10-17 12:46:36 +02:00
|
|
|
//var log = require('../../logger').create();
|
2014-12-20 08:40:48 +01:00
|
|
|
exports.drawRect = function(elem , rectData){
|
2015-10-12 07:37:02 +02:00
|
|
|
var rectElem = elem.append('rect');
|
|
|
|
rectElem.attr('x', rectData.x);
|
|
|
|
rectElem.attr('y', rectData.y);
|
|
|
|
rectElem.attr('fill', rectData.fill);
|
|
|
|
rectElem.attr('stroke', rectData.stroke);
|
|
|
|
rectElem.attr('width', rectData.width);
|
|
|
|
rectElem.attr('height', rectData.height);
|
|
|
|
rectElem.attr('rx', rectData.rx);
|
|
|
|
rectElem.attr('ry', rectData.ry);
|
2014-12-20 08:40:48 +01:00
|
|
|
|
2014-12-21 20:59:11 +01:00
|
|
|
if(typeof rectData.class !== 'undefined'){
|
2015-10-12 07:37:02 +02:00
|
|
|
rectElem.attr('class', rectData.class);
|
2014-12-21 20:59:11 +01:00
|
|
|
}
|
|
|
|
|
2014-12-20 08:40:48 +01:00
|
|
|
return rectElem;
|
|
|
|
};
|
|
|
|
|
2015-06-20 20:58:58 +02:00
|
|
|
exports.drawText = function(elem, textData, width) {
|
|
|
|
// Remove and ignore br:s
|
|
|
|
var nText = textData.text.replace(/<br\/?>/ig,' ');
|
|
|
|
|
2014-12-20 09:18:12 +01:00
|
|
|
var textElem = elem.append('text');
|
|
|
|
textElem.attr('x', textData.x);
|
|
|
|
textElem.attr('y', textData.y);
|
2014-12-20 18:41:20 +01:00
|
|
|
textElem.style('text-anchor', textData.anchor);
|
2014-12-21 20:59:11 +01:00
|
|
|
textElem.attr('fill', textData.fill);
|
2015-06-20 20:58:58 +02:00
|
|
|
if (typeof textData.class !== 'undefined') {
|
2015-10-12 07:37:02 +02:00
|
|
|
textElem.attr('class', textData.class);
|
2015-06-20 20:58:58 +02:00
|
|
|
}
|
|
|
|
/* textData.text.split(/<br\/?>/ig).forEach(function(rowText){
|
|
|
|
var span = textElem.append('tspan');
|
|
|
|
span.attr('x', textData.x +textData.textMargin);
|
|
|
|
span.attr('dy', textData.dy);
|
|
|
|
span.text(rowText);
|
|
|
|
});*/
|
2014-12-20 09:18:12 +01:00
|
|
|
|
|
|
|
|
2015-06-20 20:58:58 +02:00
|
|
|
var span = textElem.append('tspan');
|
2015-09-26 12:09:47 +02:00
|
|
|
//span.attr('x', textData.x);
|
|
|
|
span.attr('x', textData.x+textData.textMargin*2);
|
|
|
|
//span.attr('dy', textData.dy);
|
2015-06-20 20:58:58 +02:00
|
|
|
span.text(nText);
|
|
|
|
if(typeof textElem.textwrap !== 'undefined'){
|
2015-11-21 11:51:15 +01:00
|
|
|
|
2015-06-20 20:58:58 +02:00
|
|
|
textElem.textwrap({
|
2015-09-26 12:09:47 +02:00
|
|
|
x: textData.x, // bounding box is 300 pixels from the left
|
|
|
|
y: textData.y, // bounding box is 400 pixels from the top
|
2015-06-20 20:58:58 +02:00
|
|
|
width: width, // bounding box is 500 pixels across
|
|
|
|
height: 1800 // bounding box is 600 pixels tall
|
|
|
|
}, textData.textMargin);
|
2014-12-21 20:59:11 +01:00
|
|
|
}
|
|
|
|
|
2014-12-20 09:18:12 +01:00
|
|
|
return textElem;
|
|
|
|
};
|
|
|
|
|
2017-02-16 22:50:39 +08:00
|
|
|
exports.drawLabel = function (elem, txtObject) {
|
|
|
|
function genPoints(x, y, width, height, cut) {
|
|
|
|
return x + "," + y + " " +
|
|
|
|
(x + width) + "," + y + " " +
|
|
|
|
(x + width) + "," + (y + height - cut) + " " +
|
|
|
|
(x + width - cut * 1.2) + "," + (y + height) + " " +
|
|
|
|
(x) + "," + (y + height);
|
|
|
|
}
|
|
|
|
var polygon = elem.append("polygon");
|
|
|
|
polygon.attr("points" , genPoints(txtObject.x, txtObject.y, 50, 20, 7));
|
|
|
|
polygon.attr("style", "fill:#e4db14;stroke:none");
|
2014-12-20 18:41:20 +01:00
|
|
|
|
|
|
|
txtObject.y = txtObject.y + txtObject.labelMargin;
|
2017-02-16 22:50:39 +08:00
|
|
|
txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin;
|
2014-12-20 18:41:20 +01:00
|
|
|
txtObject.fill = 'white';
|
|
|
|
exports.drawText(elem, txtObject);
|
|
|
|
|
|
|
|
//return textElem;
|
|
|
|
};
|
2015-07-04 10:00:14 +02:00
|
|
|
var actorCnt = -1;
|
2015-01-05 13:41:32 +01:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2015-01-25 14:24:58 +01:00
|
|
|
exports.drawActor = function(elem, left, verticalPos, description,conf){
|
2015-01-05 13:41:32 +01:00
|
|
|
var center = left + (conf.width/2);
|
2015-10-12 07:37:02 +02:00
|
|
|
var g = elem.append('g');
|
2015-01-25 14:24:58 +01:00
|
|
|
if(verticalPos === 0) {
|
2015-07-04 10:00:14 +02:00
|
|
|
actorCnt++;
|
2015-10-12 07:37:02 +02:00
|
|
|
g.append('line')
|
|
|
|
.attr('id', 'actor'+actorCnt)
|
|
|
|
.attr('x1', center)
|
|
|
|
.attr('y1', 5)
|
|
|
|
.attr('x2', center)
|
|
|
|
.attr('y2', 2000)
|
|
|
|
.attr('class', 'actor-line')
|
|
|
|
.attr('stroke-width', '0.5px')
|
|
|
|
.attr('stroke', '#999');
|
2015-01-25 14:24:58 +01:00
|
|
|
}
|
2015-01-05 13:41:32 +01:00
|
|
|
|
2015-01-05 14:12:49 +01:00
|
|
|
var rect = exports.getNoteRect();
|
|
|
|
rect.x = left;
|
2015-01-25 14:24:58 +01:00
|
|
|
rect.y = verticalPos;
|
2015-01-05 14:12:49 +01:00
|
|
|
rect.fill = '#eaeaea';
|
|
|
|
rect.width = conf.width;
|
|
|
|
rect.height = conf.height;
|
|
|
|
rect.class = 'actor';
|
|
|
|
rect.rx = 3;
|
|
|
|
rect.ry = 3;
|
|
|
|
exports.drawRect(g, rect);
|
|
|
|
|
2016-12-07 07:48:47 -05:00
|
|
|
_drawTextCandidateFunc(conf)(description, g,
|
|
|
|
rect.x, rect.y, rect.width, rect.height, {'class':'actor'});
|
2015-01-05 13:41:32 +01:00
|
|
|
};
|
2015-01-05 14:41:00 +01:00
|
|
|
|
2016-03-11 16:44:45 +01:00
|
|
|
exports.anchorElement = function(elem) {
|
2016-12-01 00:16:44 -05:00
|
|
|
return elem.append('g');
|
2016-03-11 16:44:45 +01:00
|
|
|
};
|
2016-03-08 10:40:52 +01:00
|
|
|
/**
|
|
|
|
* Draws an actor in the diagram with the attaced line
|
2016-03-11 16:44:45 +01:00
|
|
|
* @param elem - element to append activation rect
|
|
|
|
* @param bounds - activation box bounds
|
|
|
|
* @param verticalPos - precise y cooridnate of bottom activation box edge
|
2016-03-08 10:40:52 +01:00
|
|
|
*/
|
2016-03-11 16:44:45 +01:00
|
|
|
exports.drawActivation = function(elem,bounds,verticalPos){
|
2016-03-08 10:40:52 +01:00
|
|
|
var rect = exports.getNoteRect();
|
2016-03-11 16:44:45 +01:00
|
|
|
var g = bounds.anchored;
|
|
|
|
rect.x = bounds.startx;
|
|
|
|
rect.y = bounds.starty;
|
2016-03-12 15:27:37 +01:00
|
|
|
rect.fill = '#f4f4f4';
|
2016-03-11 16:44:45 +01:00
|
|
|
rect.width = bounds.stopx - bounds.startx;
|
|
|
|
rect.height = verticalPos - bounds.starty;
|
2016-03-08 10:40:52 +01:00
|
|
|
exports.drawRect(g, rect);
|
|
|
|
};
|
|
|
|
|
2015-01-05 14:41:00 +01:00
|
|
|
/**
|
|
|
|
* 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 list of actors
|
|
|
|
* @param description The text in the box
|
|
|
|
*/
|
|
|
|
exports.drawLoop = function(elem,bounds,labelText, conf){
|
2015-10-12 07:37:02 +02:00
|
|
|
var g = elem.append('g');
|
2015-01-05 14:41:00 +01:00
|
|
|
var drawLoopLine = function(startx,starty,stopx,stopy){
|
2017-02-16 22:50:39 +08:00
|
|
|
return g.append('line')
|
2015-10-12 07:37:02 +02:00
|
|
|
.attr('x1', startx)
|
|
|
|
.attr('y1', starty)
|
|
|
|
.attr('x2', stopx )
|
|
|
|
.attr('y2', stopy )
|
|
|
|
.attr('stroke-width', 2)
|
|
|
|
.attr('stroke', '#526e52')
|
2015-01-05 14:41:00 +01:00
|
|
|
.attr('class','loopLine');
|
|
|
|
};
|
|
|
|
drawLoopLine(bounds.startx, bounds.starty, bounds.stopx , bounds.starty);
|
|
|
|
drawLoopLine(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy );
|
|
|
|
drawLoopLine(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy );
|
|
|
|
drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy );
|
|
|
|
if(typeof bounds.elsey !== 'undefined'){
|
2017-02-16 22:50:39 +08:00
|
|
|
drawLoopLine(bounds.startx, bounds.elsey, bounds.stopx, bounds.elsey).style('stroke-dasharray', '3, 3');
|
2015-01-05 14:41:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var txt = exports.getTextObj();
|
|
|
|
txt.text = labelText;
|
|
|
|
txt.x = bounds.startx;
|
|
|
|
txt.y = bounds.starty;
|
2016-02-10 08:33:12 +02:00
|
|
|
txt.labelMargin = 1.5 * 10; // This is the small box that says "loop"
|
|
|
|
txt.class = 'labelText'; // Its size & position are fixed.
|
2015-01-05 14:41:00 +01:00
|
|
|
txt.fill = 'white';
|
|
|
|
|
|
|
|
exports.drawLabel(g,txt);
|
|
|
|
|
|
|
|
txt = exports.getTextObj();
|
|
|
|
txt.text = '[ ' + bounds.title + ' ]';
|
|
|
|
txt.x = bounds.startx + (bounds.stopx - bounds.startx)/2;
|
|
|
|
txt.y = bounds.starty + 1.5 * conf.boxMargin;
|
|
|
|
txt.anchor = 'middle';
|
|
|
|
txt.class = 'loopText';
|
|
|
|
|
|
|
|
exports.drawText(g,txt);
|
|
|
|
|
2017-02-16 22:50:39 +08:00
|
|
|
if (typeof bounds.elseText !== 'undefined' && bounds.elseText !== "") {
|
2015-01-05 14:41:00 +01:00
|
|
|
txt.text = '[ ' + bounds.elseText + ' ]';
|
|
|
|
txt.y = bounds.elsey + 1.5 * conf.boxMargin;
|
|
|
|
exports.drawText(g, txt);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-01-05 13:41:32 +01:00
|
|
|
/**
|
|
|
|
* Setup arrow head and define the marker. The result is appended to the svg.
|
|
|
|
*/
|
|
|
|
exports.insertArrowHead = function(elem){
|
2015-10-12 07:37:02 +02:00
|
|
|
elem.append('defs').append('marker')
|
|
|
|
.attr('id', 'arrowhead')
|
|
|
|
.attr('refX', 5)
|
|
|
|
.attr('refY', 2)
|
|
|
|
.attr('markerWidth', 6)
|
|
|
|
.attr('markerHeight', 4)
|
|
|
|
.attr('orient', 'auto')
|
|
|
|
.append('path')
|
|
|
|
.attr('d', 'M 0,0 V 4 L6,2 Z'); //this is actual shape for arrowhead
|
2015-01-05 13:41:32 +01:00
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Setup arrow head and define the marker. The result is appended to the svg.
|
|
|
|
*/
|
|
|
|
exports.insertArrowCrossHead = function(elem){
|
2015-10-12 07:37:02 +02:00
|
|
|
var defs = elem.append('defs');
|
|
|
|
var marker = defs.append('marker')
|
|
|
|
.attr('id', 'crosshead')
|
|
|
|
.attr('markerWidth', 15)
|
|
|
|
.attr('markerHeight', 8)
|
|
|
|
.attr('orient', 'auto')
|
|
|
|
.attr('refX', 16)
|
|
|
|
.attr('refY', 4);
|
2015-01-09 08:21:48 +01:00
|
|
|
|
|
|
|
// The arrow
|
2015-10-12 07:37:02 +02:00
|
|
|
marker.append('path')
|
|
|
|
.attr('fill','black')
|
|
|
|
.attr('stroke','#000000')
|
|
|
|
.style('stroke-dasharray', ('0, 0'))
|
|
|
|
.attr('stroke-width','1px')
|
|
|
|
.attr('d', 'M 9,2 V 6 L16,4 Z');
|
2015-01-09 08:21:48 +01:00
|
|
|
|
|
|
|
// The cross
|
2015-10-12 07:37:02 +02:00
|
|
|
marker.append('path')
|
|
|
|
.attr('fill','none')
|
|
|
|
.attr('stroke','#000000')
|
|
|
|
.style('stroke-dasharray', ('0, 0'))
|
|
|
|
.attr('stroke-width','1px')
|
|
|
|
.attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
|
2015-01-09 08:21:48 +01:00
|
|
|
; //this is actual shape for arrowhead
|
|
|
|
|
2015-01-05 13:41:32 +01:00
|
|
|
};
|
2014-12-20 18:41:20 +01:00
|
|
|
|
2014-12-20 09:18:12 +01:00
|
|
|
exports.getTextObj = function(){
|
2014-12-21 20:59:11 +01:00
|
|
|
var txt = {
|
2014-12-20 09:18:12 +01:00
|
|
|
x: 0,
|
|
|
|
y: 0,
|
2014-12-20 18:41:20 +01:00
|
|
|
'fill':'black',
|
2014-12-20 09:18:12 +01:00
|
|
|
'text-anchor': 'start',
|
|
|
|
style: '#666',
|
|
|
|
width: 100,
|
|
|
|
height: 100,
|
2014-12-20 18:41:20 +01:00
|
|
|
textMargin:0,
|
2014-12-20 09:18:12 +01:00
|
|
|
rx: 0,
|
|
|
|
ry: 0
|
|
|
|
};
|
2014-12-21 20:59:11 +01:00
|
|
|
return txt;
|
2014-12-20 09:18:12 +01:00
|
|
|
};
|
|
|
|
|
2014-12-20 08:40:48 +01:00
|
|
|
exports.getNoteRect = function(){
|
|
|
|
var rect = {
|
2015-04-20 21:21:17 +02:00
|
|
|
x : 0,
|
|
|
|
y : 0,
|
|
|
|
fill : '#EDF2AE',
|
|
|
|
stroke : '#666',
|
|
|
|
width : 100,
|
|
|
|
anchor : 'start',
|
|
|
|
height : 100,
|
|
|
|
rx : 0,
|
|
|
|
ry : 0
|
2014-12-20 08:40:48 +01:00
|
|
|
};
|
|
|
|
return rect;
|
|
|
|
};
|
2016-12-01 00:16:44 -05:00
|
|
|
|
|
|
|
var _drawTextCandidateFunc = (function() {
|
2016-12-07 07:48:47 -05:00
|
|
|
function byText(content, g, x, y, width, height, textAttrs) {
|
|
|
|
var text = g.append('text')
|
|
|
|
.attr('x', x + width / 2).attr('y', y + height / 2 + 5)
|
|
|
|
.style('text-anchor', 'middle')
|
|
|
|
.text(content);
|
2016-12-17 18:03:11 -05:00
|
|
|
_setTextAttrs(text, textAttrs);
|
|
|
|
}
|
2016-12-07 07:48:47 -05:00
|
|
|
|
|
|
|
function byTspan(content, g, x, y, width, height, textAttrs) {
|
|
|
|
var text = g.append('text')
|
|
|
|
.attr('x', x + width / 2).attr('y', y)
|
|
|
|
.style('text-anchor', 'middle');
|
2016-12-17 18:03:11 -05:00
|
|
|
text.append('tspan')
|
2016-12-07 21:46:58 -05:00
|
|
|
.attr('x', x + width / 2).attr('dy', '0')
|
2016-12-07 07:48:47 -05:00
|
|
|
.text(content);
|
|
|
|
|
2016-12-07 21:46:58 -05:00
|
|
|
if(typeof(text.textwrap) !== 'undefined'){
|
|
|
|
text.textwrap({ //d3textwrap
|
|
|
|
x: x + width / 2, y: y, width: width, height: height
|
|
|
|
}, 0);
|
|
|
|
//vertical aligment after d3textwrap expans tspan to multiple tspans
|
|
|
|
var tspans = text.selectAll('tspan');
|
|
|
|
if (tspans.length > 0 && tspans[0].length > 0) {
|
|
|
|
tspans = tspans[0];
|
|
|
|
//set y of <text> to the mid y of the first line
|
2016-12-17 18:03:11 -05:00
|
|
|
text.attr('y', y + (height/2.0 - text[0][0].getBBox().height*(1 - 1.0/tspans.length)/2.0))
|
2016-12-07 21:46:58 -05:00
|
|
|
.attr("dominant-baseline", "central")
|
2016-12-17 18:03:11 -05:00
|
|
|
.attr("alignment-baseline", "central");
|
2016-12-07 21:46:58 -05:00
|
|
|
}
|
|
|
|
}
|
2016-12-17 18:03:11 -05:00
|
|
|
_setTextAttrs(text, textAttrs);
|
|
|
|
}
|
2016-12-07 07:48:47 -05:00
|
|
|
|
|
|
|
function byFo(content, g, x, y, width, height, textAttrs) {
|
2016-12-01 00:16:44 -05:00
|
|
|
var s = g.append('switch');
|
|
|
|
var f = s.append("foreignObject")
|
|
|
|
.attr('x', x).attr('y', y)
|
|
|
|
.attr('width', width).attr('height', height);
|
|
|
|
|
2016-12-07 07:48:47 -05:00
|
|
|
var text = f.append('div').style('display', 'table')
|
|
|
|
.style('height', '100%').style('width', '100%');
|
|
|
|
|
|
|
|
text.append('div').style('display', 'table-cell')
|
2016-12-01 00:16:44 -05:00
|
|
|
.style('text-align', 'center').style('vertical-align', 'middle')
|
2016-12-17 18:03:11 -05:00
|
|
|
.text(content);
|
2016-12-01 00:16:44 -05:00
|
|
|
|
2016-12-07 07:48:47 -05:00
|
|
|
byTspan(content, s, x, y, width, height, textAttrs);
|
2016-12-17 18:03:11 -05:00
|
|
|
_setTextAttrs(text, textAttrs);
|
|
|
|
}
|
2016-12-07 07:48:47 -05:00
|
|
|
|
2016-12-17 18:03:11 -05:00
|
|
|
function _setTextAttrs(toText, fromTextAttrsDict) {
|
|
|
|
for (var key in fromTextAttrsDict) {
|
|
|
|
if (fromTextAttrsDict.hasOwnProperty(key)) {
|
|
|
|
toText.attr(key, fromTextAttrsDict[key]);
|
2016-12-07 07:48:47 -05:00
|
|
|
}
|
2016-12-17 18:03:11 -05:00
|
|
|
}
|
|
|
|
}
|
2016-12-07 07:48:47 -05:00
|
|
|
|
2016-12-01 00:16:44 -05:00
|
|
|
return function(conf) {
|
2016-12-07 07:48:47 -05:00
|
|
|
return conf.textPlacement==='fo' ? byFo : (
|
2016-12-13 21:06:48 -05:00
|
|
|
conf.textPlacement==='old' ? byText: byTspan);
|
2016-12-01 00:16:44 -05:00
|
|
|
};
|
|
|
|
})();
|