Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] Render Lane (with SubLanes) #561

Merged
merged 13 commits into from
Sep 1, 2020
4 changes: 2 additions & 2 deletions docs/bpmn-support.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ The default rendering uses `white` as fill color and `black` as stroke color.
|Comments

|Lane
|icon:flask[]
|
|icon:check-circle-o[]
|Sub lanes are also supported

|Pool
|icon:check-circle-o[]
Expand Down
2 changes: 2 additions & 0 deletions src/component/mxgraph/StyleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export enum StyleDefault {
SHAPE_ACTIVITY_FROM_CENTER_MARGIN = 7,
SHAPE_ACTIVITY_MARKER_ICON_MARGIN = 5,
SHAPE_ACTIVITY_MARKER_ICON_SIZE = 20, //TODO: this may be adjusted once #465 will be implemented see @https://github.com/process-analytics/bpmn-visualization-js/issues/465
POOL_LABEL_SIZE = 30,
LANE_LABEL_SIZE = 30,
DEFAULT_FILL_COLOR = 'White',
DEFAULT_STROKE_COLOR = 'Black',
DEFAULT_FONT_FAMILY = 'Arial, Helvetica, sans-serif', // define our own to not depend on eventual mxGraph default change
Expand Down
6 changes: 5 additions & 1 deletion src/component/mxgraph/config/StyleConfigurator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export default class StyleConfigurator {

// TODO manage pool text area rendering. Maybe we can calculate it from the label size/bounds
// most of BPMN pool are ok when setting it to 30
style[mxConstants.STYLE_STARTSIZE] = 30;
style[mxConstants.STYLE_STARTSIZE] = StyleDefault.POOL_LABEL_SIZE;

this.graph.getStylesheet().putCellStyle(ShapeBpmnElementKind.POOL, style);
}
Expand All @@ -179,6 +179,10 @@ export default class StyleConfigurator {
style[mxConstants.STYLE_HORIZONTAL] = false;
style[mxConstants.STYLE_SWIMLANE_LINE] = 0; // hide the line between the title region and the content area

// TODO manage lane text area rendering. there is no Label neither the size available (we have only attribute name="Text of the Label")
// perhaps it can be calculated as a difference of starting point (either x or y) between pool, lane, sub-lane ?
style[mxConstants.STYLE_STARTSIZE] = StyleDefault.LANE_LABEL_SIZE;

this.graph.getStylesheet().putCellStyle(ShapeBpmnElementKind.LANE, style);
}

Expand Down
3 changes: 3 additions & 0 deletions src/component/parser/json/converter/ProcessConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ export default class ProcessConverter {
const laneShape = new ShapeBpmnElement(lane.id, lane.name, ShapeBpmnElementKind.LANE, processId);
convertedLaneBpmnElements.set(lane.id, laneShape);
this.assignParentOfLaneFlowNodes(lane);
if (lane.childLaneSet?.lane) {
this.buildLaneBpmnElements(lane.id, lane.childLaneSet.lane);
}
});
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 8 additions & 8 deletions test/e2e/bpmn.rendering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,25 @@ describe('no visual regression', () => {
windows: 0.007,
},
],
// ubuntu: 1 character change: 0.09905211491884058%%
// macOS: ok with 0.0009 threshold
// ubuntu: Expected image to match or be a close match to snapshot but was 0.19665548561466073%
// macOS: Expected image to match or be a close match to snapshot but was 0.15006201878846603%
// windows: Expected image to match or be a close match to snapshot but was 0.12200021675353723%
[
'pools.01.labels-and-lanes',
{
linux: 0.0009,
macos: 0.0009,
linux: 0.002,
macos: 0.0016,
windows: 0.002,
},
],
// ubuntu: 1 character change: 0.015598049599618857%
// macOS: Expected image to match or be a close match to snapshot but was 0.06612609365773682%
// ubuntu: Expected image to match or be a close match to snapshot but was 0.13132100299135807%
// macOS: Expected image to match or be a close match to snapshot but was 0.14776609441433664%
// windows: Expected image to match or be a close match to snapshot but was 0.1182792778311903%
[
'pools.02.vertical',
{
linux: 0.0001,
macos: 0.0007,
linux: 0.0014,
macos: 0.0015,
windows: 0.002,
},
],
Expand Down
10 changes: 10 additions & 0 deletions test/e2e/mxGraph.model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ describe('mxGraph model', () => {
expectModelContainsShape(cellId, { ...modelElement, kind: ShapeBpmnElementKind.POOL, styleShape: mxConstants.SHAPE_SWIMLANE });
}

function expectModelContainsLane(cellId: string, modelElement: ExpectedShapeModelElement): void {
expectModelContainsShape(cellId, { ...modelElement, kind: ShapeBpmnElementKind.LANE, styleShape: mxConstants.SHAPE_SWIMLANE });
}

it('bpmn elements should be available in the mxGraph model', async () => {
// load BPMN
bpmnVisualization.load(readFileSync('../fixtures/bpmn/model-complete-semantic.bpmn'));
Expand All @@ -228,6 +232,12 @@ describe('mxGraph model', () => {
expectModelContainsPool('participant_1_id', { ...minimalPoolModelElement, label: 'Pool 1' });
expectModelContainsPool('participant_2_id', minimalPoolModelElement);
expectModelContainsPool('participant_3_id', { ...minimalPoolModelElement, label: 'Black Box Process' });
expectModelContainsPool('participant_4_id', { ...minimalPoolModelElement, label: 'Pool containing sublanes' });

// lane
expectModelContainsLane('Lane_1jf55v8', { ...minimalPoolModelElement, label: 'Lane with child lanes' });
expectModelContainsLane('Lane_08b5s6x', { ...minimalPoolModelElement, label: 'Child Lane 1' });
expectModelContainsLane('Lane_1vk6vro', { ...minimalPoolModelElement, label: 'Child lane 2' });

// start event
expectModelContainsBpmnEvent('startEvent_1', { kind: ShapeBpmnElementKind.EVENT_START, eventKind: ShapeBpmnEventKind.NONE, font: expectedBoldFont, label: 'Start Event' });
Expand Down
30 changes: 30 additions & 0 deletions test/fixtures/bpmn/model-complete-semantic.bpmn
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<semantic:participant id="participant_1_id" name="Pool 1" processRef="WFP-6-" />
<semantic:participant id="participant_2_id" processRef="process_2" />
<semantic:participant id="participant_3_id" name="Black Box Process" />
<semantic:participant id="participant_4_id" name="Pool containing sublanes" processRef="process_4" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ sill missing tests for the JSon parser about the sublanes, the test here is to ensure the global parsing and the mxgraph model filling is done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, tests added in 422bfae


<!-- Message Flow -->
<semantic:messageFlow id="message_flow_initiating_message_id" name="Message Flow with initiating message" sourceRef="startEvent_3_message" targetRef="startEvent_2_1_message" messageRef="Message_1" />
Expand Down Expand Up @@ -369,6 +370,17 @@
</semantic:sequenceFlow>
<semantic:association id="association_id_1" associationDirection="None" sourceRef="task_with_flows" targetRef="text_annotation_id_1" />
</semantic:process>
<semantic:process id="process_4">
<semantic:laneSet id="LaneSet_0csasie">
<semantic:lane id="Lane_1jf55v8" name="Lane with child lanes">
<semantic:childLaneSet id="LaneSet_0yqmlme">
<semantic:lane id="Lane_1vk6vro" name="Child lane 2" />
<semantic:lane id="Lane_08b5s6x" name="Child Lane 1" />
</semantic:childLaneSet>
</semantic:lane>
<semantic:lane id="Lane_0hb85yg" name="Solo Lane" />
</semantic:laneSet>
</semantic:process>
<bpmndi:BPMNDiagram id="Trisotech_Visio-_6" name="A.1.0" documentation="" resolution="96.00000267028808">
<bpmndi:BPMNPlane bpmnElement="Collaboration_0isd296">
<!-- 1rst Process -->
Expand Down Expand Up @@ -1031,6 +1043,24 @@
<bpmndi:BPMNShape id="shape_participant_3_id" bpmnElement="participant_3_id" isHorizontal="true">
<dc:Bounds x="1750" y="80" width="600" height="170" />
</bpmndi:BPMNShape>

<!-- 4th process -->
<bpmndi:BPMNShape id="participant_4_id_di" bpmnElement="participant_4_id" isHorizontal="true">
<dc:Bounds x="800" y="80" width="600" height="250" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_1jf55v8_di" bpmnElement="Lane_1jf55v8" isHorizontal="true">
<dc:Bounds x="830" y="80" width="570" height="170" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_1vk6vro_di" bpmnElement="Lane_1vk6vro" isHorizontal="true">
<dc:Bounds x="860" y="80" width="540" height="90" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_08b5s6x_di" bpmnElement="Lane_08b5s6x" isHorizontal="true">
<dc:Bounds x="860" y="170" width="540" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_0hb85yg_di" bpmnElement="Lane_0hb85yg" isHorizontal="true">
<dc:Bounds x="830" y="250" width="570" height="80" />
</bpmndi:BPMNShape>

</bpmndi:BPMNPlane>

<!-- BPMN Label Styles -->
Expand Down
17 changes: 16 additions & 1 deletion test/fixtures/bpmn/non-regression/pools.01.labels-and-lanes.bpmn
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
<bpmn:lane id="Lane_0h8gy68">
<bpmn:flowNodeRef>Event_09mg2e0</bpmn:flowNodeRef>
</bpmn:lane>
<bpmn:lane id="Lane_1bjvm3u" name="Lane with children">
<bpmn:childLaneSet id="LaneSet_1wbqn51">
<bpmn:lane id="Lane_187zf6v" />
<bpmn:lane id="Lane_1ymcyzv" name="Child Lane" />
</bpmn:childLaneSet>
</bpmn:lane>
</bpmn:laneSet>
<bpmn:task id="Activity_12gni3i">
<bpmn:incoming>Flow_0d7g7xq</bpmn:incoming>
Expand All @@ -31,7 +37,7 @@
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_01pfi2w">
<bpmndi:BPMNShape id="Participant_1gtbp0n_di" bpmnElement="Participant_1gtbp0n" isHorizontal="true">
<dc:Bounds x="156" y="40" width="600" height="290" />
<dc:Bounds x="156" y="40" width="600" height="430" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_0h8gy68_di" bpmnElement="Lane_0h8gy68" isHorizontal="true">
<dc:Bounds x="186" y="250" width="570" height="80" />
Expand All @@ -42,6 +48,15 @@
<bpmndi:BPMNShape id="Lane_169i5ra_di" bpmnElement="Lane_169i5ra" isHorizontal="true">
<dc:Bounds x="186" y="40" width="570" height="83" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_1bjvm3u_di" bpmnElement="Lane_1bjvm3u" isHorizontal="true">
<dc:Bounds x="186" y="330" width="570" height="140" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_187zf6v_di" bpmnElement="Lane_187zf6v" isHorizontal="true">
<dc:Bounds x="216" y="330" width="540" height="60" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Lane_1ymcyzv_di" bpmnElement="Lane_1ymcyzv" isHorizontal="true">
<dc:Bounds x="216" y="390" width="540" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1os3eew_di" bpmnElement="Flow_1os3eew">
<di:waypoint x="460" y="180" />
<di:waypoint x="510" y="180" />
Expand Down
151 changes: 150 additions & 1 deletion test/unit/component/parser/json/BpmnJsonParser.lane.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ describe('parse bpmn as json for lane', () => {
expect(model.flowNodes[0].bpmnElement.parentId).toEqual('Lane_12u5n6x');
});

it('json containing one process declared as array with a laneset', () => {
it('json containing one process declared as array with a laneSet', () => {
const json = {
definitions: {
targetNamespace: '',
Expand Down Expand Up @@ -329,4 +329,153 @@ describe('parse bpmn as json for lane', () => {
},
});
});

it('json containing one process declared as array with a laneSet with childLaneSet', () => {
const json = {
definitions: {
targetNamespace: '',
process: [
{
id: 'Process_07bsa3h',
laneSet: {
id: 'LaneSet_1rqtug0',
lane: [
{
id: 'Lane_040h8y5',
childLaneSet: {
id: 'LaneSet_1pyljtf',
lane: [
{
id: 'Lane_06so1v5',
},
{
id: 'Lane_0amyaod',
childLaneSet: {
id: 'LaneSet_0lzaj18',
},
},
],
},
},
{
id: 'Lane_1gdg64y',
},
],
},
},
],
BPMNDiagram: {
id: 'BPMNDiagram_1',
BPMNPlane: {
id: 'BPMNPlane_1',
bpmnElement: 'Collaboration_0um5kdl',
BPMNShape: [
{
id: 'Lane_1gdg64y_di',
bpmnElement: 'Lane_1gdg64y',
isHorizontal: true,
Bounds: {
x: 186,
y: 340,
width: 584,
height: 200,
},
},
{
id: 'Lane_040h8y5_di',
bpmnElement: 'Lane_040h8y5',
isHorizontal: true,
Bounds: {
x: 186,
y: 80,
width: 584,
height: 260,
},
},
{
id: 'Lane_0amyaod_di',
bpmnElement: 'Lane_0amyaod',
isHorizontal: true,
Bounds: {
x: 216,
y: 214,
width: 554,
height: 126,
},
},
{
id: 'Lane_06so1v5_di',
bpmnElement: 'Lane_06so1v5',
isHorizontal: true,
Bounds: {
x: 216,
y: 80,
width: 554,
height: 134,
},
},
],
},
},
},
};

const model = parseJsonAndExpectOnlyLanes(json, 4);

verifyShape(model.lanes[0], {
shapeId: 'Lane_1gdg64y_di',
bpmnElementId: 'Lane_1gdg64y',
bpmnElementName: undefined,
parentId: 'Process_07bsa3h',
bpmnElementKind: ShapeBpmnElementKind.LANE,
bounds: {
x: 186,
y: 340,
width: 584,
height: 200,
},
});

verifyShape(model.lanes[1], {
shapeId: 'Lane_040h8y5_di',
bpmnElementId: 'Lane_040h8y5',
bpmnElementName: undefined,
parentId: 'Process_07bsa3h',
bpmnElementKind: ShapeBpmnElementKind.LANE,
bounds: {
x: 186,
y: 80,
width: 584,
height: 260,
},
});

verifyShape(model.lanes[2], {
shapeId: 'Lane_0amyaod_di',
bpmnElementId: 'Lane_0amyaod',
bpmnElementName: undefined,
parentId: 'Lane_040h8y5',
bpmnElementKind: ShapeBpmnElementKind.LANE,
bounds: {
x: 216,
y: 214,
width: 554,
height: 126,
},
});

verifyShape(model.lanes[3], {
shapeId: 'Lane_06so1v5_di',
bpmnElementId: 'Lane_06so1v5',
bpmnElementName: undefined,
parentId: 'Lane_040h8y5',
bpmnElementKind: ShapeBpmnElementKind.LANE,
bounds: {
x: 216,
y: 80,
width: 554,
height: 134,
},
});
});
});