feat(draw): render colored markers

Related to #629
This commit is contained in:
Philipp Fromme 2016-11-28 16:53:19 +01:00 committed by Nico Rehwaldt
parent 4059f2c501
commit 8c26699d80
1 changed files with 173 additions and 144 deletions

View File

@ -40,7 +40,7 @@ var LABEL_STYLE = {
};
function BpmnRenderer(eventBus, styles, pathMap, priority) {
function BpmnRenderer(eventBus, styles, pathMap, canvas, priority) {
BaseRenderer.call(this, eventBus, priority);
@ -53,151 +53,170 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) {
var computeStyle = styles.computeStyle;
function addMarker(id, element) {
markers[id] = element;
}
function addMarker(id, options) {
var attrs = assign({
fill: 'black',
strokeWidth: 1,
strokeLinecap: 'round',
strokeDasharray: 'none'
}, options.attrs);
function marker(id) {
var marker = markers[id];
var ref = options.ref || { x: 0, y: 0 };
return 'url(#' + marker.id + ')';
}
var scale = options.scale || 1;
function initMarkers(svg) {
function createMarker(id, options) {
var attrs = assign({
fill: 'black',
strokeWidth: 1,
strokeLinecap: 'round',
strokeDasharray: 'none'
}, options.attrs);
var ref = options.ref || { x: 0, y: 0 };
var scale = options.scale || 1;
// fix for safari / chrome / firefox bug not correctly
// resetting stroke dash array
if (attrs.strokeDasharray === 'none') {
attrs.strokeDasharray = [10000, 1];
}
var marker = svgCreate('marker');
svgAttr(options.element, attrs);
svgAppend(marker, options.element);
svgAttr(marker, {
id: id,
viewBox: '0 0 20 20',
refX: ref.x,
refY: ref.y,
markerWidth: 20 * scale,
markerHeight: 20 * scale,
orient: 'auto'
});
var defs = domQuery('defs', svg);
if (!defs) {
defs = svgCreate('defs');
svgAppend(svg, defs);
}
svgAppend(defs, marker);
return addMarker(id, marker);
// fix for safari / chrome / firefox bug not correctly
// resetting stroke dash array
if (attrs.strokeDasharray === 'none') {
attrs.strokeDasharray = [10000, 1];
}
var sequenceflowEnd = svgCreate('path');
svgAttr(sequenceflowEnd, { d: 'M 1 5 L 11 10 L 1 15 Z' });
var marker = svgCreate('marker');
createMarker('sequenceflow-end', {
element: sequenceflowEnd,
ref: { x: 11, y: 10 },
scale: 0.5
svgAttr(options.element, attrs);
svgAppend(marker, options.element);
svgAttr(marker, {
id: id,
viewBox: '0 0 20 20',
refX: ref.x,
refY: ref.y,
markerWidth: 20 * scale,
markerHeight: 20 * scale,
orient: 'auto'
});
var messageflowStart = svgCreate('circle');
svgAttr(messageflowStart, { cx: 6, cy: 6, r: 3.5 });
var defs = domQuery('defs', canvas._svg);
createMarker('messageflow-start', {
element: messageflowStart,
attrs: {
fill: 'white',
stroke: 'black'
},
ref: { x: 6, y: 6 }
});
if (!defs) {
defs = svgCreate('defs');
var messageflowEnd = svgCreate('path');
svgAttr(messageflowEnd, { d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z' });
svgAppend(canvas._svg, defs);
}
createMarker('messageflow-end', {
element: messageflowEnd,
attrs: {
fill: 'white',
stroke: 'black',
strokeLinecap: 'butt'
},
ref: { x: 8.5, y: 5 }
});
svgAppend(defs, marker);
var associationStart = svgCreate('path');
svgAttr(associationStart, { d: 'M 11 5 L 1 10 L 11 15' });
markers[id] = marker;
}
createMarker('association-start', {
element: associationStart,
attrs: {
fill: 'none',
stroke: 'black',
strokeWidth: 1.5
},
ref: { x: 1, y: 10 },
scale: 0.5
});
function marker(type, fill, stroke) {
var id = type + '-' + fill + '-' + stroke;
var associationEnd = svgCreate('path');
svgAttr(associationEnd, { d: 'M 1 5 L 11 10 L 1 15' });
if (!includes(markers, id)) {
createMarker(type, fill, stroke);
}
createMarker('association-end', {
element: associationEnd,
attrs: {
fill: 'none',
stroke: 'black',
strokeWidth: 1.5
},
ref: { x: 12, y: 10 },
scale: 0.5
});
return 'url(#' + id + ')';
}
var conditionalflowMarker = svgCreate('path');
svgAttr(conditionalflowMarker, { d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z' });
function createMarker(type, fill, stroke) {
var id = type + '-' + fill + '-' + stroke;
createMarker('conditional-flow-marker', {
element: conditionalflowMarker,
attrs: {
fill: 'white',
stroke: 'black'
},
ref: { x: -1, y: 10 },
scale: 0.5
});
if (type === 'sequenceflow-end') {
var sequenceflowEnd = svgCreate('path');
svgAttr(sequenceflowEnd, { d: 'M 1 5 L 11 10 L 1 15 Z' });
var conditionaldefaultflowMarker = svgCreate('path');
svgAttr(conditionaldefaultflowMarker, { d: 'M 1 4 L 5 16' });
addMarker(id, {
element: sequenceflowEnd,
ref: { x: 11, y: 10 },
scale: 0.5,
attrs: {
fill: stroke,
stroke: stroke
}
});
}
createMarker('conditional-default-flow-marker', {
element: conditionaldefaultflowMarker,
attrs: {
stroke: 'black'
},
ref: { x: -5, y: 10 },
scale: 0.5
});
if (type === 'messageflow-start') {
var messageflowStart = svgCreate('circle');
svgAttr(messageflowStart, { cx: 6, cy: 6, r: 3.5 });
addMarker(id, {
element: messageflowStart,
attrs: {
fill: fill,
stroke: stroke
},
ref: { x: 6, y: 6 }
});
}
if (type === 'messageflow-end') {
var messageflowEnd = svgCreate('path');
svgAttr(messageflowEnd, { d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z' });
addMarker(id, {
element: messageflowEnd,
attrs: {
fill: fill,
stroke: stroke,
strokeLinecap: 'butt'
},
ref: { x: 8.5, y: 5 }
});
}
if (type === 'association-start') {
var associationStart = svgCreate('path');
svgAttr(associationStart, { d: 'M 11 5 L 1 10 L 11 15' });
addMarker(id, {
element: associationStart,
attrs: {
fill: 'none',
stroke: stroke,
strokeWidth: 1.5
},
ref: { x: 1, y: 10 },
scale: 0.5
});
}
if (type === 'association-end') {
var associationEnd = svgCreate('path');
svgAttr(associationEnd, { d: 'M 1 5 L 11 10 L 1 15' });
addMarker(id, {
element: associationEnd,
attrs: {
fill: 'none',
stroke: stroke,
strokeWidth: 1.5
},
ref: { x: 12, y: 10 },
scale: 0.5
});
}
if (type === 'conditional-flow-marker') {
var conditionalflowMarker = svgCreate('path');
svgAttr(conditionalflowMarker, { d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z' });
addMarker(id, {
element: conditionalflowMarker,
attrs: {
fill: fill,
stroke: stroke
},
ref: { x: -1, y: 10 },
scale: 0.5
});
}
if (type === 'conditional-default-flow-marker') {
var conditionaldefaultflowMarker = svgCreate('path');
svgAttr(conditionaldefaultflowMarker, { d: 'M 1 4 L 5 16' });
addMarker(id, {
element: conditionaldefaultflowMarker,
attrs: {
stroke: stroke
},
ref: { x: -5, y: 10 },
scale: 0.5
});
}
}
function drawCircle(parentGfx, width, height, offset, attrs) {
@ -1280,9 +1299,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) {
'bpmn:SequenceFlow': function(parentGfx, element) {
var pathData = createPathFromConnection(element);
var fill = getFillColor(element),
stroke = getStrokeColor(element);
var attrs = {
strokeLinejoin: 'round',
markerEnd: marker('sequenceflow-end'),
markerEnd: marker('sequenceflow-end', fill, stroke),
stroke: getStrokeColor(element)
};
@ -1294,7 +1316,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) {
// conditional flow marker
if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) {
svgAttr(path, {
markerStart: marker('conditional-flow-marker')
markerStart: marker('conditional-flow-marker', fill, stroke)
});
}
@ -1302,7 +1324,7 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) {
if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) &&
source.default === sequenceFlow) {
svgAttr(path, {
markerStart: marker('conditional-default-flow-marker')
markerStart: marker('conditional-default-flow-marker', fill, stroke)
});
}
@ -1312,31 +1334,41 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) {
var semantic = getSemantic(element);
var fill = getFillColor(element),
stroke = getStrokeColor(element);
attrs = assign({
strokeDasharray: '0.5, 5',
strokeLinecap: 'round',
strokeLinejoin: 'round'
strokeLinejoin: 'round',
stroke: getStrokeColor(element)
}, attrs || {});
if (semantic.associationDirection === 'One' ||
semantic.associationDirection === 'Both') {
attrs.markerEnd = marker('association-end');
attrs.markerEnd = marker('association-end', fill, stroke);
}
if (semantic.associationDirection === 'Both') {
attrs.markerStart = marker('association-start');
attrs.markerStart = marker('association-start', fill, stroke);
}
return drawLine(parentGfx, element.waypoints, attrs);
},
'bpmn:DataInputAssociation': function(parentGfx, element) {
var fill = getFillColor(element),
stroke = getStrokeColor(element);
return renderer('bpmn:Association')(parentGfx, element, {
markerEnd: marker('association-end')
markerEnd: marker('association-end', fill, stroke)
});
},
'bpmn:DataOutputAssociation': function(parentGfx, element) {
var fill = getFillColor(element),
stroke = getStrokeColor(element);
return renderer('bpmn:Association')(parentGfx, element, {
markerEnd: marker('association-end')
markerEnd: marker('association-end', fill, stroke)
});
},
'bpmn:MessageFlow': function(parentGfx, element) {
@ -1344,11 +1376,14 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) {
var semantic = getSemantic(element),
di = getDi(element);
var fill = getFillColor(element),
stroke = getStrokeColor(element);
var pathData = createPathFromConnection(element);
var attrs = {
markerEnd: marker('messageflow-end'),
markerStart: marker('messageflow-start'),
markerEnd: marker('messageflow-end', fill, stroke),
markerStart: marker('messageflow-start', fill, stroke),
strokeDasharray: '10, 12',
strokeLinecap: 'round',
strokeLinejoin: 'round',
@ -1735,18 +1770,12 @@ function BpmnRenderer(eventBus, styles, pathMap, priority) {
strokeWidth: 2
});
}
// hook onto canvas init event to initialize
// connection start/end markers on svg
eventBus.on('canvas.init', function(event) {
initMarkers(event.svg);
});
}
inherits(BpmnRenderer, BaseRenderer);
BpmnRenderer.$inject = [ 'eventBus', 'styles', 'pathMap' ];
BpmnRenderer.$inject = [ 'eventBus', 'styles', 'pathMap', 'canvas' ];
module.exports = BpmnRenderer;