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

refactor: [POC] Replace mxGraph with maxGraph 0.10.x #3098

Draft
wants to merge 90 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
9083c7d
POC maxGraph 0.1.0 v1
tbouffard Jul 4, 2023
2909669
TMP disable the GH workflow running the e2e tests (not passing)
tbouffard Jun 16, 2023
8f4ee05
POC maxGraph 0.1.0 v2
tbouffard Jun 16, 2023
f6681a1
bump maxGraph from 0.1.0 to 0.10.0
tbouffard Apr 22, 2024
f3b1775
update package-lock.json
tbouffard Apr 22, 2024
db2a32a
fix tsc error after bumping maxGraph
tbouffard Apr 22, 2024
b8df3cc
bump vite to not have "No matching export in"
tbouffard Apr 22, 2024
bb5b140
update package-lock.json
tbouffard Apr 22, 2024
cdced05
fix tsc error after bumping maxGraph
tbouffard Apr 22, 2024
675857d
StyleConfigurator.ts add missing TODO maxgraph 0.1.0
tbouffard Apr 23, 2024
fc62054
EXTRA integration tests run in ESM (needed for maxgraph --> IN PROGRE…
tbouffard Apr 22, 2024
1aa5ee2
EXTRA unit tests run in ESM (needed to run maxgraph)
tbouffard Apr 23, 2024
d6d2261
WIP e2e and perf tests run in ESM (with commonJS configuration)
tbouffard Apr 23, 2024
d6420fb
WIP e2e and perf tests run in ESM (with commonJS configuration)
tbouffard Apr 23, 2024
e3af056
EXTRA jest.image.ts fix async by using await
tbouffard Apr 23, 2024
c925966
WIP e2e tests run in ESM - tmp jest.image configuration
tbouffard Apr 23, 2024
c95a9cb
WIP e2e tests run in ESM - tmp jest.image configuration
tbouffard Apr 23, 2024
54e8117
WIP e2e tests run in ESM - tmp jest.image configuration
tbouffard Apr 23, 2024
b002dcd
WIP e2e tests run in ESM - fix package.json script
tbouffard Apr 23, 2024
99901fa
bump maxGraph
tbouffard Apr 23, 2024
ec2b544
update package-lock.json after maxGraph bump
tbouffard Apr 23, 2024
2286241
vite: reduce the chunk limit to match maxGraph chunk size
tbouffard Apr 23, 2024
a6b3f2a
EXTRA (todo on master) e2e: start fixing path to received file in fit…
tbouffard Apr 23, 2024
7ae90a5
EXTRA (todo on master) e2e: start fixing path to received file in fit…
tbouffard Apr 26, 2024
f340246
EXTRA (todo on master) e2e: start fixing path to received file in fit…
tbouffard Apr 26, 2024
6f2f057
EXTRA (todo on master) e2e: start fixing path to received file in fit…
tbouffard Aug 9, 2024
2c5726d
EXTRA (todo on master) e2e: start fixing path to received file in fit…
tbouffard Aug 13, 2024
d208c48
StyleConfigurator.ts: manage todo from maxgraph 0.1.0
tbouffard Apr 23, 2024
21f6694
StyleManager update TODO
tbouffard Apr 23, 2024
82ce011
Manage some TODO maxgraph 0.1.0 in StyleComputer.test.ts
tbouffard Apr 23, 2024
8024887
Manage some TODO maxgraph 0.1.0 in StyleComputer.test.ts
tbouffard Apr 23, 2024
a6fc85b
Fix typo in TODO of StyleConfigurator.ts
tbouffard Apr 24, 2024
221aac3
StyleComputer.ts BPMNCellStyle remove arrow fill properties available…
tbouffard Apr 24, 2024
bcd1f7e
Add TODO
tbouffard Apr 26, 2024
3ea1a7e
fix TODO
tbouffard Apr 26, 2024
827f436
update TODO in BpmnGraph.ts
tbouffard Apr 26, 2024
f91d847
update TODO in BpmnRenderer.ts
tbouffard Apr 26, 2024
b6a14e1
Use Graph.insertXXX methods with a single parameter
tbouffard Apr 26, 2024
14ab375
Remove FONT and use the constants.FONT from maxGraph
tbouffard Apr 26, 2024
cacc7f5
setStyleFlag: remove workaround as there is now a fix in maxGraph
tbouffard Apr 26, 2024
a4e6ffc
Manage TODO in utils.ts getCellStyleClone
tbouffard Apr 26, 2024
eff4a53
Update TODO
tbouffard Apr 26, 2024
628a6d8
StyleComputer.ts update TODO
tbouffard Apr 26, 2024
af351af
StyleComputer.ts: fix TODO
tbouffard Apr 26, 2024
88a6524
remove extra imports
tbouffard Apr 26, 2024
dc396e0
Update edge.arcSize value to replicate the rendering we had with mxGraph
tbouffard Apr 26, 2024
927ce24
Move BPMNCellStyle to a dedicated file
tbouffard Apr 26, 2024
79ea060
StyleComputer.ts manage TODO
tbouffard Apr 26, 2024
e37b321
style-utils.ts manage TODO
tbouffard Apr 26, 2024
65c4935
Update todo of maxgraph 0.1.0: mark them to be done after a new rebas…
tbouffard Apr 26, 2024
a36015a
manage TODO in utils.ts setCssClasses
tbouffard Apr 26, 2024
53197c3
Update todo of maxgraph 0.1.0: mark them to be done after a new rebas…
tbouffard Apr 26, 2024
d72d568
Update todo of maxgraph 0.1.0: mark them to be done after a new rebas…
tbouffard Apr 26, 2024
bdea858
Rename the "BpmnCellStyle" type used in tests
tbouffard Apr 26, 2024
0ccbc64
Rename "BPMNCellStyle" into "BpmnCellStyle" type to use a consistent …
tbouffard Apr 26, 2024
c7e5142
test: Remove "align" types and use maxGraph "align" type instead (the…
tbouffard Apr 26, 2024
e5b5fa2
Update todo of maxgraph 0.1.0: mark them to be done after a new rebas…
tbouffard Apr 26, 2024
643bf1a
StyleComputer.test.ts: manage TODO
tbouffard Apr 26, 2024
797c9f4
Update TODO in style-utils.test.ts
tbouffard Apr 26, 2024
242fe00
StyleConfigurator.ts: update TODO about Perimeter configuration
tbouffard May 23, 2024
5894e10
bump maxGraph to 0.10.2
tbouffard May 24, 2024
284905a
package-lock.json - bump maxGraph to 0.10.2
tbouffard May 24, 2024
c286c77
SVGExporter: manage TODO
tbouffard May 24, 2024
7fc8e9d
SVGExporter: try to debug empty content
tbouffard May 24, 2024
a4bade6
ShapeConfigurator.ts: manage TODO
tbouffard May 24, 2024
087bf5c
custom-overlay.ts: manage TODO
tbouffard May 24, 2024
e7b8f89
SvgExporter.ts: update TODO - add link to maxGraph PR fixing issues
tbouffard May 27, 2024
3ca3cd0
GraphConfigurator.ts add TODO about foldingEnabled configuration
tbouffard May 27, 2024
5930261
Introduce BpmnCellStateStyle
tbouffard Aug 9, 2024
9672809
Introduce BpmnCellStateStyle - ShapeConfigurator.ts: remove unused im…
tbouffard Aug 9, 2024
39d2e31
GraphConfigurator.ts: update TODO about PanningHandler
tbouffard Aug 9, 2024
ff1e1cf
GraphCellUpdater: update TODO
tbouffard Aug 9, 2024
84f62b2
Graph constructor: only used maxGraph plugins we need
tbouffard Aug 9, 2024
ca48e96
WIP remove maxGraph workaround for v0.1.0 that are now fixed
tbouffard Aug 9, 2024
f265908
WIP remove maxGraph workaround for v0.1.0 that are now fixed
tbouffard Aug 9, 2024
61bd589
WIP remove maxGraph workaround for v0.1.0 that are now fixed
tbouffard Aug 9, 2024
e2e6f76
WIP remove maxGraph workaround for v0.1.0 that are now fixed - BpmnGr…
tbouffard Aug 9, 2024
3924d31
GraphCellUpdater.ts update TODO
tbouffard Aug 9, 2024
67a7b5b
GraphConfigurator.ts update TODO
tbouffard Aug 9, 2024
227c849
types.ts: update TODO
tbouffard Aug 9, 2024
d993029
BpmnGraph.ts update TODO
tbouffard Aug 9, 2024
4e2bba3
ShapeConfigurator.ts update TODO
tbouffard Aug 9, 2024
8e18141
StyleConfigurator.ts simplify type
tbouffard Aug 9, 2024
34553da
StyleConfigurator.ts: update TODO
tbouffard Aug 9, 2024
db7e4a2
StyleConfigurator.ts: update TODO
tbouffard Aug 9, 2024
2de8548
StyleConfigurator.ts: TMP update edge arcSize to try to reproduce the…
tbouffard Aug 9, 2024
16768c2
custom-overlay.ts: update TODO
tbouffard Aug 9, 2024
e10cecd
StyleConfigurator.ts: TMP update edge arcSize to try to reproduce the…
tbouffard Aug 11, 2024
da64089
bump maxgraph to 0.10.3 + fix enabledFolding option in GraphConfigura…
tbouffard Aug 13, 2024
f50b06e
update package-lock.json after bump maxgraph to 0.10.3
tbouffard Aug 13, 2024
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
1 change: 1 addition & 0 deletions .github/workflows/test-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ on:
jobs:
test_e2e:
runs-on: ${{ matrix.os }}
if: github.event_name == 'NOT_SUPPORTED' # TEMP disable e2e until the code compile and the JS doesn't generate runtime errors that block the dev server
strategy:
# we want to run the full build on all os: don't cancel running jobs even if one fails
fail-fast: false
Expand Down
6 changes: 6 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"name": "test:unit",
"request": "launch",
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
"env": {
"NODE_OPTIONS": "--experimental-vm-modules"
},
"args": [
"--runInBand", "--config=./test/unit/jest.config.js"
],
Expand All @@ -33,6 +36,9 @@
"name": "test:integration",
"request": "launch",
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
"env": {
"NODE_OPTIONS": "--experimental-vm-modules"
},
"args": [
"--runInBand", "--config=./test/integration/jest.config.js"
],
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
"source.fixAll": "explicit"
},
// Jest Extension (https://github.com/jest-community/vscode-jest)
// The following is to run unit tests
Expand Down
85 changes: 51 additions & 34 deletions dev/ts/component/SvgExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { mxgraph, mxClient, mxConstants, mxSvgCanvas2D, mxUtils } from '../../../src/component/mxgraph/initializer';
import type { mxGraph, mxSvgCanvas2D as mxSvgCanvas2DType } from 'mxgraph';
import { Client, SvgCanvas2D, ImageExport, constants, xmlUtils, domUtils, stringUtils, XmlCanvas2D } from '@maxgraph/core';
import type { Graph, AlignValue, VAlignValue, OverflowValue, TextDirectionValue } from '@maxgraph/core';

interface SvgExportOptions {
scale: number;
Expand All @@ -30,7 +30,7 @@ interface SvgExportOptions {
// https://github.com/jgraph/drawio/blob/v14.7.7/src/main/webapp/js/diagramly/Editor.js#L5932
// https://github.com/jgraph/drawio/blob/v14.8.0/src/main/webapp/js/grapheditor/Graph.js#L9007
export class SvgExporter {
constructor(private graph: mxGraph) {}
constructor(private graph: Graph) {}

exportSvg(): string {
return this.doSvgExport(true);
Expand All @@ -40,20 +40,37 @@ export class SvgExporter {
// chrome and webkit: tainted canvas when svg contains foreignObject
// also on brave --> probably fail on chromium based browsers
// so disable foreign objects for such browsers
const isFirefox = mxClient.IS_FF;
const isFirefox = Client.IS_FF;
return this.doSvgExport(isFirefox);
}

// TODO [email protected] migration - generate empty content - should be fixed with https://github.com/maxGraph/maxGraph/pull/425
private doSvgExport(enableForeignObjectForLabel: boolean): string {
const svgDocument = this.computeSvg({ scale: 1, border: 25, enableForeignObjectForLabel: enableForeignObjectForLabel });
const svgAsString = mxUtils.getXml(svgDocument);

const svgAsString = xmlUtils.getXml(svgDocument);
// DEBUG - TODO [email protected] - attempt to debug empty content
console.warn('svgDocument', svgDocument);
const xmlDoc = xmlUtils.createXmlDocument();
const root = xmlDoc.createElement('data');
xmlDoc.appendChild(root);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore -- TODO [email protected] migration - wrong type in maxGraph XmlCanvas2D constructor, should be Element in constructor - see https://github.com/maxGraph/maxGraph/pull/423
const xmlCanvas = new XmlCanvas2D(root);
const imgExport = new ImageExport();
imgExport.includeOverlays = true;
imgExport.drawState(this.graph.getView().getState(this.graph.model.root), xmlCanvas);
const xml = xmlUtils.getXml(root);
console.warn('xml', xml);
// end of DEBUG

return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
${svgAsString}
`;
}

private computeSvg(svgExportOptions: SvgExportOptions): XMLDocument {
private computeSvg(svgExportOptions: SvgExportOptions): Element {
const scale = svgExportOptions.scale ?? 1;
const border = svgExportOptions.border ?? 0;
const crisp = svgExportOptions.crisp ?? true;
Expand All @@ -63,8 +80,8 @@ ${svgAsString}
const viewScale = this.graph.view.scale;

// Prepares SVG document that holds the output
const svgDoc = mxUtils.createXmlDocument();
const root = svgDoc.createElementNS(mxConstants.NS_SVG, 'svg');
const svgDoc = xmlUtils.createXmlDocument();
const root = svgDoc.createElementNS(constants.NS_SVG, 'svg');

const s = scale / viewScale;
const w = Math.max(1, Math.ceil(bounds.width * s) + 2 * border);
Expand All @@ -76,7 +93,7 @@ ${svgAsString}
root.setAttribute('viewBox', (crisp ? '-0.5 -0.5' : '0 0') + ' ' + w + ' ' + h);
svgDoc.appendChild(root);

const group = svgDoc.createElementNS(mxConstants.NS_SVG, 'g');
const group = svgDoc.createElementNS(constants.NS_SVG, 'g');
root.appendChild(group);

const svgCanvas = this.createSvgCanvas(group);
Expand All @@ -91,50 +108,46 @@ ${svgAsString}

svgCanvas.scale(s);

const imgExport = new mxgraph.mxImageExport();
const imgExport = new ImageExport();
// FIXME only the first overlay is placed at the right position
// overlays put on element of subprocess/call-activity are not placed correctly in svg export
imgExport.includeOverlays = true;

imgExport.drawState(this.graph.getView().getState(this.graph.model.root), svgCanvas);
return svgDoc;
return root;
}

createSvgCanvas(node: Element): mxSvgCanvas2DType {
const canvas = new CanvasForExport(node);
createSvgCanvas(node: SVGElement): SvgCanvas2D {
const canvas = new CanvasForExport(node, true);
// from the draw.io code, may not be needed here
canvas.pointerEvents = true;
return canvas;
}
}

class CanvasForExport extends mxSvgCanvas2D {
class CanvasForExport extends SvgCanvas2D {
// Convert HTML entities
private htmlConverter = document.createElement('div');

constructor(node: Element) {
super(node);
}

override getAlternateText(
fo: Element,
fo: SVGForeignObjectElement,
x: number,
y: number,
w: number,
h: number,
str: string,
str: Element | string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
align: string,
align: AlignValue,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
valign: string,
valign: VAlignValue,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
wrap: string,
wrap: boolean,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
format: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
overflow: string,
overflow: OverflowValue,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
clip: string,
clip: boolean,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
rotation: number,
): string {
Expand All @@ -147,27 +160,31 @@ class CanvasForExport extends mxSvgCanvas2D {
w: number,
h: number,
str: string,
align: string,
valign: string,
wrap: string,
overflow: string,
clip: string,
align: AlignValue,
valign: VAlignValue,
wrap: boolean,
overflow: OverflowValue,
clip: boolean,
rotation: number,
dir: string,
dir: TextDirectionValue,
): void {
str = this.computeTruncatedText(str, w);
super.plainText(x, y, w, h, str, align, valign, wrap, overflow, clip, rotation, dir);
}

private computeTruncatedText(str: string, w: number): string {
private computeTruncatedText(str: Element | string, w: number): string {
// Assumes a max character width of 0.5em
if (str == null || this.state.fontSize <= 0) {
return '';
}
// TODO [email protected] migration - manage str when it is an Element (see maxGraph code)
if (str instanceof Element) {
str = str.innerHTML;
}

try {
this.htmlConverter.innerHTML = str;
str = mxUtils.extractTextWithWhitespace(this.htmlConverter.childNodes);
str = domUtils.extractTextWithWhitespace(<Element[]>Array.from(this.htmlConverter.childNodes));

// Workaround for substring breaking double byte UTF
const exp = Math.ceil((2 * w) / this.state.fontSize);
Expand All @@ -192,7 +209,7 @@ class CanvasForExport extends mxSvgCanvas2D {

// Uses result and adds ellipsis if more than 1 char remains
if (result.length < str.length && str.length - result.length > 1) {
str = mxUtils.trim(result.join('')) + '...';
str = stringUtils.trim(result.join('')) + '...';
}
} catch (e) {
console.warn('Error while computing txt label', e);
Expand Down
47 changes: 23 additions & 24 deletions dev/ts/component/ThemedBpmnVisualization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ limitations under the License.

import { BpmnVisualization, FlowKind, ShapeBpmnElementKind, ShapeUtil, StyleConfigurator, StyleDefault } from '../../../src/bpmn-visualization';
import { logStartup } from '../utils/internal-helpers';
import { mxConstants } from '../../../src/component/mxgraph/initializer';

interface Theme {
defaultFillColor: string;
Expand Down Expand Up @@ -139,44 +138,44 @@ export class ThemedBpmnVisualization extends BpmnVisualization {
strokeColor = theme.defaultStrokeColor;
break;
}
const style = styleSheet.styles[kind];
style['fillColor'] = fillColor;
style['strokeColor'] = strokeColor;
const style = styleSheet.styles.get(kind);
style.fillColor = fillColor;
style.strokeColor = strokeColor;
});

// TASK
ShapeUtil.taskKinds().forEach(kind => {
const style = styleSheet.styles[kind];
style['fillColor'] = theme.taskAndCallActivityFillColor;
const style = styleSheet.styles.get(kind);
style.fillColor = theme.taskAndCallActivityFillColor;
});

// CALL ACTIVITY
const callActivityStyle = styleSheet.styles[ShapeBpmnElementKind.CALL_ACTIVITY];
callActivityStyle['fillColor'] = theme.taskAndCallActivityFillColor;
const callActivityStyle = styleSheet.styles.get(ShapeBpmnElementKind.CALL_ACTIVITY);
callActivityStyle.fillColor = theme.taskAndCallActivityFillColor;

// TEXT ANNOTATION
const textAnnotationStyle = styleSheet.styles[ShapeBpmnElementKind.TEXT_ANNOTATION];
textAnnotationStyle['fillColor'] = theme.textAnnotationFillColor ?? StyleDefault.TEXT_ANNOTATION_FILL_COLOR;
const textAnnotationStyle = styleSheet.styles.get(ShapeBpmnElementKind.TEXT_ANNOTATION);
textAnnotationStyle.fillColor = theme.textAnnotationFillColor ?? StyleDefault.TEXT_ANNOTATION_FILL_COLOR;

// POOL
const poolStyle = styleSheet.styles[ShapeBpmnElementKind.POOL];
poolStyle['fillColor'] = theme.poolFillColor;
poolStyle['swimlaneFillColor'] = theme.defaultFillColor;
const poolStyle = styleSheet.styles.get(ShapeBpmnElementKind.POOL);
poolStyle.fillColor = theme.poolFillColor;
poolStyle.swimlaneFillColor = theme.defaultFillColor;

// LANE
const laneStyle = styleSheet.styles[ShapeBpmnElementKind.LANE];
laneStyle['fillColor'] = theme.laneFillColor;
const laneStyle = styleSheet.styles.get(ShapeBpmnElementKind.LANE);
laneStyle.fillColor = theme.laneFillColor;

// DEFAULTS
const defaultVertexStyle = styleSheet.getDefaultVertexStyle();
defaultVertexStyle['fontColor'] = theme.defaultFontColor;
defaultVertexStyle['fillColor'] = theme.defaultFillColor;
defaultVertexStyle['strokeColor'] = theme.defaultStrokeColor;
defaultVertexStyle.fontColor = theme.defaultFontColor;
defaultVertexStyle.fillColor = theme.defaultFillColor;
defaultVertexStyle.strokeColor = theme.defaultStrokeColor;

const defaultEdgeStyle = styleSheet.getDefaultEdgeStyle();
defaultEdgeStyle['fontColor'] = theme.defaultFontColor;
defaultEdgeStyle['fillColor'] = theme.defaultFillColor;
defaultEdgeStyle['strokeColor'] = theme.flowColor ?? theme.defaultStrokeColor;
defaultEdgeStyle.fontColor = theme.defaultFontColor;
defaultEdgeStyle.fillColor = theme.defaultFillColor;
defaultEdgeStyle.strokeColor = theme.flowColor ?? theme.defaultStrokeColor;

// theme configuration completed
return true;
Expand All @@ -188,9 +187,9 @@ export class ThemedBpmnVisualization extends BpmnVisualization {
const stylesheet = this.graph.getStylesheet();

// directly access the 'styles' map to update values. Using stylesheet.getCellStyle returns a copy of the style
const seqFlowStyle = stylesheet.styles[FlowKind.SEQUENCE_FLOW];
seqFlowStyle[mxConstants.STYLE_STROKECOLOR] = color;
seqFlowStyle[mxConstants.STYLE_FILLCOLOR] = color;
const seqFlowStyle = stylesheet.styles.get(FlowKind.SEQUENCE_FLOW);
seqFlowStyle.strokeColor = color;
seqFlowStyle.fillColor = color;

logStartup('Sequence flows style updated');
}
Expand Down
2 changes: 1 addition & 1 deletion dev/ts/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ function collapseBpmnElement(bpmnElementId: string): void {
return;
}
log('Updating model, bpmnElement to collapse:', bpmnElementId);
const model = bpmnVisualization.graph.getModel();
const model = bpmnVisualization.graph.getDataModel();
const cell = model.getCell(bpmnElementId);
if (!cell) {
log('Element not found in the model, do nothing');
Expand Down
Loading
Loading