Skip to content

Commit cfec0a9

Browse files
sombrekbarmac
authored andcommitted
feat: render event subprocess icons
Closes #50
1 parent f8398cc commit cfec0a9

File tree

3 files changed

+1057
-41
lines changed

3 files changed

+1057
-41
lines changed

lib/draw/BpmnRenderer.js

Lines changed: 92 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,8 @@ export default function BpmnRenderer(
462462
var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
463463
xScaleFactor: 0.9,
464464
yScaleFactor: 0.9,
465-
containerWidth: element.width,
466-
containerHeight: element.height,
465+
containerWidth: attrs.width || element.width,
466+
containerHeight: attrs.height || element.height,
467467
position: {
468468
mx: 0.235,
469469
my: 0.315
@@ -487,17 +487,23 @@ export default function BpmnRenderer(
487487
return messagePath;
488488
},
489489
'bpmn:TimerEventDefinition': function(parentGfx, element, attrs = {}) {
490-
var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, {
490+
var baseWidth = attrs.width || element.width;
491+
var baseHeight = attrs.height || element.height;
492+
493+
// use a lighter stroke for event suprocess icons
494+
var strokeWidth = attrs.width ? 1 : 2;
495+
496+
var circle = drawCircle(parentGfx, baseWidth, baseHeight, 0.2 * baseHeight, {
491497
fill: getFillColor(element, defaultFillColor, attrs.fill),
492498
stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
493-
strokeWidth: 2
499+
strokeWidth: strokeWidth
494500
});
495501

496502
var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
497503
xScaleFactor: 0.75,
498504
yScaleFactor: 0.75,
499-
containerWidth: element.width,
500-
containerHeight: element.height,
505+
containerWidth: baseWidth,
506+
containerHeight: baseHeight,
501507
position: {
502508
mx: 0.5,
503509
my: 0.5
@@ -506,23 +512,23 @@ export default function BpmnRenderer(
506512

507513
drawPath(parentGfx, pathData, {
508514
stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
509-
strokeWidth: 2
515+
strokeWidth: strokeWidth
510516
});
511517

512518
for (var i = 0; i < 12; i++) {
513519
var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
514520
xScaleFactor: 0.75,
515521
yScaleFactor: 0.75,
516-
containerWidth: element.width,
517-
containerHeight: element.height,
522+
containerWidth: baseWidth,
523+
containerHeight: baseHeight,
518524
position: {
519525
mx: 0.5,
520526
my: 0.5
521527
}
522528
});
523529

524-
var width = element.width / 2,
525-
height = element.height / 2;
530+
var width = baseWidth / 2,
531+
height = baseHeight / 2;
526532

527533
drawPath(parentGfx, linePathData, {
528534
strokeWidth: 1,
@@ -537,8 +543,8 @@ export default function BpmnRenderer(
537543
var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
538544
xScaleFactor: 1,
539545
yScaleFactor: 1,
540-
containerWidth: event.width,
541-
containerHeight: event.height,
546+
containerWidth: attrs.width || event.width,
547+
containerHeight: attrs.height || event.height,
542548
position: {
543549
mx: 0.5,
544550
my: 0.2
@@ -559,8 +565,8 @@ export default function BpmnRenderer(
559565
var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
560566
xScaleFactor: 1,
561567
yScaleFactor: 1,
562-
containerWidth: event.width,
563-
containerHeight: event.height,
568+
containerWidth: attrs.width || event.width,
569+
containerHeight: attrs.height || event.height,
564570
position: {
565571
mx: 0.5,
566572
my: 0.222
@@ -599,8 +605,8 @@ export default function BpmnRenderer(
599605
var pathData = pathMap.getScaledPath('EVENT_ERROR', {
600606
xScaleFactor: 1.1,
601607
yScaleFactor: 1.1,
602-
containerWidth: event.width,
603-
containerHeight: event.height,
608+
containerWidth: attrs.width || event.width,
609+
containerHeight: attrs.height || event.height,
604610
position: {
605611
mx: 0.2,
606612
my: 0.722
@@ -645,8 +651,8 @@ export default function BpmnRenderer(
645651
var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
646652
xScaleFactor: 1,
647653
yScaleFactor: 1,
648-
containerWidth: event.width,
649-
containerHeight: event.height,
654+
containerWidth: attrs.width || event.width,
655+
containerHeight: attrs.height || event.height,
650656
position: {
651657
mx: 0.22,
652658
my: 0.5
@@ -667,8 +673,8 @@ export default function BpmnRenderer(
667673
var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
668674
xScaleFactor: 0.9,
669675
yScaleFactor: 0.9,
670-
containerWidth: event.width,
671-
containerHeight: event.height,
676+
containerWidth: attrs.width || event.width,
677+
containerHeight: attrs.height || event.height,
672678
position: {
673679
mx: 0.5,
674680
my: 0.2
@@ -689,10 +695,10 @@ export default function BpmnRenderer(
689695
var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
690696
xScaleFactor: 1.1,
691697
yScaleFactor: 1.1,
692-
containerWidth: event.width,
693-
containerHeight: event.height,
698+
containerWidth: attrs.width || event.width,
699+
containerHeight: attrs.height || event.height,
694700
position: {
695-
mx: 0.222,
701+
mx: 0.211,
696702
my: 0.36
697703
}
698704
});
@@ -703,15 +709,16 @@ export default function BpmnRenderer(
703709

704710
return drawPath(parentGfx, pathData, {
705711
fill,
712+
stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
706713
strokeWidth: 1
707714
});
708715
},
709716
'bpmn:ParallelMultipleEventDefinition': function(parentGfx, event, attrs = {}) {
710717
var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
711718
xScaleFactor: 1.2,
712719
yScaleFactor: 1.2,
713-
containerWidth: event.width,
714-
containerHeight: event.height,
720+
containerWidth: attrs.width || event.width,
721+
containerHeight: attrs.height || event.height,
715722
position: {
716723
mx: 0.458,
717724
my: 0.194
@@ -735,57 +742,59 @@ export default function BpmnRenderer(
735742
}
736743
};
737744

738-
function renderEventIcon(element, parentGfx, attrs = {}) {
745+
function renderEventIcon(element, parentGfx, attrs = {}, proxyElement) {
739746
var semantic = getSemantic(element),
740747
isThrowing = isThrowEvent(semantic);
741748

749+
var nodeElement = proxyElement || element;
750+
742751
if (semantic.get('eventDefinitions') && semantic.get('eventDefinitions').length > 1) {
743752
if (semantic.get('parallelMultiple')) {
744-
return eventIconRenderers[ 'bpmn:ParallelMultipleEventDefinition' ](parentGfx, element, attrs, isThrowing);
753+
return eventIconRenderers[ 'bpmn:ParallelMultipleEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
745754
}
746755
else {
747-
return eventIconRenderers[ 'bpmn:MultipleEventDefinition' ](parentGfx, element, attrs, isThrowing);
756+
return eventIconRenderers[ 'bpmn:MultipleEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
748757
}
749758
}
750759

751760
if (isTypedEvent(semantic, 'bpmn:MessageEventDefinition')) {
752-
return eventIconRenderers[ 'bpmn:MessageEventDefinition' ](parentGfx, element, attrs, isThrowing);
761+
return eventIconRenderers[ 'bpmn:MessageEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
753762
}
754763

755764
if (isTypedEvent(semantic, 'bpmn:TimerEventDefinition')) {
756-
return eventIconRenderers[ 'bpmn:TimerEventDefinition' ](parentGfx, element, attrs, isThrowing);
765+
return eventIconRenderers[ 'bpmn:TimerEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
757766
}
758767

759768
if (isTypedEvent(semantic, 'bpmn:ConditionalEventDefinition')) {
760-
return eventIconRenderers[ 'bpmn:ConditionalEventDefinition' ](parentGfx, element, attrs, isThrowing);
769+
return eventIconRenderers[ 'bpmn:ConditionalEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
761770
}
762771

763772
if (isTypedEvent(semantic, 'bpmn:SignalEventDefinition')) {
764-
return eventIconRenderers[ 'bpmn:SignalEventDefinition' ](parentGfx, element, attrs, isThrowing);
773+
return eventIconRenderers[ 'bpmn:SignalEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
765774
}
766775

767776
if (isTypedEvent(semantic, 'bpmn:EscalationEventDefinition')) {
768-
return eventIconRenderers[ 'bpmn:EscalationEventDefinition' ](parentGfx, element, attrs, isThrowing);
777+
return eventIconRenderers[ 'bpmn:EscalationEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
769778
}
770779

771780
if (isTypedEvent(semantic, 'bpmn:LinkEventDefinition')) {
772-
return eventIconRenderers[ 'bpmn:LinkEventDefinition' ](parentGfx, element, attrs, isThrowing);
781+
return eventIconRenderers[ 'bpmn:LinkEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
773782
}
774783

775784
if (isTypedEvent(semantic, 'bpmn:ErrorEventDefinition')) {
776-
return eventIconRenderers[ 'bpmn:ErrorEventDefinition' ](parentGfx, element, attrs, isThrowing);
785+
return eventIconRenderers[ 'bpmn:ErrorEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
777786
}
778787

779788
if (isTypedEvent(semantic, 'bpmn:CancelEventDefinition')) {
780-
return eventIconRenderers[ 'bpmn:CancelEventDefinition' ](parentGfx, element, attrs, isThrowing);
789+
return eventIconRenderers[ 'bpmn:CancelEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
781790
}
782791

783792
if (isTypedEvent(semantic, 'bpmn:CompensateEventDefinition')) {
784-
return eventIconRenderers[ 'bpmn:CompensateEventDefinition' ](parentGfx, element, attrs, isThrowing);
793+
return eventIconRenderers[ 'bpmn:CompensateEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
785794
}
786795

787796
if (isTypedEvent(semantic, 'bpmn:TerminateEventDefinition')) {
788-
return eventIconRenderers[ 'bpmn:TerminateEventDefinition' ](parentGfx, element, attrs, isThrowing);
797+
return eventIconRenderers[ 'bpmn:TerminateEventDefinition' ](parentGfx, nodeElement, attrs, isThrowing);
789798
}
790799

791800
return null;
@@ -1207,14 +1216,23 @@ export default function BpmnRenderer(
12071216
function renderSubProcess(parentGfx, element, attrs = {}) {
12081217
var activity = renderActivity(parentGfx, element, attrs);
12091218

1219+
var expanded = isExpanded(element);
1220+
12101221
if (isEventSubProcess(element)) {
12111222
svgAttr(activity, {
12121223
strokeDasharray: '0, 5.5',
12131224
strokeWidth: 2.5
12141225
});
1215-
}
12161226

1217-
var expanded = isExpanded(element);
1227+
if (!expanded) {
1228+
var flowElements = getSemantic(element).flowElements || [];
1229+
var startEvents = flowElements.filter(e => is(e, 'bpmn:StartEvent'));
1230+
1231+
if (startEvents.length === 1) {
1232+
renderEventSubProcessIcon(startEvents[0], parentGfx, attrs, element);
1233+
}
1234+
}
1235+
}
12181236

12191237
renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle', attrs);
12201238

@@ -1227,6 +1245,39 @@ export default function BpmnRenderer(
12271245
return activity;
12281246
}
12291247

1248+
function renderEventSubProcessIcon(startEvent, parentGfx, attrs, proxyElement) {
1249+
var iconSize = 22;
1250+
1251+
// match the colors of the enclosing subprocess
1252+
var proxyAttrs = {
1253+
fill: getFillColor(proxyElement, defaultFillColor, attrs.fill),
1254+
stroke: getStrokeColor(proxyElement, defaultStrokeColor, attrs.stroke),
1255+
width: iconSize,
1256+
height: iconSize
1257+
};
1258+
1259+
var interrupting = getSemantic(startEvent).isInterrupting;
1260+
var strokeDasharray = interrupting ? 0 : 3;
1261+
1262+
// better visibility for non-interrupting events
1263+
var strokeWidth = interrupting ? 1 : 1.2;
1264+
1265+
// make the icon look larger by drawing a smaller circle
1266+
var circleSize = 20;
1267+
var shift = (iconSize - circleSize) / 2;
1268+
var transform = 'translate(' + shift + ',' + shift + ')';
1269+
1270+
drawCircle(parentGfx, circleSize, circleSize, {
1271+
fill: proxyAttrs.fill,
1272+
stroke: proxyAttrs.stroke,
1273+
strokeWidth,
1274+
strokeDasharray,
1275+
transform
1276+
});
1277+
1278+
renderEventIcon(startEvent, parentGfx, proxyAttrs, proxyElement);
1279+
}
1280+
12301281
function renderTask(parentGfx, element, attrs = {}) {
12311282
var activity = renderActivity(parentGfx, element, attrs);
12321283

0 commit comments

Comments
 (0)