BpmnRenderer.js 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341
  1. import inherits from 'inherits-browser';
  2. import {
  3. assign,
  4. forEach,
  5. isObject
  6. } from 'min-dash';
  7. import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer';
  8. import {
  9. isExpanded,
  10. isHorizontal,
  11. isEventSubProcess
  12. } from '../util/DiUtil';
  13. import {
  14. getLabel
  15. } from '../util/LabelUtil';
  16. import {
  17. is
  18. } from '../util/ModelUtil';
  19. import {
  20. createLine
  21. } from 'diagram-js/lib/util/RenderUtil';
  22. import {
  23. isTypedEvent,
  24. isThrowEvent,
  25. isCollection,
  26. getBounds,
  27. getDi,
  28. getSemantic,
  29. getCirclePath,
  30. getRoundRectPath,
  31. getDiamondPath,
  32. getRectPath,
  33. getFillColor,
  34. getStrokeColor,
  35. getLabelColor,
  36. getHeight,
  37. getWidth
  38. } from './BpmnRenderUtil';
  39. import {
  40. query as domQuery
  41. } from 'min-dom';
  42. import {
  43. append as svgAppend,
  44. attr as svgAttr,
  45. create as svgCreate,
  46. classes as svgClasses
  47. } from 'tiny-svg';
  48. import {
  49. rotate,
  50. transform,
  51. translate
  52. } from 'diagram-js/lib/util/SvgTransformUtil';
  53. import Ids from 'ids';
  54. import { black } from './BpmnRenderUtil';
  55. var rendererIds = new Ids();
  56. var ELEMENT_LABEL_DISTANCE = 10,
  57. INNER_OUTER_DIST = 3,
  58. PARTICIPANT_STROKE_WIDTH = 1.5,
  59. TASK_BORDER_RADIUS = 10;
  60. var DEFAULT_OPACITY = 0.95,
  61. FULL_OPACITY = 1,
  62. LOW_OPACITY = 0.25;
  63. /**
  64. * @typedef { Partial<{
  65. * defaultFillColor: string,
  66. * defaultStrokeColor: string,
  67. * defaultLabelColor: string
  68. * }> } BpmnRendererConfig
  69. *
  70. * @typedef { Partial<{
  71. * fill: string,
  72. * stroke: string,
  73. * width: string,
  74. * height: string
  75. * }> } Attrs
  76. */
  77. /**
  78. * @typedef { import('../model/Types').Element } Element
  79. */
  80. /**
  81. * A renderer for BPMN elements
  82. *
  83. * @param {BpmnRendererConfig} config
  84. * @param {import('diagram-js/lib/core/EventBus').default} eventBus
  85. * @param {import('diagram-js/lib/draw/Styles').default} styles
  86. * @param {import('./PathMap').default} pathMap
  87. * @param {import('diagram-js/lib/core/Canvas').default} canvas
  88. * @param {import('./TextRenderer').default} textRenderer
  89. * @param {number} [priority]
  90. */
  91. export default function BpmnRenderer(
  92. config, eventBus, styles, pathMap,
  93. canvas, textRenderer, priority) {
  94. BaseRenderer.call(this, eventBus, priority);
  95. var defaultFillColor = config && config.defaultFillColor,
  96. defaultStrokeColor = config && config.defaultStrokeColor,
  97. defaultLabelColor = config && config.defaultLabelColor;
  98. var rendererId = rendererIds.next();
  99. var markers = {};
  100. function shapeStyle(attrs) {
  101. return styles.computeStyle(attrs, {
  102. strokeLinecap: 'round',
  103. strokeLinejoin: 'round',
  104. stroke: black,
  105. strokeWidth: 2,
  106. fill: 'white'
  107. });
  108. }
  109. function lineStyle(attrs) {
  110. return styles.computeStyle(attrs, [ 'no-fill' ], {
  111. strokeLinecap: 'round',
  112. strokeLinejoin: 'round',
  113. stroke: black,
  114. strokeWidth: 2
  115. });
  116. }
  117. function addMarker(id, options) {
  118. var {
  119. ref = { x: 0, y: 0 },
  120. scale = 1,
  121. element
  122. } = options;
  123. var marker = svgCreate('marker', {
  124. id: id,
  125. viewBox: '0 0 20 20',
  126. refX: ref.x,
  127. refY: ref.y,
  128. markerWidth: 20 * scale,
  129. markerHeight: 20 * scale,
  130. orient: 'auto'
  131. });
  132. svgAppend(marker, element);
  133. var defs = domQuery('defs', canvas._svg);
  134. if (!defs) {
  135. defs = svgCreate('defs');
  136. svgAppend(canvas._svg, defs);
  137. }
  138. svgAppend(defs, marker);
  139. markers[id] = marker;
  140. }
  141. function colorEscape(str) {
  142. // only allow characters and numbers
  143. return str.replace(/[^0-9a-zA-Z]+/g, '_');
  144. }
  145. function marker(type, fill, stroke) {
  146. var id = type + '-' + colorEscape(fill) + '-' + colorEscape(stroke) + '-' + rendererId;
  147. if (!markers[id]) {
  148. createMarker(id, type, fill, stroke);
  149. }
  150. return 'url(#' + id + ')';
  151. }
  152. function createMarker(id, type, fill, stroke) {
  153. if (type === 'sequenceflow-end') {
  154. var sequenceflowEnd = svgCreate('path', {
  155. d: 'M 1 5 L 11 10 L 1 15 Z',
  156. ...shapeStyle({
  157. fill: stroke,
  158. stroke: stroke,
  159. strokeWidth: 1
  160. })
  161. });
  162. addMarker(id, {
  163. element: sequenceflowEnd,
  164. ref: { x: 11, y: 10 },
  165. scale: 0.5
  166. });
  167. }
  168. if (type === 'messageflow-start') {
  169. var messageflowStart = svgCreate('circle', {
  170. cx: 6,
  171. cy: 6,
  172. r: 3.5,
  173. ...shapeStyle({
  174. fill,
  175. stroke: stroke,
  176. strokeWidth: 1,
  177. // fix for safari / chrome / firefox bug not correctly
  178. // resetting stroke dash array
  179. strokeDasharray: [ 10000, 1 ]
  180. })
  181. });
  182. addMarker(id, {
  183. element: messageflowStart,
  184. ref: { x: 6, y: 6 }
  185. });
  186. }
  187. if (type === 'messageflow-end') {
  188. var messageflowEnd = svgCreate('path', {
  189. d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z',
  190. ...shapeStyle({
  191. fill,
  192. stroke: stroke,
  193. strokeWidth: 1,
  194. // fix for safari / chrome / firefox bug not correctly
  195. // resetting stroke dash array
  196. strokeDasharray: [ 10000, 1 ]
  197. })
  198. });
  199. addMarker(id, {
  200. element: messageflowEnd,
  201. ref: { x: 8.5, y: 5 }
  202. });
  203. }
  204. if (type === 'association-start') {
  205. var associationStart = svgCreate('path', {
  206. d: 'M 11 5 L 1 10 L 11 15',
  207. ...lineStyle({
  208. fill: 'none',
  209. stroke,
  210. strokeWidth: 1.5,
  211. // fix for safari / chrome / firefox bug not correctly
  212. // resetting stroke dash array
  213. strokeDasharray: [ 10000, 1 ]
  214. })
  215. });
  216. addMarker(id, {
  217. element: associationStart,
  218. ref: { x: 1, y: 10 },
  219. scale: 0.5
  220. });
  221. }
  222. if (type === 'association-end') {
  223. var associationEnd = svgCreate('path', {
  224. d: 'M 1 5 L 11 10 L 1 15',
  225. ...lineStyle({
  226. fill: 'none',
  227. stroke,
  228. strokeWidth: 1.5,
  229. // fix for safari / chrome / firefox bug not correctly
  230. // resetting stroke dash array
  231. strokeDasharray: [ 10000, 1 ]
  232. })
  233. });
  234. addMarker(id, {
  235. element: associationEnd,
  236. ref: { x: 11, y: 10 },
  237. scale: 0.5
  238. });
  239. }
  240. if (type === 'conditional-flow-marker') {
  241. var conditionalFlowMarker = svgCreate('path', {
  242. d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z',
  243. ...shapeStyle({
  244. fill,
  245. stroke: stroke
  246. })
  247. });
  248. addMarker(id, {
  249. element: conditionalFlowMarker,
  250. ref: { x: -1, y: 10 },
  251. scale: 0.5
  252. });
  253. }
  254. if (type === 'conditional-default-flow-marker') {
  255. var defaultFlowMarker = svgCreate('path', {
  256. d: 'M 6 4 L 10 16',
  257. ...shapeStyle({
  258. stroke: stroke
  259. })
  260. });
  261. addMarker(id, {
  262. element: defaultFlowMarker,
  263. ref: { x: 0, y: 10 },
  264. scale: 0.5
  265. });
  266. }
  267. }
  268. function drawCircle(parentGfx, width, height, offset, attrs = {}) {
  269. if (isObject(offset)) {
  270. attrs = offset;
  271. offset = 0;
  272. }
  273. offset = offset || 0;
  274. attrs = shapeStyle(attrs);
  275. var cx = width / 2,
  276. cy = height / 2;
  277. var circle = svgCreate('circle', {
  278. cx: cx,
  279. cy: cy,
  280. r: Math.round((width + height) / 4 - offset),
  281. ...attrs
  282. });
  283. svgAppend(parentGfx, circle);
  284. return circle;
  285. }
  286. function drawRect(parentGfx, width, height, r, offset, attrs) {
  287. if (isObject(offset)) {
  288. attrs = offset;
  289. offset = 0;
  290. }
  291. offset = offset || 0;
  292. attrs = shapeStyle(attrs);
  293. var rect = svgCreate('rect', {
  294. x: offset,
  295. y: offset,
  296. width: width - offset * 2,
  297. height: height - offset * 2,
  298. rx: r,
  299. ry: r,
  300. ...attrs
  301. });
  302. svgAppend(parentGfx, rect);
  303. return rect;
  304. }
  305. function drawDiamond(parentGfx, width, height, attrs) {
  306. var x_2 = width / 2;
  307. var y_2 = height / 2;
  308. var points = [
  309. { x: x_2, y: 0 },
  310. { x: width, y: y_2 },
  311. { x: x_2, y: height },
  312. { x: 0, y: y_2 }
  313. ];
  314. var pointsString = points.map(function(point) {
  315. return point.x + ',' + point.y;
  316. }).join(' ');
  317. attrs = shapeStyle(attrs);
  318. var polygon = svgCreate('polygon', {
  319. ...attrs,
  320. points: pointsString
  321. });
  322. svgAppend(parentGfx, polygon);
  323. return polygon;
  324. }
  325. /**
  326. * @param {SVGElement} parentGfx
  327. * @param {Point[]} waypoints
  328. * @param {any} attrs
  329. * @param {number} [radius]
  330. *
  331. * @return {SVGElement}
  332. */
  333. function drawLine(parentGfx, waypoints, attrs, radius) {
  334. attrs = lineStyle(attrs);
  335. var line = createLine(waypoints, attrs, radius);
  336. svgAppend(parentGfx, line);
  337. return line;
  338. }
  339. /**
  340. * @param {SVGElement} parentGfx
  341. * @param {Point[]} waypoints
  342. * @param {any} attrs
  343. *
  344. * @return {SVGElement}
  345. */
  346. function drawConnectionSegments(parentGfx, waypoints, attrs) {
  347. return drawLine(parentGfx, waypoints, attrs, 5);
  348. }
  349. function drawPath(parentGfx, d, attrs) {
  350. attrs = lineStyle(attrs);
  351. var path = svgCreate('path', {
  352. ...attrs,
  353. d
  354. });
  355. svgAppend(parentGfx, path);
  356. return path;
  357. }
  358. function drawMarker(type, parentGfx, path, attrs) {
  359. return drawPath(parentGfx, path, assign({ 'data-marker': type }, attrs));
  360. }
  361. function renderer(type) {
  362. return handlers[type];
  363. }
  364. function as(type) {
  365. return function(parentGfx, element, attrs) {
  366. return renderer(type)(parentGfx, element, attrs);
  367. };
  368. }
  369. var eventIconRenderers = {
  370. 'bpmn:MessageEventDefinition': function(parentGfx, element, attrs = {}, isThrowing) {
  371. var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
  372. xScaleFactor: 0.9,
  373. yScaleFactor: 0.9,
  374. containerWidth: element.width,
  375. containerHeight: element.height,
  376. position: {
  377. mx: 0.235,
  378. my: 0.315
  379. }
  380. });
  381. var fill = isThrowing
  382. ? getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  383. : getFillColor(element, defaultFillColor, attrs.fill);
  384. var stroke = isThrowing
  385. ? getFillColor(element, defaultFillColor, attrs.fill)
  386. : getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  387. var messagePath = drawPath(parentGfx, pathData, {
  388. fill,
  389. stroke,
  390. strokeWidth: 1
  391. });
  392. return messagePath;
  393. },
  394. 'bpmn:TimerEventDefinition': function(parentGfx, element, attrs = {}) {
  395. var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, {
  396. fill: getFillColor(element, defaultFillColor, attrs.fill),
  397. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  398. strokeWidth: 2
  399. });
  400. var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
  401. xScaleFactor: 0.75,
  402. yScaleFactor: 0.75,
  403. containerWidth: element.width,
  404. containerHeight: element.height,
  405. position: {
  406. mx: 0.5,
  407. my: 0.5
  408. }
  409. });
  410. drawPath(parentGfx, pathData, {
  411. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  412. strokeWidth: 2
  413. });
  414. for (var i = 0; i < 12; i++) {
  415. var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
  416. xScaleFactor: 0.75,
  417. yScaleFactor: 0.75,
  418. containerWidth: element.width,
  419. containerHeight: element.height,
  420. position: {
  421. mx: 0.5,
  422. my: 0.5
  423. }
  424. });
  425. var width = element.width / 2,
  426. height = element.height / 2;
  427. drawPath(parentGfx, linePathData, {
  428. strokeWidth: 1,
  429. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  430. transform: 'rotate(' + (i * 30) + ',' + height + ',' + width + ')'
  431. });
  432. }
  433. return circle;
  434. },
  435. 'bpmn:EscalationEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  436. var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
  437. xScaleFactor: 1,
  438. yScaleFactor: 1,
  439. containerWidth: event.width,
  440. containerHeight: event.height,
  441. position: {
  442. mx: 0.5,
  443. my: 0.2
  444. }
  445. });
  446. var fill = isThrowing
  447. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  448. : getFillColor(event, defaultFillColor, attrs.fill);
  449. return drawPath(parentGfx, pathData, {
  450. fill,
  451. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  452. strokeWidth: 1
  453. });
  454. },
  455. 'bpmn:ConditionalEventDefinition': function(parentGfx, event, attrs = {}) {
  456. var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
  457. xScaleFactor: 1,
  458. yScaleFactor: 1,
  459. containerWidth: event.width,
  460. containerHeight: event.height,
  461. position: {
  462. mx: 0.5,
  463. my: 0.222
  464. }
  465. });
  466. return drawPath(parentGfx, pathData, {
  467. fill: getFillColor(event, defaultFillColor, attrs.fill),
  468. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  469. strokeWidth: 1
  470. });
  471. },
  472. 'bpmn:LinkEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  473. var pathData = pathMap.getScaledPath('EVENT_LINK', {
  474. xScaleFactor: 1,
  475. yScaleFactor: 1,
  476. containerWidth: event.width,
  477. containerHeight: event.height,
  478. position: {
  479. mx: 0.57,
  480. my: 0.263
  481. }
  482. });
  483. var fill = isThrowing
  484. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  485. : getFillColor(event, defaultFillColor, attrs.fill);
  486. return drawPath(parentGfx, pathData, {
  487. fill,
  488. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  489. strokeWidth: 1
  490. });
  491. },
  492. 'bpmn:ErrorEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  493. var pathData = pathMap.getScaledPath('EVENT_ERROR', {
  494. xScaleFactor: 1.1,
  495. yScaleFactor: 1.1,
  496. containerWidth: event.width,
  497. containerHeight: event.height,
  498. position: {
  499. mx: 0.2,
  500. my: 0.722
  501. }
  502. });
  503. var fill = isThrowing
  504. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  505. : getFillColor(event, defaultFillColor, attrs.fill);
  506. return drawPath(parentGfx, pathData, {
  507. fill,
  508. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  509. strokeWidth: 1
  510. });
  511. },
  512. 'bpmn:CancelEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  513. var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
  514. xScaleFactor: 1.0,
  515. yScaleFactor: 1.0,
  516. containerWidth: event.width,
  517. containerHeight: event.height,
  518. position: {
  519. mx: 0.638,
  520. my: -0.055
  521. }
  522. });
  523. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor, attrs.stroke) : 'none';
  524. var path = drawPath(parentGfx, pathData, {
  525. fill,
  526. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  527. strokeWidth: 1
  528. });
  529. rotate(path, 45);
  530. return path;
  531. },
  532. 'bpmn:CompensateEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  533. var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
  534. xScaleFactor: 1,
  535. yScaleFactor: 1,
  536. containerWidth: event.width,
  537. containerHeight: event.height,
  538. position: {
  539. mx: 0.22,
  540. my: 0.5
  541. }
  542. });
  543. var fill = isThrowing
  544. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  545. : getFillColor(event, defaultFillColor, attrs.fill);
  546. return drawPath(parentGfx, pathData, {
  547. fill,
  548. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  549. strokeWidth: 1
  550. });
  551. },
  552. 'bpmn:SignalEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  553. var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
  554. xScaleFactor: 0.9,
  555. yScaleFactor: 0.9,
  556. containerWidth: event.width,
  557. containerHeight: event.height,
  558. position: {
  559. mx: 0.5,
  560. my: 0.2
  561. }
  562. });
  563. var fill = isThrowing
  564. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  565. : getFillColor(event, defaultFillColor, attrs.fill);
  566. return drawPath(parentGfx, pathData, {
  567. strokeWidth: 1,
  568. fill,
  569. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  570. });
  571. },
  572. 'bpmn:MultipleEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  573. var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
  574. xScaleFactor: 1.1,
  575. yScaleFactor: 1.1,
  576. containerWidth: event.width,
  577. containerHeight: event.height,
  578. position: {
  579. mx: 0.222,
  580. my: 0.36
  581. }
  582. });
  583. var fill = isThrowing
  584. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  585. : getFillColor(event, defaultFillColor, attrs.fill);
  586. return drawPath(parentGfx, pathData, {
  587. fill,
  588. strokeWidth: 1
  589. });
  590. },
  591. 'bpmn:ParallelMultipleEventDefinition': function(parentGfx, event, attrs = {}) {
  592. var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
  593. xScaleFactor: 1.2,
  594. yScaleFactor: 1.2,
  595. containerWidth: event.width,
  596. containerHeight: event.height,
  597. position: {
  598. mx: 0.458,
  599. my: 0.194
  600. }
  601. });
  602. return drawPath(parentGfx, pathData, {
  603. fill: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  604. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  605. strokeWidth: 1
  606. });
  607. },
  608. 'bpmn:TerminateEventDefinition': function(parentGfx, element, attrs = {}) {
  609. var circle = drawCircle(parentGfx, element.width, element.height, 8, {
  610. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  611. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  612. strokeWidth: 4
  613. });
  614. return circle;
  615. }
  616. };
  617. function renderEventIcon(element, parentGfx, attrs = {}) {
  618. var semantic = getSemantic(element),
  619. isThrowing = isThrowEvent(semantic);
  620. if (semantic.get('eventDefinitions') && semantic.get('eventDefinitions').length > 1) {
  621. if (semantic.get('parallelMultiple')) {
  622. return eventIconRenderers[ 'bpmn:ParallelMultipleEventDefinition' ](parentGfx, element, attrs, isThrowing);
  623. }
  624. else {
  625. return eventIconRenderers[ 'bpmn:MultipleEventDefinition' ](parentGfx, element, attrs, isThrowing);
  626. }
  627. }
  628. if (isTypedEvent(semantic, 'bpmn:MessageEventDefinition')) {
  629. return eventIconRenderers[ 'bpmn:MessageEventDefinition' ](parentGfx, element, attrs, isThrowing);
  630. }
  631. if (isTypedEvent(semantic, 'bpmn:TimerEventDefinition')) {
  632. return eventIconRenderers[ 'bpmn:TimerEventDefinition' ](parentGfx, element, attrs, isThrowing);
  633. }
  634. if (isTypedEvent(semantic, 'bpmn:ConditionalEventDefinition')) {
  635. return eventIconRenderers[ 'bpmn:ConditionalEventDefinition' ](parentGfx, element, attrs, isThrowing);
  636. }
  637. if (isTypedEvent(semantic, 'bpmn:SignalEventDefinition')) {
  638. return eventIconRenderers[ 'bpmn:SignalEventDefinition' ](parentGfx, element, attrs, isThrowing);
  639. }
  640. if (isTypedEvent(semantic, 'bpmn:EscalationEventDefinition')) {
  641. return eventIconRenderers[ 'bpmn:EscalationEventDefinition' ](parentGfx, element, attrs, isThrowing);
  642. }
  643. if (isTypedEvent(semantic, 'bpmn:LinkEventDefinition')) {
  644. return eventIconRenderers[ 'bpmn:LinkEventDefinition' ](parentGfx, element, attrs, isThrowing);
  645. }
  646. if (isTypedEvent(semantic, 'bpmn:ErrorEventDefinition')) {
  647. return eventIconRenderers[ 'bpmn:ErrorEventDefinition' ](parentGfx, element, attrs, isThrowing);
  648. }
  649. if (isTypedEvent(semantic, 'bpmn:CancelEventDefinition')) {
  650. return eventIconRenderers[ 'bpmn:CancelEventDefinition' ](parentGfx, element, attrs, isThrowing);
  651. }
  652. if (isTypedEvent(semantic, 'bpmn:CompensateEventDefinition')) {
  653. return eventIconRenderers[ 'bpmn:CompensateEventDefinition' ](parentGfx, element, attrs, isThrowing);
  654. }
  655. if (isTypedEvent(semantic, 'bpmn:TerminateEventDefinition')) {
  656. return eventIconRenderers[ 'bpmn:TerminateEventDefinition' ](parentGfx, element, attrs, isThrowing);
  657. }
  658. return null;
  659. }
  660. var taskMarkerRenderers = {
  661. 'ParticipantMultiplicityMarker': function(parentGfx, element, attrs = {}) {
  662. var width = getWidth(element, attrs),
  663. height = getHeight(element, attrs);
  664. var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
  665. xScaleFactor: 1,
  666. yScaleFactor: 1,
  667. containerWidth: width,
  668. containerHeight: height,
  669. position: {
  670. mx: ((width / 2 - 6) / width),
  671. my: (height - 15) / height
  672. }
  673. });
  674. drawMarker('participant-multiplicity', parentGfx, markerPath, {
  675. strokeWidth: 2,
  676. fill: getFillColor(element, defaultFillColor, attrs.fill),
  677. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  678. });
  679. },
  680. 'SubProcessMarker': function(parentGfx, element, attrs = {}) {
  681. var markerRect = drawRect(parentGfx, 14, 14, 0, {
  682. strokeWidth: 1,
  683. fill: getFillColor(element, defaultFillColor, attrs.fill),
  684. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  685. });
  686. translate(markerRect, element.width / 2 - 7.5, element.height - 20);
  687. var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', {
  688. xScaleFactor: 1.5,
  689. yScaleFactor: 1.5,
  690. containerWidth: element.width,
  691. containerHeight: element.height,
  692. position: {
  693. mx: (element.width / 2 - 7.5) / element.width,
  694. my: (element.height - 20) / element.height
  695. }
  696. });
  697. drawMarker('sub-process', parentGfx, markerPath, {
  698. fill: getFillColor(element, defaultFillColor, attrs.fill),
  699. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  700. });
  701. },
  702. 'ParallelMarker': function(parentGfx, element, attrs) {
  703. var width = getWidth(element, attrs),
  704. height = getHeight(element, attrs);
  705. var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
  706. xScaleFactor: 1,
  707. yScaleFactor: 1,
  708. containerWidth: width,
  709. containerHeight: height,
  710. position: {
  711. mx: ((width / 2 + attrs.parallel) / width),
  712. my: (height - 20) / height
  713. }
  714. });
  715. drawMarker('parallel', parentGfx, markerPath, {
  716. fill: getFillColor(element, defaultFillColor, attrs.fill),
  717. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  718. });
  719. },
  720. 'SequentialMarker': function(parentGfx, element, attrs) {
  721. var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
  722. xScaleFactor: 1,
  723. yScaleFactor: 1,
  724. containerWidth: element.width,
  725. containerHeight: element.height,
  726. position: {
  727. mx: ((element.width / 2 + attrs.seq) / element.width),
  728. my: (element.height - 19) / element.height
  729. }
  730. });
  731. drawMarker('sequential', parentGfx, markerPath, {
  732. fill: getFillColor(element, defaultFillColor, attrs.fill),
  733. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  734. });
  735. },
  736. 'CompensationMarker': function(parentGfx, element, attrs) {
  737. var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', {
  738. xScaleFactor: 1,
  739. yScaleFactor: 1,
  740. containerWidth: element.width,
  741. containerHeight: element.height,
  742. position: {
  743. mx: ((element.width / 2 + attrs.compensation) / element.width),
  744. my: (element.height - 13) / element.height
  745. }
  746. });
  747. drawMarker('compensation', parentGfx, markerMath, {
  748. strokeWidth: 1,
  749. fill: getFillColor(element, defaultFillColor, attrs.fill),
  750. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  751. });
  752. },
  753. 'LoopMarker': function(parentGfx, element, attrs) {
  754. var width = getWidth(element, attrs),
  755. height = getHeight(element, attrs);
  756. var markerPath = pathMap.getScaledPath('MARKER_LOOP', {
  757. xScaleFactor: 1,
  758. yScaleFactor: 1,
  759. containerWidth: width,
  760. containerHeight: height,
  761. position: {
  762. mx: ((width / 2 + attrs.loop) / width),
  763. my: (height - 7) / height
  764. }
  765. });
  766. drawMarker('loop', parentGfx, markerPath, {
  767. strokeWidth: 1.5,
  768. fill: 'none',
  769. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  770. strokeMiterlimit: 0.5
  771. });
  772. },
  773. 'AdhocMarker': function(parentGfx, element, attrs) {
  774. var width = getWidth(element, attrs),
  775. height = getHeight(element, attrs);
  776. var markerPath = pathMap.getScaledPath('MARKER_ADHOC', {
  777. xScaleFactor: 1,
  778. yScaleFactor: 1,
  779. containerWidth: width,
  780. containerHeight: height,
  781. position: {
  782. mx: ((width / 2 + attrs.adhoc) / width),
  783. my: (height - 15) / height
  784. }
  785. });
  786. drawMarker('adhoc', parentGfx, markerPath, {
  787. strokeWidth: 1,
  788. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  789. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  790. });
  791. }
  792. };
  793. function renderTaskMarker(type, parentGfx, element, attrs) {
  794. taskMarkerRenderers[ type ](parentGfx, element, attrs);
  795. }
  796. function renderTaskMarkers(parentGfx, element, taskMarkers, attrs = {}) {
  797. attrs = {
  798. fill: attrs.fill,
  799. stroke: attrs.stroke,
  800. width: getWidth(element, attrs),
  801. height: getHeight(element, attrs)
  802. };
  803. var semantic = getSemantic(element);
  804. var subprocess = taskMarkers && taskMarkers.includes('SubProcessMarker');
  805. if (subprocess) {
  806. attrs = {
  807. ...attrs,
  808. seq: -21,
  809. parallel: -22,
  810. compensation: -42,
  811. loop: -18,
  812. adhoc: 10
  813. };
  814. } else {
  815. attrs = {
  816. ...attrs,
  817. seq: -5,
  818. parallel: -6,
  819. compensation: -27,
  820. loop: 0,
  821. adhoc: 10
  822. };
  823. }
  824. forEach(taskMarkers, function(marker) {
  825. renderTaskMarker(marker, parentGfx, element, attrs);
  826. });
  827. if (semantic.get('isForCompensation')) {
  828. renderTaskMarker('CompensationMarker', parentGfx, element, attrs);
  829. }
  830. if (is(semantic, 'bpmn:AdHocSubProcess')) {
  831. renderTaskMarker('AdhocMarker', parentGfx, element, attrs);
  832. }
  833. var loopCharacteristics = semantic.get('loopCharacteristics'),
  834. isSequential = loopCharacteristics && loopCharacteristics.get('isSequential');
  835. if (loopCharacteristics) {
  836. if (isSequential === undefined) {
  837. renderTaskMarker('LoopMarker', parentGfx, element, attrs);
  838. }
  839. if (isSequential === false) {
  840. renderTaskMarker('ParallelMarker', parentGfx, element, attrs);
  841. }
  842. if (isSequential === true) {
  843. renderTaskMarker('SequentialMarker', parentGfx, element, attrs);
  844. }
  845. }
  846. }
  847. function renderLabel(parentGfx, label, attrs = {}) {
  848. attrs = assign({
  849. size: {
  850. width: 100
  851. }
  852. }, attrs);
  853. var text = textRenderer.createText(label || '', attrs);
  854. svgClasses(text).add('djs-label');
  855. svgAppend(parentGfx, text);
  856. return text;
  857. }
  858. function renderEmbeddedLabel(parentGfx, element, align, attrs = {}) {
  859. var semantic = getSemantic(element);
  860. var box = getBounds({
  861. x: element.x,
  862. y: element.y,
  863. width: element.width,
  864. height: element.height
  865. }, attrs);
  866. return renderLabel(parentGfx, semantic.name, {
  867. align,
  868. box,
  869. padding: 7,
  870. style: {
  871. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  872. }
  873. });
  874. }
  875. function renderExternalLabel(parentGfx, element, attrs = {}) {
  876. var box = {
  877. width: 90,
  878. height: 30,
  879. x: element.width / 2 + element.x,
  880. y: element.height / 2 + element.y
  881. };
  882. return renderLabel(parentGfx, getLabel(element), {
  883. box: box,
  884. fitBox: true,
  885. style: assign(
  886. {},
  887. textRenderer.getExternalStyle(),
  888. {
  889. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  890. }
  891. )
  892. });
  893. }
  894. function renderLaneLabel(parentGfx, text, element, attrs = {}) {
  895. var isHorizontalLane = isHorizontal(element);
  896. var textBox = renderLabel(parentGfx, text, {
  897. box: {
  898. height: 30,
  899. width: isHorizontalLane ? getHeight(element, attrs) : getWidth(element, attrs),
  900. },
  901. align: 'center-middle',
  902. style: {
  903. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  904. }
  905. });
  906. if (isHorizontalLane) {
  907. var top = -1 * getHeight(element, attrs);
  908. transform(textBox, 0, -top, 270);
  909. }
  910. }
  911. function renderActivity(parentGfx, element, attrs = {}) {
  912. var {
  913. width,
  914. height
  915. } = getBounds(element, attrs);
  916. return drawRect(parentGfx, width, height, TASK_BORDER_RADIUS, {
  917. ...attrs,
  918. fill: getFillColor(element, defaultFillColor, attrs.fill),
  919. fillOpacity: DEFAULT_OPACITY,
  920. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  921. });
  922. }
  923. function renderAssociation(parentGfx, element, attrs = {}) {
  924. var semantic = getSemantic(element);
  925. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  926. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  927. if (semantic.get('associationDirection') === 'One' ||
  928. semantic.get('associationDirection') === 'Both') {
  929. attrs.markerEnd = marker('association-end', fill, stroke);
  930. }
  931. if (semantic.get('associationDirection') === 'Both') {
  932. attrs.markerStart = marker('association-start', fill, stroke);
  933. }
  934. attrs = pickAttrs(attrs, [
  935. 'markerStart',
  936. 'markerEnd'
  937. ]);
  938. return drawConnectionSegments(parentGfx, element.waypoints, {
  939. ...attrs,
  940. stroke,
  941. strokeDasharray: '0, 5'
  942. });
  943. }
  944. function renderDataObject(parentGfx, element, attrs = {}) {
  945. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  946. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  947. var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
  948. xScaleFactor: 1,
  949. yScaleFactor: 1,
  950. containerWidth: element.width,
  951. containerHeight: element.height,
  952. position: {
  953. mx: 0.474,
  954. my: 0.296
  955. }
  956. });
  957. var dataObject = drawPath(parentGfx, pathData, {
  958. fill,
  959. fillOpacity: DEFAULT_OPACITY,
  960. stroke
  961. });
  962. var semantic = getSemantic(element);
  963. if (isCollection(semantic)) {
  964. var collectionPathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', {
  965. xScaleFactor: 1,
  966. yScaleFactor: 1,
  967. containerWidth: element.width,
  968. containerHeight: element.height,
  969. position: {
  970. mx: 0.33,
  971. my: (element.height - 18) / element.height
  972. }
  973. });
  974. drawPath(parentGfx, collectionPathData, {
  975. strokeWidth: 2,
  976. fill,
  977. stroke
  978. });
  979. }
  980. return dataObject;
  981. }
  982. function renderEvent(parentGfx, element, attrs = {}) {
  983. return drawCircle(parentGfx, element.width, element.height, {
  984. fillOpacity: DEFAULT_OPACITY,
  985. ...attrs,
  986. fill: getFillColor(element, defaultFillColor, attrs.fill),
  987. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  988. });
  989. }
  990. function renderGateway(parentGfx, element, attrs = {}) {
  991. return drawDiamond(parentGfx, element.width, element.height, {
  992. fill: getFillColor(element, defaultFillColor, attrs.fill),
  993. fillOpacity: DEFAULT_OPACITY,
  994. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  995. });
  996. }
  997. function renderLane(parentGfx, element, attrs = {}) {
  998. var lane = drawRect(parentGfx, getWidth(element, attrs), getHeight(element, attrs), 0, {
  999. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1000. fillOpacity: attrs.fillOpacity || DEFAULT_OPACITY,
  1001. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1002. strokeWidth: 1.5
  1003. });
  1004. var semantic = getSemantic(element);
  1005. if (is(semantic, 'bpmn:Lane')) {
  1006. var text = semantic.get('name');
  1007. renderLaneLabel(parentGfx, text, element, attrs);
  1008. }
  1009. return lane;
  1010. }
  1011. function renderSubProcess(parentGfx, element, attrs = {}) {
  1012. var activity = renderActivity(parentGfx, element, attrs);
  1013. if (isEventSubProcess(element)) {
  1014. svgAttr(activity, {
  1015. strokeDasharray: '0, 5.5',
  1016. strokeWidth: 2.5
  1017. });
  1018. }
  1019. var expanded = isExpanded(element);
  1020. renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle', attrs);
  1021. if (expanded) {
  1022. renderTaskMarkers(parentGfx, element, undefined, attrs);
  1023. } else {
  1024. renderTaskMarkers(parentGfx, element, [ 'SubProcessMarker' ], attrs);
  1025. }
  1026. return activity;
  1027. }
  1028. function renderTask(parentGfx, element, attrs = {}) {
  1029. var activity = renderActivity(parentGfx, element, attrs);
  1030. renderEmbeddedLabel(parentGfx, element, 'center-middle', attrs);
  1031. renderTaskMarkers(parentGfx, element, undefined, attrs);
  1032. return activity;
  1033. }
  1034. var handlers = this.handlers = {
  1035. 'bpmn:AdHocSubProcess': function(parentGfx, element, attrs = {}) {
  1036. if (isExpanded(element)) {
  1037. attrs = pickAttrs(attrs, [
  1038. 'fill',
  1039. 'stroke',
  1040. 'width',
  1041. 'height'
  1042. ]);
  1043. } else {
  1044. attrs = pickAttrs(attrs, [
  1045. 'fill',
  1046. 'stroke'
  1047. ]);
  1048. }
  1049. return renderSubProcess(parentGfx, element, attrs);
  1050. },
  1051. 'bpmn:Association': function(parentGfx, element, attrs = {}) {
  1052. attrs = pickAttrs(attrs, [
  1053. 'fill',
  1054. 'stroke'
  1055. ]);
  1056. return renderAssociation(parentGfx, element, attrs);
  1057. },
  1058. 'bpmn:BoundaryEvent': function(parentGfx, element, attrs = {}) {
  1059. var { renderIcon = true } = attrs;
  1060. attrs = pickAttrs(attrs, [
  1061. 'fill',
  1062. 'stroke'
  1063. ]);
  1064. var semantic = getSemantic(element),
  1065. cancelActivity = semantic.get('cancelActivity');
  1066. attrs = {
  1067. strokeWidth: 1.5,
  1068. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1069. fillOpacity: FULL_OPACITY,
  1070. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  1071. };
  1072. if (!cancelActivity) {
  1073. attrs.strokeDasharray = '6';
  1074. }
  1075. var event = renderEvent(parentGfx, element, attrs);
  1076. drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
  1077. ...attrs,
  1078. fill: 'none'
  1079. });
  1080. if (renderIcon) {
  1081. renderEventIcon(element, parentGfx, attrs);
  1082. }
  1083. return event;
  1084. },
  1085. 'bpmn:BusinessRuleTask': function(parentGfx, element, attrs = {}) {
  1086. attrs = pickAttrs(attrs, [
  1087. 'fill',
  1088. 'stroke'
  1089. ]);
  1090. var task = renderTask(parentGfx, element, attrs);
  1091. var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
  1092. abspos: {
  1093. x: 8,
  1094. y: 8
  1095. }
  1096. });
  1097. var businessPath = drawPath(parentGfx, headerData);
  1098. svgAttr(businessPath, {
  1099. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1100. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1101. strokeWidth: 1
  1102. });
  1103. var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
  1104. abspos: {
  1105. x: 8,
  1106. y: 8
  1107. }
  1108. });
  1109. var businessHeaderPath = drawPath(parentGfx, headerPathData);
  1110. svgAttr(businessHeaderPath, {
  1111. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1112. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1113. strokeWidth: 1
  1114. });
  1115. return task;
  1116. },
  1117. 'bpmn:CallActivity': function(parentGfx, element, attrs = {}) {
  1118. attrs = pickAttrs(attrs, [
  1119. 'fill',
  1120. 'stroke'
  1121. ]);
  1122. return renderSubProcess(parentGfx, element, {
  1123. strokeWidth: 5,
  1124. ...attrs
  1125. });
  1126. },
  1127. 'bpmn:ComplexGateway': function(parentGfx, element, attrs = {}) {
  1128. attrs = pickAttrs(attrs, [
  1129. 'fill',
  1130. 'stroke'
  1131. ]);
  1132. var gateway = renderGateway(parentGfx, element, attrs);
  1133. var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
  1134. xScaleFactor: 0.5,
  1135. yScaleFactor:0.5,
  1136. containerWidth: element.width,
  1137. containerHeight: element.height,
  1138. position: {
  1139. mx: 0.46,
  1140. my: 0.26
  1141. }
  1142. });
  1143. drawPath(parentGfx, pathData, {
  1144. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1145. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1146. strokeWidth: 1
  1147. });
  1148. return gateway;
  1149. },
  1150. 'bpmn:DataInput': function(parentGfx, element, attrs = {}) {
  1151. attrs = pickAttrs(attrs, [
  1152. 'fill',
  1153. 'stroke'
  1154. ]);
  1155. var arrowPathData = pathMap.getRawPath('DATA_ARROW');
  1156. var dataObject = renderDataObject(parentGfx, element, attrs);
  1157. drawPath(parentGfx, arrowPathData, {
  1158. fill: 'none',
  1159. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1160. strokeWidth: 1
  1161. });
  1162. return dataObject;
  1163. },
  1164. 'bpmn:DataInputAssociation': function(parentGfx, element, attrs = {}) {
  1165. attrs = pickAttrs(attrs, [
  1166. 'fill',
  1167. 'stroke'
  1168. ]);
  1169. return renderAssociation(parentGfx, element, {
  1170. ...attrs,
  1171. markerEnd: marker('association-end', getFillColor(element, defaultFillColor, attrs.fill), getStrokeColor(element, defaultStrokeColor, attrs.stroke))
  1172. });
  1173. },
  1174. 'bpmn:DataObject': function(parentGfx, element, attrs = {}) {
  1175. attrs = pickAttrs(attrs, [
  1176. 'fill',
  1177. 'stroke'
  1178. ]);
  1179. return renderDataObject(parentGfx, element, attrs);
  1180. },
  1181. 'bpmn:DataObjectReference': as('bpmn:DataObject'),
  1182. 'bpmn:DataOutput': function(parentGfx, element, attrs = {}) {
  1183. attrs = pickAttrs(attrs, [
  1184. 'fill',
  1185. 'stroke'
  1186. ]);
  1187. var arrowPathData = pathMap.getRawPath('DATA_ARROW');
  1188. var dataObject = renderDataObject(parentGfx, element, attrs);
  1189. drawPath(parentGfx, arrowPathData, {
  1190. strokeWidth: 1,
  1191. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1192. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  1193. });
  1194. return dataObject;
  1195. },
  1196. 'bpmn:DataOutputAssociation': function(parentGfx, element, attrs = {}) {
  1197. attrs = pickAttrs(attrs, [
  1198. 'fill',
  1199. 'stroke'
  1200. ]);
  1201. return renderAssociation(parentGfx, element, {
  1202. ...attrs,
  1203. markerEnd: marker('association-end', getFillColor(element, defaultFillColor, attrs.fill), getStrokeColor(element, defaultStrokeColor, attrs.stroke))
  1204. });
  1205. },
  1206. 'bpmn:DataStoreReference': function(parentGfx, element, attrs = {}) {
  1207. attrs = pickAttrs(attrs, [
  1208. 'fill',
  1209. 'stroke'
  1210. ]);
  1211. var dataStorePath = pathMap.getScaledPath('DATA_STORE', {
  1212. xScaleFactor: 1,
  1213. yScaleFactor: 1,
  1214. containerWidth: element.width,
  1215. containerHeight: element.height,
  1216. position: {
  1217. mx: 0,
  1218. my: 0.133
  1219. }
  1220. });
  1221. return drawPath(parentGfx, dataStorePath, {
  1222. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1223. fillOpacity: DEFAULT_OPACITY,
  1224. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1225. strokeWidth: 2
  1226. });
  1227. },
  1228. 'bpmn:EndEvent': function(parentGfx, element, attrs = {}) {
  1229. var { renderIcon = true } = attrs;
  1230. attrs = pickAttrs(attrs, [
  1231. 'fill',
  1232. 'stroke'
  1233. ]);
  1234. var event = renderEvent(parentGfx, element, {
  1235. ...attrs,
  1236. strokeWidth: 4
  1237. });
  1238. if (renderIcon) {
  1239. renderEventIcon(element, parentGfx, attrs);
  1240. }
  1241. return event;
  1242. },
  1243. 'bpmn:EventBasedGateway': function(parentGfx, element, attrs = {}) {
  1244. attrs = pickAttrs(attrs, [
  1245. 'fill',
  1246. 'stroke'
  1247. ]);
  1248. var semantic = getSemantic(element);
  1249. var diamond = renderGateway(parentGfx, element, attrs);
  1250. drawCircle(parentGfx, element.width, element.height, element.height * 0.20, {
  1251. fill: getFillColor(element, 'none', attrs.fill),
  1252. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1253. strokeWidth: 1
  1254. });
  1255. var type = semantic.get('eventGatewayType'),
  1256. instantiate = !!semantic.get('instantiate');
  1257. function drawEvent() {
  1258. var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', {
  1259. xScaleFactor: 0.18,
  1260. yScaleFactor: 0.18,
  1261. containerWidth: element.width,
  1262. containerHeight: element.height,
  1263. position: {
  1264. mx: 0.36,
  1265. my: 0.44
  1266. }
  1267. });
  1268. drawPath(parentGfx, pathData, {
  1269. fill: 'none',
  1270. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1271. strokeWidth: 2
  1272. });
  1273. }
  1274. if (type === 'Parallel') {
  1275. var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
  1276. xScaleFactor: 0.4,
  1277. yScaleFactor: 0.4,
  1278. containerWidth: element.width,
  1279. containerHeight: element.height,
  1280. position: {
  1281. mx: 0.474,
  1282. my: 0.296
  1283. }
  1284. });
  1285. drawPath(parentGfx, pathData, {
  1286. fill: 'none',
  1287. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1288. strokeWidth: 1
  1289. });
  1290. } else if (type === 'Exclusive') {
  1291. if (!instantiate) {
  1292. drawCircle(parentGfx, element.width, element.height, element.height * 0.26, {
  1293. fill: 'none',
  1294. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1295. strokeWidth: 1
  1296. });
  1297. }
  1298. drawEvent();
  1299. }
  1300. return diamond;
  1301. },
  1302. 'bpmn:ExclusiveGateway': function(parentGfx, element, attrs = {}) {
  1303. attrs = pickAttrs(attrs, [
  1304. 'fill',
  1305. 'stroke'
  1306. ]);
  1307. var gateway = renderGateway(parentGfx, element, attrs);
  1308. var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
  1309. xScaleFactor: 0.4,
  1310. yScaleFactor: 0.4,
  1311. containerWidth: element.width,
  1312. containerHeight: element.height,
  1313. position: {
  1314. mx: 0.32,
  1315. my: 0.3
  1316. }
  1317. });
  1318. var di = getDi(element);
  1319. if (di.get('isMarkerVisible')) {
  1320. drawPath(parentGfx, pathData, {
  1321. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1322. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1323. strokeWidth: 1
  1324. });
  1325. }
  1326. return gateway;
  1327. },
  1328. 'bpmn:Gateway': function(parentGfx, element, attrs = {}) {
  1329. attrs = pickAttrs(attrs, [
  1330. 'fill',
  1331. 'stroke'
  1332. ]);
  1333. return renderGateway(parentGfx, element, attrs);
  1334. },
  1335. 'bpmn:Group': function(parentGfx, element, attrs = {}) {
  1336. attrs = pickAttrs(attrs, [
  1337. 'fill',
  1338. 'stroke',
  1339. 'width',
  1340. 'height'
  1341. ]);
  1342. return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, {
  1343. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1344. strokeWidth: 1.5,
  1345. strokeDasharray: '10, 6, 0, 6',
  1346. fill: 'none',
  1347. pointerEvents: 'none',
  1348. width: getWidth(element, attrs),
  1349. height: getHeight(element, attrs)
  1350. });
  1351. },
  1352. 'bpmn:InclusiveGateway': function(parentGfx, element, attrs = {}) {
  1353. attrs = pickAttrs(attrs, [
  1354. 'fill',
  1355. 'stroke'
  1356. ]);
  1357. var gateway = renderGateway(parentGfx, element, attrs);
  1358. drawCircle(parentGfx, element.width, element.height, element.height * 0.24, {
  1359. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1360. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1361. strokeWidth: 2.5
  1362. });
  1363. return gateway;
  1364. },
  1365. 'bpmn:IntermediateEvent': function(parentGfx, element, attrs = {}) {
  1366. var { renderIcon = true } = attrs;
  1367. attrs = pickAttrs(attrs, [
  1368. 'fill',
  1369. 'stroke'
  1370. ]);
  1371. var outer = renderEvent(parentGfx, element, {
  1372. ...attrs,
  1373. strokeWidth: 1.5
  1374. });
  1375. drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
  1376. fill: 'none',
  1377. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1378. strokeWidth: 1.5
  1379. });
  1380. if (renderIcon) {
  1381. renderEventIcon(element, parentGfx, attrs);
  1382. }
  1383. return outer;
  1384. },
  1385. 'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'),
  1386. 'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'),
  1387. 'bpmn:Lane': function(parentGfx, element, attrs = {}) {
  1388. attrs = pickAttrs(attrs, [
  1389. 'fill',
  1390. 'stroke',
  1391. 'width',
  1392. 'height'
  1393. ]);
  1394. return renderLane(parentGfx, element, {
  1395. ...attrs,
  1396. fillOpacity: LOW_OPACITY
  1397. });
  1398. },
  1399. 'bpmn:ManualTask': function(parentGfx, element, attrs = {}) {
  1400. attrs = pickAttrs(attrs, [
  1401. 'fill',
  1402. 'stroke'
  1403. ]);
  1404. var task = renderTask(parentGfx, element, attrs);
  1405. var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
  1406. abspos: {
  1407. x: 17,
  1408. y: 15
  1409. }
  1410. });
  1411. drawPath(parentGfx, pathData, {
  1412. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1413. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1414. strokeWidth: 0.5
  1415. });
  1416. return task;
  1417. },
  1418. 'bpmn:MessageFlow': function(parentGfx, element, attrs = {}) {
  1419. attrs = pickAttrs(attrs, [
  1420. 'fill',
  1421. 'stroke'
  1422. ]);
  1423. var semantic = getSemantic(element),
  1424. di = getDi(element);
  1425. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  1426. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  1427. var path = drawConnectionSegments(parentGfx, element.waypoints, {
  1428. markerEnd: marker('messageflow-end', fill, stroke),
  1429. markerStart: marker('messageflow-start', fill, stroke),
  1430. stroke,
  1431. strokeDasharray: '10, 11',
  1432. strokeWidth: 1.5
  1433. });
  1434. if (semantic.get('messageRef')) {
  1435. var midPoint = path.getPointAtLength(path.getTotalLength() / 2);
  1436. var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', {
  1437. abspos: {
  1438. x: midPoint.x,
  1439. y: midPoint.y
  1440. }
  1441. });
  1442. var messageAttrs = {
  1443. strokeWidth: 1
  1444. };
  1445. if (di.get('messageVisibleKind') === 'initiating') {
  1446. messageAttrs.fill = fill;
  1447. messageAttrs.stroke = stroke;
  1448. } else {
  1449. messageAttrs.fill = stroke;
  1450. messageAttrs.stroke = fill;
  1451. }
  1452. var message = drawPath(parentGfx, markerPathData, messageAttrs);
  1453. var messageRef = semantic.get('messageRef'),
  1454. name = messageRef.get('name');
  1455. var label = renderLabel(parentGfx, name, {
  1456. align: 'center-top',
  1457. fitBox: true,
  1458. style: {
  1459. fill: stroke
  1460. }
  1461. });
  1462. var messageBounds = message.getBBox(),
  1463. labelBounds = label.getBBox();
  1464. var translateX = midPoint.x - labelBounds.width / 2,
  1465. translateY = midPoint.y + messageBounds.height / 2 + ELEMENT_LABEL_DISTANCE;
  1466. transform(label, translateX, translateY, 0);
  1467. }
  1468. return path;
  1469. },
  1470. 'bpmn:ParallelGateway': function(parentGfx, element, attrs = {}) {
  1471. attrs = pickAttrs(attrs, [
  1472. 'fill',
  1473. 'stroke'
  1474. ]);
  1475. var diamond = renderGateway(parentGfx, element, attrs);
  1476. var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
  1477. xScaleFactor: 0.6,
  1478. yScaleFactor: 0.6,
  1479. containerWidth: element.width,
  1480. containerHeight: element.height,
  1481. position: {
  1482. mx: 0.46,
  1483. my: 0.2
  1484. }
  1485. });
  1486. drawPath(parentGfx, pathData, {
  1487. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1488. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1489. strokeWidth: 1
  1490. });
  1491. return diamond;
  1492. },
  1493. 'bpmn:Participant': function(parentGfx, element, attrs = {}) {
  1494. attrs = pickAttrs(attrs, [
  1495. 'fill',
  1496. 'stroke',
  1497. 'width',
  1498. 'height'
  1499. ]);
  1500. var participant = renderLane(parentGfx, element, attrs);
  1501. var expandedParticipant = isExpanded(element);
  1502. var horizontalParticipant = isHorizontal(element);
  1503. var semantic = getSemantic(element),
  1504. name = semantic.get('name');
  1505. if (expandedParticipant) {
  1506. var waypoints = horizontalParticipant ? [
  1507. {
  1508. x: 30,
  1509. y: 0
  1510. },
  1511. {
  1512. x: 30,
  1513. y: getHeight(element, attrs)
  1514. }
  1515. ] : [
  1516. {
  1517. x: 0,
  1518. y: 30
  1519. },
  1520. {
  1521. x: getWidth(element, attrs),
  1522. y: 30
  1523. }
  1524. ];
  1525. drawLine(parentGfx, waypoints, {
  1526. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1527. strokeWidth: PARTICIPANT_STROKE_WIDTH
  1528. });
  1529. renderLaneLabel(parentGfx, name, element, attrs);
  1530. } else {
  1531. var bounds = getBounds(element, attrs);
  1532. if (!horizontalParticipant) {
  1533. bounds.height = getWidth(element, attrs);
  1534. bounds.width = getHeight(element, attrs);
  1535. }
  1536. var textBox = renderLabel(parentGfx, name, {
  1537. box: bounds,
  1538. align: 'center-middle',
  1539. style: {
  1540. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  1541. }
  1542. });
  1543. if (!horizontalParticipant) {
  1544. var top = -1 * getHeight(element, attrs);
  1545. transform(textBox, 0, -top, 270);
  1546. }
  1547. }
  1548. if (semantic.get('participantMultiplicity')) {
  1549. renderTaskMarker('ParticipantMultiplicityMarker', parentGfx, element, attrs);
  1550. }
  1551. return participant;
  1552. },
  1553. 'bpmn:ReceiveTask' : function(parentGfx, element, attrs = {}) {
  1554. attrs = pickAttrs(attrs, [
  1555. 'fill',
  1556. 'stroke'
  1557. ]);
  1558. var semantic = getSemantic(element);
  1559. var task = renderTask(parentGfx, element, attrs);
  1560. var pathData;
  1561. if (semantic.get('instantiate')) {
  1562. drawCircle(parentGfx, 28, 28, 20 * 0.22, {
  1563. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1564. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1565. strokeWidth: 1
  1566. });
  1567. pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
  1568. abspos: {
  1569. x: 7.77,
  1570. y: 9.52
  1571. }
  1572. });
  1573. } else {
  1574. pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
  1575. xScaleFactor: 0.9,
  1576. yScaleFactor: 0.9,
  1577. containerWidth: 21,
  1578. containerHeight: 14,
  1579. position: {
  1580. mx: 0.3,
  1581. my: 0.4
  1582. }
  1583. });
  1584. }
  1585. drawPath(parentGfx, pathData, {
  1586. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1587. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1588. strokeWidth: 1
  1589. });
  1590. return task;
  1591. },
  1592. 'bpmn:ScriptTask': function(parentGfx, element, attrs = {}) {
  1593. attrs = pickAttrs(attrs, [
  1594. 'fill',
  1595. 'stroke'
  1596. ]);
  1597. var task = renderTask(parentGfx, element, attrs);
  1598. var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
  1599. abspos: {
  1600. x: 15,
  1601. y: 20
  1602. }
  1603. });
  1604. drawPath(parentGfx, pathData, {
  1605. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1606. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1607. strokeWidth: 1
  1608. });
  1609. return task;
  1610. },
  1611. 'bpmn:SendTask': function(parentGfx, element, attrs = {}) {
  1612. attrs = pickAttrs(attrs, [
  1613. 'fill',
  1614. 'stroke'
  1615. ]);
  1616. var task = renderTask(parentGfx, element, attrs);
  1617. var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
  1618. xScaleFactor: 1,
  1619. yScaleFactor: 1,
  1620. containerWidth: 21,
  1621. containerHeight: 14,
  1622. position: {
  1623. mx: 0.285,
  1624. my: 0.357
  1625. }
  1626. });
  1627. drawPath(parentGfx, pathData, {
  1628. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1629. stroke: getFillColor(element, defaultFillColor, attrs.fill),
  1630. strokeWidth: 1
  1631. });
  1632. return task;
  1633. },
  1634. 'bpmn:SequenceFlow': function(parentGfx, element, attrs = {}) {
  1635. attrs = pickAttrs(attrs, [
  1636. 'fill',
  1637. 'stroke'
  1638. ]);
  1639. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  1640. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  1641. var connection = drawConnectionSegments(parentGfx, element.waypoints, {
  1642. markerEnd: marker('sequenceflow-end', fill, stroke),
  1643. stroke
  1644. });
  1645. var semantic = getSemantic(element);
  1646. var { source } = element;
  1647. if (source) {
  1648. var sourceSemantic = getSemantic(source);
  1649. // conditional flow marker
  1650. if (semantic.get('conditionExpression') && is(sourceSemantic, 'bpmn:Activity')) {
  1651. svgAttr(connection, {
  1652. markerStart: marker('conditional-flow-marker', fill, stroke)
  1653. });
  1654. }
  1655. // default marker
  1656. if (sourceSemantic.get('default') && (is(sourceSemantic, 'bpmn:Gateway') || is(sourceSemantic, 'bpmn:Activity')) &&
  1657. sourceSemantic.get('default') === semantic) {
  1658. svgAttr(connection, {
  1659. markerStart: marker('conditional-default-flow-marker', fill, stroke)
  1660. });
  1661. }
  1662. }
  1663. return connection;
  1664. },
  1665. 'bpmn:ServiceTask': function(parentGfx, element, attrs = {}) {
  1666. attrs = pickAttrs(attrs, [
  1667. 'fill',
  1668. 'stroke'
  1669. ]);
  1670. var task = renderTask(parentGfx, element, attrs);
  1671. drawCircle(parentGfx, 10, 10, {
  1672. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1673. stroke: 'none',
  1674. transform: 'translate(6, 6)'
  1675. });
  1676. var pathDataService1 = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
  1677. abspos: {
  1678. x: 12,
  1679. y: 18
  1680. }
  1681. });
  1682. drawPath(parentGfx, pathDataService1, {
  1683. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1684. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1685. strokeWidth: 1
  1686. });
  1687. drawCircle(parentGfx, 10, 10, {
  1688. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1689. stroke: 'none',
  1690. transform: 'translate(11, 10)'
  1691. });
  1692. var pathDataService2 = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
  1693. abspos: {
  1694. x: 17,
  1695. y: 22
  1696. }
  1697. });
  1698. drawPath(parentGfx, pathDataService2, {
  1699. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1700. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1701. strokeWidth: 1
  1702. });
  1703. return task;
  1704. },
  1705. 'bpmn:StartEvent': function(parentGfx, element, attrs = {}) {
  1706. var { renderIcon = true } = attrs;
  1707. attrs = pickAttrs(attrs, [
  1708. 'fill',
  1709. 'stroke'
  1710. ]);
  1711. var semantic = getSemantic(element);
  1712. if (!semantic.get('isInterrupting')) {
  1713. attrs = {
  1714. ...attrs,
  1715. strokeDasharray: '6'
  1716. };
  1717. }
  1718. var event = renderEvent(parentGfx, element, attrs);
  1719. if (renderIcon) {
  1720. renderEventIcon(element, parentGfx, attrs);
  1721. }
  1722. return event;
  1723. },
  1724. 'bpmn:SubProcess': function(parentGfx, element, attrs = {}) {
  1725. if (isExpanded(element)) {
  1726. attrs = pickAttrs(attrs, [
  1727. 'fill',
  1728. 'stroke',
  1729. 'width',
  1730. 'height'
  1731. ]);
  1732. } else {
  1733. attrs = pickAttrs(attrs, [
  1734. 'fill',
  1735. 'stroke'
  1736. ]);
  1737. }
  1738. return renderSubProcess(parentGfx, element, attrs);
  1739. },
  1740. 'bpmn:Task': function(parentGfx, element, attrs = {}) {
  1741. attrs = pickAttrs(attrs, [
  1742. 'fill',
  1743. 'stroke'
  1744. ]);
  1745. return renderTask(parentGfx, element, attrs);
  1746. },
  1747. 'bpmn:TextAnnotation': function(parentGfx, element, attrs = {}) {
  1748. attrs = pickAttrs(attrs, [
  1749. 'fill',
  1750. 'stroke',
  1751. 'width',
  1752. 'height'
  1753. ]);
  1754. var {
  1755. width,
  1756. height
  1757. } = getBounds(element, attrs);
  1758. var textElement = drawRect(parentGfx, width, height, 0, 0, {
  1759. fill: 'none',
  1760. stroke: 'none'
  1761. });
  1762. var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
  1763. xScaleFactor: 1,
  1764. yScaleFactor: 1,
  1765. containerWidth: width,
  1766. containerHeight: height,
  1767. position: {
  1768. mx: 0.0,
  1769. my: 0.0
  1770. }
  1771. });
  1772. drawPath(parentGfx, textPathData, {
  1773. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  1774. });
  1775. var semantic = getSemantic(element),
  1776. text = semantic.get('text') || '';
  1777. renderLabel(parentGfx, text, {
  1778. align: 'left-top',
  1779. box: getBounds(element, attrs),
  1780. padding: 7,
  1781. style: {
  1782. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  1783. }
  1784. });
  1785. return textElement;
  1786. },
  1787. 'bpmn:Transaction': function(parentGfx, element, attrs = {}) {
  1788. if (isExpanded(element)) {
  1789. attrs = pickAttrs(attrs, [
  1790. 'fill',
  1791. 'stroke',
  1792. 'width',
  1793. 'height'
  1794. ]);
  1795. } else {
  1796. attrs = pickAttrs(attrs, [
  1797. 'fill',
  1798. 'stroke'
  1799. ]);
  1800. }
  1801. var outer = renderSubProcess(parentGfx, element, {
  1802. strokeWidth: 1.5,
  1803. ...attrs
  1804. });
  1805. var innerAttrs = styles.style([ 'no-fill', 'no-events' ], {
  1806. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1807. strokeWidth: 1.5
  1808. });
  1809. var expanded = isExpanded(element);
  1810. if (!expanded) {
  1811. attrs = {};
  1812. }
  1813. drawRect(
  1814. parentGfx,
  1815. getWidth(element, attrs),
  1816. getHeight(element, attrs),
  1817. TASK_BORDER_RADIUS - INNER_OUTER_DIST,
  1818. INNER_OUTER_DIST,
  1819. innerAttrs
  1820. );
  1821. return outer;
  1822. },
  1823. 'bpmn:UserTask': function(parentGfx, element, attrs = {}) {
  1824. attrs = pickAttrs(attrs, [
  1825. 'fill',
  1826. 'stroke'
  1827. ]);
  1828. var task = renderTask(parentGfx, element, attrs);
  1829. var x = 15;
  1830. var y = 12;
  1831. var pathDataUser1 = pathMap.getScaledPath('TASK_TYPE_USER_1', {
  1832. abspos: {
  1833. x: x,
  1834. y: y
  1835. }
  1836. });
  1837. drawPath(parentGfx, pathDataUser1, {
  1838. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1839. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1840. strokeWidth: 0.5
  1841. });
  1842. var pathDataUser2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
  1843. abspos: {
  1844. x: x,
  1845. y: y
  1846. }
  1847. });
  1848. drawPath(parentGfx, pathDataUser2, {
  1849. fill: getFillColor(element, defaultFillColor, attrs.fill),
  1850. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1851. strokeWidth: 0.5
  1852. });
  1853. var pathDataUser3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
  1854. abspos: {
  1855. x: x,
  1856. y: y
  1857. }
  1858. });
  1859. drawPath(parentGfx, pathDataUser3, {
  1860. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1861. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  1862. strokeWidth: 0.5
  1863. });
  1864. return task;
  1865. },
  1866. 'label': function(parentGfx, element, attrs = {}) {
  1867. return renderExternalLabel(parentGfx, element, attrs);
  1868. }
  1869. };
  1870. // extension API, use at your own risk
  1871. this._drawPath = drawPath;
  1872. this._renderer = renderer;
  1873. }
  1874. inherits(BpmnRenderer, BaseRenderer);
  1875. BpmnRenderer.$inject = [
  1876. 'config.bpmnRenderer',
  1877. 'eventBus',
  1878. 'styles',
  1879. 'pathMap',
  1880. 'canvas',
  1881. 'textRenderer'
  1882. ];
  1883. /**
  1884. * @param {Element} element
  1885. *
  1886. * @return {boolean}
  1887. */
  1888. BpmnRenderer.prototype.canRender = function(element) {
  1889. return is(element, 'bpmn:BaseElement');
  1890. };
  1891. /**
  1892. * Draw shape into parentGfx.
  1893. *
  1894. * @param {SVGElement} parentGfx
  1895. * @param {Element} element
  1896. * @param {Attrs} [attrs]
  1897. *
  1898. * @return {SVGElement} mainGfx
  1899. */
  1900. BpmnRenderer.prototype.drawShape = function(parentGfx, element, attrs = {}) {
  1901. var { type } = element;
  1902. var handler = this._renderer(type);
  1903. return handler(parentGfx, element, attrs);
  1904. };
  1905. /**
  1906. * Draw connection into parentGfx.
  1907. *
  1908. * @param {SVGElement} parentGfx
  1909. * @param {Element} element
  1910. * @param {Attrs} [attrs]
  1911. *
  1912. * @return {SVGElement} mainGfx
  1913. */
  1914. BpmnRenderer.prototype.drawConnection = function(parentGfx, element, attrs = {}) {
  1915. var { type } = element;
  1916. var handler = this._renderer(type);
  1917. return handler(parentGfx, element, attrs);
  1918. };
  1919. /**
  1920. * Get shape path.
  1921. *
  1922. * @param {Element} element
  1923. *
  1924. * @return {string} path
  1925. */
  1926. BpmnRenderer.prototype.getShapePath = function(element) {
  1927. if (is(element, 'bpmn:Event')) {
  1928. return getCirclePath(element);
  1929. }
  1930. if (is(element, 'bpmn:Activity')) {
  1931. return getRoundRectPath(element, TASK_BORDER_RADIUS);
  1932. }
  1933. if (is(element, 'bpmn:Gateway')) {
  1934. return getDiamondPath(element);
  1935. }
  1936. return getRectPath(element);
  1937. };
  1938. /**
  1939. * Pick attributes if they exist.
  1940. *
  1941. * @param {Object} attrs
  1942. * @param {string[]} keys
  1943. *
  1944. * @returns {Object}
  1945. */
  1946. function pickAttrs(attrs, keys = []) {
  1947. return keys.reduce((pickedAttrs, key) => {
  1948. if (attrs[ key ]) {
  1949. pickedAttrs[ key ] = attrs[ key ];
  1950. }
  1951. return pickedAttrs;
  1952. }, {});
  1953. }