diff --git a/lib/Importer.js b/lib/Importer.js index c2666de3..b50a6984 100644 --- a/lib/Importer.js +++ b/lib/Importer.js @@ -24,7 +24,7 @@ function importBpmnDiagram(diagram, definitions, done) { return { x: p.x, y: p.y }; }); - shape = { id: element.id, waypoints: waypoints }; + shape = { id: element.id, type: element.$type, waypoints: waypoints }; canvas.addConnection(shape); } diff --git a/lib/draw/BpmnRenderer.js b/lib/draw/BpmnRenderer.js index 578f2cb8..645afd7e 100644 --- a/lib/draw/BpmnRenderer.js +++ b/lib/draw/BpmnRenderer.js @@ -1,12 +1,96 @@ var bpmnModule = require('../di').defaultModule; +require('diagram-js/src/core/Events'); + var DefaultRenderer = require('diagram-js/src/draw/Renderer'); -function BpmnRenderer() { + +var flattenPoints = DefaultRenderer.flattenPoints; + +function BpmnRenderer(events) { var TASK_BORDER_RADIUS = 8; var INNER_OUTER_DIST = 3; + var markers = {}; + + function addMarker(id, element) { + markers[id] = element; + } + + function marker(id) { + return markers[id]; + } + + function initMarkers(paper) { + + addMarker('sequenceflow-end', + paper + .path('M 0 0 L 10 5 L 0 10 Z') + .attr({ + 'fill': 'black', + 'stroke': 'none' + }) + .marker(0, 0, 10, 10, 10, 5) + .attr({ + markerUnits: 'strokeWidth', + markerWidth: 10, + markerHeight: 6, + orient: 'auto', + overflow: 'visible' + })); + + addMarker('messageflow-start', + paper + .circle(4, 4, 4) + .attr({ + fill: 'white', + stroke: 'black', + 'stroke-width': 1.5, + 'stroke-dasharray': '1,0' + }) + .marker(0, 0, 10, 10, 4, 4) + .attr({ + markerUnits: 'strokeWidth', + markerWidth: 8, + markerHeight: 8, + orient: 'auto', + overflow: 'visible' + })); + + addMarker('messageflow-end', + paper + .path('M 0 0 L 10 5 L 0 10') + .attr({ + stroke: 'black', + fill: 'none', + 'stroke-width': 1.5, + 'stroke-linecap': 'round', + 'stroke-dasharray': '1,0' + }) + .marker(0, 0, 10, 10, 12, 5) + .attr({ + markerUnits: 'strokeWidth', + markerWidth: 10, + markerHeight: 5, + orient: 'auto', + overflow: 'visible' + })); + + addMarker('directed-association-end', + paper + .path('M 0 0 L 10 5 L 0 10 Z') + .attr('class', 'djs-connection-marker') + .marker(0, 0, 10, 10, 10, 5) + .attr({ + stroke: 'black', + fill: 'none', + 'stroke-width': 1.5, + 'stroke-linecap': 'round', + 'stroke-dasharray': '1,0' + })); + } + function drawCircle(p, width, height, offset) { offset = offset || 0; @@ -35,6 +119,29 @@ function BpmnRenderer() { }); } + function drawDiamond(p, width, height) { + + var x_2 = width / 2; + var y_2 = height / 2; + + var points = [x_2, 0, width, y_2, x_2, height, 0, y_2 ]; + + return p.polygon(points).attr({ + 'stroke': 'Black', + 'stroke-width': 2, + 'fill': 'White' + }); + } + + function drawLine(p, waypoints) { + var points = flattenPoints(waypoints); + + return p.polyline(points).attr({ + 'stroke-width': 2, + 'stroke': 'Black' + }); + } + function as(type) { return function(p, data) { return handlers[type](p, data); @@ -106,6 +213,43 @@ function BpmnRenderer() { 'bpmn:Lane': function(p, data) { var rect = drawRect(p, data.width, data.height, 0); return rect; + }, + + 'bpmn:InclusiveGateway': as('bpmn:Gateway'), + 'bpmn:ExclusiveGateway': as('bpmn:Gateway'), + 'bpmn:ComplexGateway': as('bpmn:Gateway'), + 'bpmn:ParallelGateway': as('bpmn:Gateway'), + 'bpmn:EventBasedGateway': as('bpmn:Gateway'), + 'bpmn:Gateway': function(p, data) { + + var diamond = drawDiamond(p, data.width, data.height); + + return diamond; + }, + + 'bpmn:SequenceFlow': function(p, data) { + var polyline = drawLine(p, data.waypoints); + + return polyline.attr({ + 'marker-end': marker('sequenceflow-end') + }); + }, + 'bpmn:Association': function(p, data) { + var polyline = drawLine(p, data.waypoints); + + // TODO(nre): style according to directed state + return polyline.attr({ + 'stroke-dasharray': '3,3' + }); + }, + 'bpmn:MessageFlow': function(p, data) { + var polyline = drawLine(p, data.waypoints); + + return polyline.attr({ + 'marker-end': marker('messageflow-end'), + 'marker-start': marker('messageflow-start'), + 'stroke-dasharray': '3,4' + }); } }; @@ -121,12 +265,33 @@ function BpmnRenderer() { } } + function drawConnection(parent, data) { + + var type = data.type; + var h = handlers[type]; + + if (!h) { + return BpmnRenderer.prototype.drawConnection(parent, data); + } else { + return h(parent, data); + } + } + + // hook onto canvas init event to initialize + // connection start/end markers on paper + events.on('canvas.init', function(event) { + var paper = event.paper; + + initMarkers(paper); + }); + this.drawShape = drawShape; + this.drawConnection = drawConnection; } BpmnRenderer.prototype = new DefaultRenderer(); -bpmnModule.type('renderer', [ 'snap', BpmnRenderer ]); +bpmnModule.type('renderer', [ 'events', BpmnRenderer ]); module.exports = BpmnRenderer; \ No newline at end of file