Skip to content
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c958950
feat: add support for 'BPMN in Color'
tbouffard Apr 9, 2023
44563ff
e2e test: remove unused import
tbouffard Apr 9, 2023
94db78b
e2e: configure thresholds
tbouffard Apr 12, 2023
3a8f874
e2e: configure thresholds
tbouffard Apr 12, 2023
aa7080d
introduce RendererOptions: "bpmn in color" optional and ignored by de…
tbouffard May 4, 2023
7606577
Add integration test: check no "model colors" support by default
tbouffard May 9, 2023
7b03ac6
StyleComputer: no color support by default
tbouffard May 9, 2023
00eb1ea
lib: options to enable support for colors from BPMN model
tbouffard May 9, 2023
5d965d0
e2e tests: check when model colors are ignored or not
tbouffard May 9, 2023
8e98dd8
Merge branch 'master' into feat/bpmn-in-color
tbouffard May 9, 2023
e0660fe
tests: fix bad import after merge + reorg imports
tbouffard May 9, 2023
0f255fa
JSDoc: RendererOptions
tbouffard May 9, 2023
04afe69
fix unit and integration tests after merge
tbouffard May 9, 2023
3902d44
refactor parser: reduce the "Cognitive Complexity" (introduce specifi…
tbouffard May 9, 2023
b832d6d
e2e tests: set thresholds
tbouffard May 9, 2023
3513199
StyleComputer: add test when there is no extension
tbouffard May 9, 2023
80aacb8
docs: mention the "BPMN in Color" support in the users documentation
tbouffard May 11, 2023
921ce1c
docs: update the schema of the internal model (add extensions)
tbouffard May 11, 2023
f838422
API docs: warn usage of "default" value in StyleUpdate types
tbouffard May 16, 2023
57af8c9
API docs: fix typo
tbouffard May 16, 2023
7f1407e
StyleComputer.ts make field reaonly
tbouffard May 16, 2023
f5ec16f
Rename option ignoreModelColors into ignoreBpmnColors
tbouffard May 16, 2023
f9bd177
Merge branch 'master' into feat/bpmn-in-color
tbouffard May 25, 2023
d957d43
refactor: use named properties in EdgeExtensions, LabelExtensions, Sh…
tbouffard May 25, 2023
04052da
restore
tbouffard May 25, 2023
be6e750
restore
tbouffard May 25, 2023
4d2cc3d
refactor(StyleComputer): simplify passing arrays
tbouffard May 25, 2023
4ee509e
refactor(StyleComputer): simplify final style computation
tbouffard May 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions dev/ts/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,15 +273,23 @@ function configurePoolsFilteringFromParameters(parameters: URLSearchParams): Mod
export function startBpmnVisualization(config: BpmnVisualizationDemoConfiguration): void {
const log = logStartup;
log(`Initializing BpmnVisualization with container '${config.globalOptions.container}'...`);

const parameters = new URLSearchParams(window.location.search);
const rendererIgnoreBpmnColors = parameters.get('renderer.ignore.bpmn.colors');
if (rendererIgnoreBpmnColors) {
const ignoreBpmnColors = rendererIgnoreBpmnColors === 'true';
log('Ignore support for "BPMN in Color"?', ignoreBpmnColors);
!config.globalOptions.renderer && (config.globalOptions.renderer = {});
config.globalOptions.renderer.ignoreBpmnColors = ignoreBpmnColors;
}

bpmnVisualization = new ThemedBpmnVisualization(config.globalOptions);
log('Initialization completed');
new DropFileUserInterface(window, 'drop-container', bpmnVisualization.graph.container, readAndLoadFile);
log('Drag&Drop support initialized');

statusKoNotifier = config.statusKoNotifier ?? logOnlyStatusKoNotifier;

const parameters = new URLSearchParams(window.location.search);

log('Configuring Load Options');
loadOptions = config.loadOptions || {};
loadOptions.fit = getFitOptionsFromParameters(config, parameters);
Expand Down

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/users/images/bpmn-in-color-C.1.0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions docs/users/overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ image::images/bpmn-theme-custom-colors.png[Custom BPMN Theme]
_Custom BPMN Theme_


==== `BPMN in Color` Support

As of version 0.35.0, `bpmn-visualization` supports the https://github.com/bpmn-miwg/bpmn-in-color[BPMN in Color Specification] with a fallback to the
https://github.com/bpmn-io/bpmn-moddle/blob/ea7fa6a94c55f49fe1da1f019dc9a40d62967252/resources/bpmn-io/json/bioc.json[bpmn.io specific BPMN extensions for colors] (a.k.a `bioc`).

This support is disabled by default, and it can be enabled at the library initialization.

image::images/bpmn-in-color-C.1.0.png[C.1.0 with "BPMN in Color"]

_miwg-test-suite C.1.0 reference diagram using "BPMN in Color"_


[[diagram-navigation]]
=== Diagram Navigation

Expand Down
7 changes: 5 additions & 2 deletions src/component/BpmnVisualization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import GraphConfigurator from './mxgraph/GraphConfigurator';
import { newBpmnRenderer } from './mxgraph/BpmnRenderer';
import { newBpmnParser } from './parser/BpmnParser';
import type { BpmnGraph } from './mxgraph/BpmnGraph';
import type { GlobalOptions, LoadOptions, ParserOptions } from './options';
import type { GlobalOptions, LoadOptions, ParserOptions, RendererOptions } from './options';
import type { BpmnElementsRegistry } from './registry';
import { newBpmnElementsRegistry } from './registry/bpmn-elements-registry';
import { BpmnModelRegistry } from './registry/bpmn-model-registry';
Expand Down Expand Up @@ -69,7 +69,10 @@ export class BpmnVisualization {

private readonly parserOptions: ParserOptions;

private readonly rendererOptions: RendererOptions;

constructor(options: GlobalOptions) {
this.rendererOptions = options?.renderer;
// mxgraph configuration
const configurator = new GraphConfigurator(htmlElement(options?.container));
this.graph = configurator.configure(options);
Expand All @@ -89,7 +92,7 @@ export class BpmnVisualization {
load(xml: string, options?: LoadOptions): void {
const bpmnModel = newBpmnParser(this.parserOptions).parse(xml);
const renderedModel = this.bpmnModelRegistry.load(bpmnModel, options?.modelFilter);
newBpmnRenderer(this.graph).render(renderedModel, options?.fit);
newBpmnRenderer(this.graph, this.rendererOptions).render(renderedModel, options?.fit);
}

getVersion(): Version {
Expand Down
6 changes: 3 additions & 3 deletions src/component/mxgraph/BpmnRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { MessageVisibleKind, ShapeUtil } from '../../model/bpmn/internal';
import CoordinatesTranslator from './renderer/CoordinatesTranslator';
import StyleComputer from './renderer/StyleComputer';
import type { BpmnGraph } from './BpmnGraph';
import type { FitOptions } from '../options';
import type { FitOptions, RendererOptions } from '../options';
import type { RenderedModel } from '../registry/bpmn-model-registry';
import { mxgraph } from './initializer';
import type { mxCell } from 'mxgraph';
Expand Down Expand Up @@ -139,8 +139,8 @@ export class BpmnRenderer {
/**
* @internal
*/
export function newBpmnRenderer(graph: BpmnGraph): BpmnRenderer {
return new BpmnRenderer(graph, new CoordinatesTranslator(graph), new StyleComputer());
export function newBpmnRenderer(graph: BpmnGraph, options: RendererOptions): BpmnRenderer {
return new BpmnRenderer(graph, new CoordinatesTranslator(graph), new StyleComputer(options));
}

/**
Expand Down
70 changes: 58 additions & 12 deletions src/component/mxgraph/renderer/StyleComputer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,39 +31,46 @@ import { BpmnStyleIdentifier } from '../style';
import { MessageVisibleKind, ShapeBpmnCallActivityKind, ShapeBpmnElementKind, ShapeBpmnMarkerKind, ShapeUtil } from '../../../model/bpmn/internal';
import { AssociationFlow, SequenceFlow } from '../../../model/bpmn/internal/edge/flows';
import type { Font } from '../../../model/bpmn/internal/Label';
import type { RendererOptions } from '../../options';

/**
* @internal
*/
export default class StyleComputer {
private readonly ignoreBpmnColors: boolean;

constructor(options?: RendererOptions) {
this.ignoreBpmnColors = options?.ignoreBpmnColors ?? true;
}

computeStyle(bpmnCell: Shape | Edge, labelBounds: Bounds): string {
const styles: string[] = [bpmnCell.bpmnElement.kind as string];
Comment thread
csouchet marked this conversation as resolved.

let shapeStyleValues;
let mainStyleValues;
if (bpmnCell instanceof Shape) {
shapeStyleValues = StyleComputer.computeShapeStyle(bpmnCell);
mainStyleValues = this.computeShapeStyleValues(bpmnCell);
} else {
styles.push(...StyleComputer.computeEdgeStyle(bpmnCell));
shapeStyleValues = new Map<string, string | number>();
styles.push(...StyleComputer.computeEdgeBaseStyles(bpmnCell));
mainStyleValues = this.computeEdgeStyleValues(bpmnCell);
}

const fontStyleValues = StyleComputer.computeFontStyleValues(bpmnCell);
const fontStyleValues = this.computeFontStyleValues(bpmnCell);
const labelStyleValues = StyleComputer.computeLabelStyleValues(bpmnCell, labelBounds);

return [] //
.concat([...styles])
Comment thread
csouchet marked this conversation as resolved.
Outdated
.concat([...shapeStyleValues, ...fontStyleValues, ...labelStyleValues].filter(([, v]) => v && v != 'undefined').map(([key, value]) => key + '=' + value))
.concat(toArrayOfMxGraphStyleEntries([...mainStyleValues, ...fontStyleValues, ...labelStyleValues]))
.join(';');
}

private static computeShapeStyle(shape: Shape): Map<string, string | number> {
private computeShapeStyleValues(shape: Shape): Map<string, string | number> {
const styleValues = new Map<string, string | number>();
const bpmnElement = shape.bpmnElement;

if (bpmnElement instanceof ShapeBpmnEvent) {
this.computeEventShapeStyle(bpmnElement, styleValues);
StyleComputer.computeEventShapeStyle(bpmnElement, styleValues);
} else if (bpmnElement instanceof ShapeBpmnActivity) {
this.computeActivityShapeStyle(bpmnElement, styleValues);
StyleComputer.computeActivityShapeStyle(bpmnElement, styleValues);
} else if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) {
// mxgraph.mxConstants.STYLE_HORIZONTAL is for the label
// In BPMN, isHorizontal is for the Shape
Expand All @@ -74,6 +81,18 @@ export default class StyleComputer {
styleValues.set(BpmnStyleIdentifier.EVENT_BASED_GATEWAY_KIND, String(bpmnElement.gatewayKind));
}

if (!this.ignoreBpmnColors) {
const extensions = shape.extensions;
const fillColor = extensions.fillColor;
if (fillColor) {
styleValues.set(mxgraph.mxConstants.STYLE_FILLCOLOR, fillColor);
if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) {
styleValues.set(mxgraph.mxConstants.STYLE_SWIMLANE_FILLCOLOR, fillColor);
}
}
extensions.strokeColor && styleValues.set(mxgraph.mxConstants.STYLE_STROKECOLOR, extensions.strokeColor);
}

return styleValues;
}

Expand All @@ -100,7 +119,7 @@ export default class StyleComputer {
}
}

private static computeEdgeStyle(edge: Edge): string[] {
private static computeEdgeBaseStyles(edge: Edge): string[] {
const styles: string[] = [];

const bpmnElement = edge.bpmnElement;
Expand All @@ -114,7 +133,18 @@ export default class StyleComputer {
return styles;
}

private static computeFontStyleValues(bpmnCell: Shape | Edge): Map<string, string | number> {
private computeEdgeStyleValues(edge: Edge): Map<string, string | number> {
const styleValues = new Map<string, string | number>();

if (!this.ignoreBpmnColors) {
const extensions = edge.extensions;
extensions.strokeColor && styleValues.set(mxgraph.mxConstants.STYLE_STROKECOLOR, extensions.strokeColor);
}

return styleValues;
}

private computeFontStyleValues(bpmnCell: Shape | Edge): Map<string, string | number> {
const styleValues = new Map<string, string | number>();

const font = bpmnCell.label?.font;
Expand All @@ -124,6 +154,11 @@ export default class StyleComputer {
styleValues.set(mxgraph.mxConstants.STYLE_FONTSTYLE, getFontStyleValue(font));
}

if (!this.ignoreBpmnColors) {
const extensions = bpmnCell.label?.extensions;
extensions?.color && styleValues.set(mxgraph.mxConstants.STYLE_FONTCOLOR, extensions.color);
}

return styleValues;
}

Expand Down Expand Up @@ -162,7 +197,14 @@ export default class StyleComputer {
}

computeMessageFlowIconStyle(edge: Edge): string {
return `shape=${BpmnStyleIdentifier.MESSAGE_FLOW_ICON};${BpmnStyleIdentifier.IS_INITIATING}=${edge.messageVisibleKind === MessageVisibleKind.INITIATING}`;
const styleValues: Array<[string, string]> = [];
styleValues.push(['shape', BpmnStyleIdentifier.MESSAGE_FLOW_ICON]);
styleValues.push([BpmnStyleIdentifier.IS_INITIATING, String(edge.messageVisibleKind === MessageVisibleKind.INITIATING)]);
if (!this.ignoreBpmnColors) {
edge.extensions.strokeColor && styleValues.push([mxgraph.mxConstants.STYLE_STROKECOLOR, edge.extensions.strokeColor]);
}

return toArrayOfMxGraphStyleEntries([...styleValues]).join(';');
Comment thread
tbouffard marked this conversation as resolved.
Outdated
}
}

Expand All @@ -186,3 +228,7 @@ export function getFontStyleValue(font: Font): number {
}
return value;
}

function toArrayOfMxGraphStyleEntries(styleValues: Array<[string, string | number]>): string[] {
return styleValues.filter(([, v]) => v && v != 'undefined').map(([key, value]) => `${key}=${value}`);
}
20 changes: 20 additions & 0 deletions src/component/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export interface GlobalOptions {
navigation?: NavigationConfiguration;
/** Configure the BPMN parser. */
parser?: ParserOptions;
/** Configure how the BPMN diagram and its elements are rendered. */
renderer?: RendererOptions;
}

/**
Expand Down Expand Up @@ -180,3 +182,21 @@ export type ParserOptions = {
*/
additionalXmlAttributeProcessor?: (val: string) => string;
};

/**
* Global configuration for the rendering of the BPMN elements.
*
* @category Initialization & Configuration
* @since 0.35.0
*/
export type RendererOptions = {
/**
* If set to `false`, support the "BPMN in Color" specification with a fallback with bpmn.io colors. For more details about the support, see
* {@link https://github.com/process-analytics/bpmn-visualization-js/pull/2614}.
*
* Otherwise, disable the support.
*
* @default true
*/
ignoreBpmnColors?: boolean;
};
72 changes: 52 additions & 20 deletions src/component/parser/json/converter/DiagramConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ import { Edge, Waypoint } from '../../../../model/bpmn/internal/edge/edge';
import type { Shapes } from '../../../../model/bpmn/internal/BpmnModel';
import type BpmnModel from '../../../../model/bpmn/internal/BpmnModel';
import Label, { Font } from '../../../../model/bpmn/internal/Label';
import { MessageVisibleKind } from '../../../../model/bpmn/internal/edge/kinds';
import { MessageVisibleKind, ShapeBpmnCallActivityKind, ShapeBpmnMarkerKind, ShapeUtil } from '../../../../model/bpmn/internal';
import type { BPMNDiagram, BPMNEdge, BPMNLabel, BPMNLabelStyle, BPMNShape } from '../../../../model/bpmn/json/BPMNDI';
import type { Point } from '../../../../model/bpmn/json/DC';
import type { ConvertedElements } from './utils';
import { ShapeBpmnCallActivityKind, ShapeBpmnMarkerKind, ShapeUtil } from '../../../../model/bpmn/internal';
import { ensureIsArray } from '../../../helpers/array-utils';
import type { ParsingMessageCollector } from '../../parsing-messages';
import { EdgeUnknownBpmnElementWarning, LabelStyleMissingFontWarning, ShapeUnknownBpmnElementWarning } from '../warnings';
Expand Down Expand Up @@ -104,26 +103,44 @@ export default class DiagramConverter {
return false;
}

private deserializeShape(shape: BPMNShape, findShapeElement: (bpmnElement: string) => ShapeBpmnElement): Shape | undefined {
const bpmnElement = findShapeElement(shape.bpmnElement);
private deserializeShape(bpmnShape: BPMNShape, findShapeElement: (bpmnElement: string) => ShapeBpmnElement): Shape | undefined {
const bpmnElement = findShapeElement(bpmnShape.bpmnElement);
if (bpmnElement) {
const bounds = DiagramConverter.deserializeBounds(shape);
const bounds = DiagramConverter.deserializeBounds(bpmnShape);

if (
(bpmnElement instanceof ShapeBpmnSubProcess ||
(bpmnElement instanceof ShapeBpmnCallActivity && bpmnElement.callActivityKind === ShapeBpmnCallActivityKind.CALLING_PROCESS)) &&
!shape.isExpanded
!bpmnShape.isExpanded
) {
bpmnElement.markers.push(ShapeBpmnMarkerKind.EXPAND);
}

let isHorizontal;
if (ShapeUtil.isPoolOrLane(bpmnElement.kind)) {
isHorizontal = shape.isHorizontal ?? true;
isHorizontal = bpmnShape.isHorizontal ?? true;
}

const label = this.deserializeLabel(shape.BPMNLabel, shape.id);
return new Shape(shape.id, bpmnElement, bounds, label, isHorizontal);
const bpmnLabel = bpmnShape.BPMNLabel;
const label = this.deserializeLabel(bpmnLabel, bpmnShape.id);
const shape = new Shape(bpmnShape.id, bpmnElement, bounds, label, isHorizontal);
DiagramConverter.setColorExtensionsOnShape(shape, bpmnShape);

return shape;
}
}

// 'BPMN in Color' extensions with fallback to bpmn.io colors
private static setColorExtensionsOnShape(shape: Shape, bpmnShape: BPMNShape): void {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion:

I think we don't need to check if background-color, fill, border-color and stroke are in bpmnShape, because even if there are undefined, with this implementation or the suggested implementation, the attributes of shape.extensions will be undefined.

Suggested change
private static setColorExtensionsOnShape(shape: Shape, bpmnShape: BPMNShape): void {
private static setColorExtensionsOnShape(shape: Shape, bpmnShape: BPMNShape): void {
shape.extensions.fillColor = <string>bpmnShape['background-color'] ?? <string>bpmnShape['fill'];
shape.extensions.strokeColor = <string>bpmnShape['border-color'] ?? <string>bpmnShape['stroke'];
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The usage of the color extensions is very rare, so the idea was to not have properties with undefined values but to have no property in this case.
The model is not stored internally, so I will give it a try to your proposal to simplify the code here and for Edge.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@csouchet the proposal cannot be implemented out of the box

const backgroundColor = bpmnShape['background-color'];

generates a TS error TS7053: Element implicitly has an 'any' type because expression of type '"background-color"' can't be used to index type 'BPMNShape'.   Property 'background-color' does not exist on type 'BPMNShape'.

I can ignore the error but the resulting code is less lisible and ignoring error is misleading

    // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- explain why!
    // @ts-ignore
    shape.extensions.fillColor = <string>bpmnShape['background-color'] ?? <string>bpmnShape['fill'];
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- explain why!
    // @ts-ignore
    shape.extensions.strokeColor = <string>bpmnShape['border-color'] ?? <string>bpmnShape['stroke'];

if ('background-color' in bpmnShape) {
shape.extensions.fillColor = <string>bpmnShape['background-color'];
} else if ('fill' in bpmnShape) {
shape.extensions.fillColor = <string>bpmnShape['fill'];
}
if ('border-color' in bpmnShape) {
shape.extensions.strokeColor = <string>bpmnShape['border-color'];
} else if ('stroke' in bpmnShape) {
shape.extensions.strokeColor = <string>bpmnShape['stroke'];
}
}

Expand All @@ -136,26 +153,37 @@ export default class DiagramConverter {

private deserializeEdges(edges: BPMNEdge | BPMNEdge[]): Edge[] {
return ensureIsArray(edges)
.map(edge => {
.map(bpmnEdge => {
const flow =
this.convertedElements.findSequenceFlow(edge.bpmnElement) ||
this.convertedElements.findMessageFlow(edge.bpmnElement) ||
this.convertedElements.findAssociationFlow(edge.bpmnElement);
this.convertedElements.findSequenceFlow(bpmnEdge.bpmnElement) ||
this.convertedElements.findMessageFlow(bpmnEdge.bpmnElement) ||
this.convertedElements.findAssociationFlow(bpmnEdge.bpmnElement);

if (!flow) {
this.parsingMessageCollector.warning(new EdgeUnknownBpmnElementWarning(edge.bpmnElement));
this.parsingMessageCollector.warning(new EdgeUnknownBpmnElementWarning(bpmnEdge.bpmnElement));
return;
}

const waypoints = this.deserializeWaypoints(edge.waypoint);
const label = this.deserializeLabel(edge.BPMNLabel, edge.id);
const messageVisibleKind = edge.messageVisibleKind ? (edge.messageVisibleKind as unknown as MessageVisibleKind) : MessageVisibleKind.NONE;
const waypoints = this.deserializeWaypoints(bpmnEdge.waypoint);
const label = this.deserializeLabel(bpmnEdge.BPMNLabel, bpmnEdge.id);
const messageVisibleKind = bpmnEdge.messageVisibleKind ? (bpmnEdge.messageVisibleKind as unknown as MessageVisibleKind) : MessageVisibleKind.NONE;

return new Edge(edge.id, flow, waypoints, label, messageVisibleKind);
const edge = new Edge(bpmnEdge.id, flow, waypoints, label, messageVisibleKind);
DiagramConverter.setColorExtensionsOnEdge(edge, bpmnEdge);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question:
Same as for Shape

return edge;
})
.filter(Boolean);
}

// 'BPMN in Color' extensions with fallback to bpmn.io colors
private static setColorExtensionsOnEdge(edge: Edge, bpmnEdge: BPMNEdge): void {
if ('border-color' in bpmnEdge) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion:

Suggested change
if ('border-color' in bpmnEdge) {
edge.extensions.strokeColor = <string>bpmnEdge['border-color'] ?? <string>bpmnEdge['stroke'];
}

edge.extensions.strokeColor = <string>bpmnEdge['border-color'];
} else if ('stroke' in bpmnEdge) {
edge.extensions.strokeColor = <string>bpmnEdge['stroke'];
}
}

private deserializeWaypoints(waypoints: Point[]): Waypoint[] {
return ensureIsArray(waypoints).map(waypoint => new Waypoint(waypoint.x, waypoint.y));
}
Expand All @@ -164,9 +192,13 @@ export default class DiagramConverter {
if (bpmnLabel && typeof bpmnLabel === 'object') {
const font = this.findFont(bpmnLabel.labelStyle, id);
const bounds = DiagramConverter.deserializeBounds(bpmnLabel);

const label = new Label(font, bounds);
if ('color' in bpmnLabel) {
label.extensions.color = <string>bpmnLabel.color;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question:

Same as for Shape & Edge

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Here this would change the behavior.
We return a Label instance only if properties are set (previously only font and bounds.
If I change the implementation as for shape and edge, we will always have an instance even when the label color is undefined.
So, I prefer not to change it.

return label;
}
if (font || bounds) {
return new Label(font, bounds);
return label;
}
}
}
Expand Down
Loading