Skip to content

Commit

Permalink
[FIX] Always fill the start and end flow markers
Browse files Browse the repository at this point in the history
Changes
  - Avoid seeing the line over the markers on some zoom level for the
  conditional start diamond and the message flow end arrow.
  - For message flow, also fill the 'start circle' to avoid seeing the edge line
  and the line of the source shape.

Implementation notes:
  - this requires custom code as mxgraph doesn't support filling the markers out
  of the box.
  - it is also possible to change the fill color as for other defaults.
  • Loading branch information
tbouffard committed Jun 14, 2021
1 parent 6e54299 commit 166e5ef
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
8 changes: 8 additions & 0 deletions src/component/mxgraph/StyleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export enum StyleDefault {
DEFAULT_OVERLAY_STROKE_WIDTH = 1,
DEFAULT_OVERLAY_FONT_SIZE = DEFAULT_FONT_SIZE,
DEFAULT_OVERLAY_FONT_COLOR = DEFAULT_FONT_COLOR,
// Edge
SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR = 'White',
MESSAGE_FLOW_MARKER_START_FILL_COLOR = 'White',
MESSAGE_FLOW_MARKER_END_FILL_COLOR = 'White',
}

export enum StyleIdentifier {
Expand All @@ -65,6 +69,10 @@ export enum StyleIdentifier {
BPMN_STYLE_MESSAGE_FLOW_ICON = 'bpmn.messageFlowIcon',
BPMN_STYLE_EVENT_BASED_GATEWAY_KIND = 'bpmn.gatewayKind',
BPMN_STYLE_EXTRA_CSS_CLASSES = 'bpmn.extra.css.classes',
// for edge
EDGE = 'bpmn.edge',
EDGE_START_FILL_COLOR = 'bpmn.edge.startFillColor',
EDGE_END_FILL_COLOR = 'bpmn.edge.endFillColor',
}

/* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types */
Expand Down
2 changes: 2 additions & 0 deletions src/component/mxgraph/config/ShapeConfigurator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { StyleIdentifier } from '../StyleUtils';
import { computeAllBpmnClassNames, extractBpmnKindFromStyle } from '../style-helper';
import { MxGraphCustomOverlay } from '../overlay/custom-overlay';
import { OverlayBadgeShape } from '../overlay/shapes';
import { BpmnConnector } from '../shape/edges';

/**
* @internal
Expand Down Expand Up @@ -76,6 +77,7 @@ export default class ShapeConfigurator {
mxgraph.mxCellRenderer.registerShape(ShapeBpmnElementKind.TEXT_ANNOTATION, TextAnnotationShape);

// shapes for flows
mxgraph.mxCellRenderer.registerShape(StyleIdentifier.EDGE, BpmnConnector);
mxgraph.mxCellRenderer.registerShape(StyleIdentifier.BPMN_STYLE_MESSAGE_FLOW_ICON, MessageFlowIconShape);
}

Expand Down
10 changes: 7 additions & 3 deletions src/component/mxgraph/config/StyleConfigurator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ export default class StyleConfigurator {
style[mxgraph.mxConstants.STYLE_DASH_PATTERN] = '8 5';
style[mxgraph.mxConstants.STYLE_STARTARROW] = mxgraph.mxConstants.ARROW_OVAL;
style[mxgraph.mxConstants.STYLE_STARTSIZE] = 8;
style[mxgraph.mxConstants.STYLE_STARTFILL] = false;
style[mxgraph.mxConstants.STYLE_STARTFILL] = true;
style[StyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_START_FILL_COLOR;
style[mxgraph.mxConstants.STYLE_ENDARROW] = mxgraph.mxConstants.ARROW_BLOCK_THIN;
style[mxgraph.mxConstants.STYLE_ENDFILL] = false;
style[mxgraph.mxConstants.STYLE_ENDFILL] = true;
style[StyleIdentifier.EDGE_END_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_END_FILL_COLOR;
},
],
[
Expand All @@ -84,7 +86,8 @@ export default class StyleConfigurator {
(style: StyleMap) => {
style[mxgraph.mxConstants.STYLE_STARTARROW] = mxgraph.mxConstants.ARROW_DIAMOND_THIN;
style[mxgraph.mxConstants.STYLE_STARTSIZE] = 18;
style[mxgraph.mxConstants.STYLE_STARTFILL] = false;
style[mxgraph.mxConstants.STYLE_STARTFILL] = true;
style[StyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR;
},
],
]);
Expand Down Expand Up @@ -238,6 +241,7 @@ export default class StyleConfigurator {

private configureDefaultEdgeStyle(): void {
const style = this.getDefaultEdgeStyle();
style[mxgraph.mxConstants.STYLE_SHAPE] = StyleIdentifier.EDGE;
style[mxgraph.mxConstants.STYLE_EDGE] = mxgraph.mxConstants.EDGESTYLE_SEGMENT;
style[mxgraph.mxConstants.STYLE_ENDSIZE] = 12;
style[mxgraph.mxConstants.STYLE_STROKEWIDTH] = 1.5;
Expand Down
71 changes: 71 additions & 0 deletions src/component/mxgraph/shape/edges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright 2021 Bonitasoft S.A.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { mxgraph } from '../initializer';
import { mxAbstractCanvas2D, mxPoint } from 'mxgraph';
import { StyleIdentifier } from '../StyleUtils'; // for types

/* eslint-disable @typescript-eslint/ban-ts-comment */
export class BpmnConnector extends mxgraph.mxConnector {
constructor(points: mxPoint[], stroke: string, strokewidth?: number) {
super(points, stroke, strokewidth);
}

paintEdgeShape(c: mxAbstractCanvas2D, pts: mxPoint[]): void {
// The indirection via functions for markers is needed in
// order to apply the offsets before painting the line and
// paint the markers after painting the line.
// @ts-ignore wrong type returned by [email protected]
const sourceMarker: () => void = this.createMarker(c, pts, true);
// @ts-ignore wrong type returned by [email protected]
const targetMarker: () => void = this.createMarker(c, pts, false);

this.paintEdgeLine(c, pts);

// Disables shadows, dashed styles
c.setShadow(false);
c.setDashed(false, false);

if (sourceMarker != null) {
c.setFillColor(mxgraph.mxUtils.getValue(this.style, StyleIdentifier.EDGE_START_FILL_COLOR, this.stroke));
sourceMarker();
}

if (targetMarker != null) {
c.setFillColor(mxgraph.mxUtils.getValue(this.style, StyleIdentifier.EDGE_END_FILL_COLOR, this.stroke));
targetMarker();
}
}

// taken from mxPolyline, required as we cannot call mxPolyline method here (parent of the parent)
// we only support non STYLE_CURVED here (is possible with parent class)
private paintEdgeLine(c: mxAbstractCanvas2D, pts: mxPoint[]): void {
const prev = getPointerEventsValue(c);
setPointerEventsValue(c, 'stroke');
this.paintLine(c, pts, this.isRounded);
setPointerEventsValue(c, prev);
}
}

function getPointerEventsValue(c: mxAbstractCanvas2D): string {
return c instanceof mxgraph.mxSvgCanvas2D ? c.pointerEventsValue : null;
}

function setPointerEventsValue(c: mxAbstractCanvas2D, value: string): void {
if (c instanceof mxgraph.mxSvgCanvas2D) {
c.pointerEventsValue = value;
}
}

0 comments on commit 166e5ef

Please sign in to comment.