diff --git a/.github/workflows/check-typescript-projects.yml b/.github/workflows/check-typescript-projects.yml
index 6052b9c..23f0402 100644
--- a/.github/workflows/check-typescript-projects.yml
+++ b/.github/workflows/check-typescript-projects.yml
@@ -19,7 +19,7 @@ on:
- 'projects/**/*'
jobs:
- build_maxgraph_package:
+ build_maxgraph_dev_package:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
@@ -43,12 +43,16 @@ jobs:
build_projects:
runs-on: ubuntu-22.04
- needs: [build_maxgraph_package]
+ needs: [build_maxgraph_dev_package]
strategy:
# don't cancel running jobs even if one fails
fail-fast: false
matrix:
- project: [parcel-ts, rollup-ts, vitejs-ts]
+ project:
+ - lit-ts
+ - parcel-ts
+ - rollup-ts
+ - vitejs-ts
npm-package: ['release', 'development']
defaults:
run:
diff --git a/README.md b/README.md
index 939bd0e..a0f1176 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
Demonstrate how to integrate [maxGraph](https://github.com/maxGraph/maxGraph/) in projects.
+⏩ Find the live demo at https://maxgraph.github.io/maxgraph-integration-examples/
+
## Getting started
### Setup
@@ -18,6 +20,7 @@ If the Node version is not installed, `nvm` will state how to install the requir
### Available projects
+- [TypeScript with Lit](./projects/lit-ts/README.md)
- [TypeScript with Parcel](./projects/parcel-ts/README.md)
- [TypeScript with Rollup](./projects/rollup-ts/README.md)
- [TypeScript with ViteJs](./projects/vitejs-ts/README.md)
@@ -25,6 +28,8 @@ If the Node version is not installed, `nvm` will state how to install the requir
### Use the maxGraph development version
+**Note**: the `maxGraph` development version is tested in a [GitHub Workflow](./.github/workflows/check-typescript-projects.yml) that uses the procedure explained below.
+
Build [maxGraph](https://github.com/maxGraph/maxGraph/) locally:
- from the `maxGraph` project root, run: `npm install`
- then, from the `packages/core` folder, run: `npm pack`
diff --git a/projects/lit-ts/README.md b/projects/lit-ts/README.md
new file mode 100644
index 0000000..df9257f
--- /dev/null
+++ b/projects/lit-ts/README.md
@@ -0,0 +1,18 @@
+# lit-ts
+
+Demonstrate how to integrate maxGraph in a Web Component created with [lit](https://lit.dev/).
+
+The application is built with [Vite](https://vitejs.dev/).
+
+## Setup
+
+From the project root, run `npm install`.
+
+If you want to use the maxGraph development version (built locally), see the README about maxGraph integration.
+
+## Running the project
+
+Run `npm run dev` and go to http://localhost:5173/
+
+If you want to bundle the application, run `npm run build` and then run `npm run preview` to access to a preview of the
+bundle application.
diff --git a/projects/lit-ts/favicon.svg b/projects/lit-ts/favicon.svg
new file mode 100644
index 0000000..20eaec4
--- /dev/null
+++ b/projects/lit-ts/favicon.svg
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/projects/lit-ts/index.html b/projects/lit-ts/index.html
new file mode 100644
index 0000000..cab0f7c
--- /dev/null
+++ b/projects/lit-ts/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ maxGraph Lit integration example
+
+
+
+
+ maxGraph TypeScript example
+ Display a test graph. Activated behaviours:
+
+ Panning: use mouse right button
+ Cells selection with Rubberband: use mouse left button
+
+
+
+
diff --git a/projects/lit-ts/package-lock.json b/projects/lit-ts/package-lock.json
new file mode 100644
index 0000000..535153f
--- /dev/null
+++ b/projects/lit-ts/package-lock.json
@@ -0,0 +1,249 @@
+{
+ "name": "bpmn-visualization-lit-element-ts-vite",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "bpmn-visualization-lit-element-ts-vite",
+ "version": "0.0.0",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@maxgraph/core": "0.2.1",
+ "lit": "~2.7.5"
+ },
+ "devDependencies": {
+ "typescript": "~5.1.6",
+ "vite": "~4.3.9"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.17.19",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@lit-labs/ssr-dom-shim": {
+ "version": "1.1.1",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@lit/reactive-element": {
+ "version": "1.6.2",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.0.0"
+ }
+ },
+ "node_modules/@maxgraph/core": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@maxgraph/core/-/core-0.2.1.tgz",
+ "integrity": "sha512-6dBVcVwNVZr8iEn9pmvyMr66GYL7qGc1oWB1VF70kQqVKlkMSLVKKeQRmEATX5GFlywoxjQ40m8edMyNt5vsPw=="
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.3",
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.17.19",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.17.19",
+ "@esbuild/android-arm64": "0.17.19",
+ "@esbuild/android-x64": "0.17.19",
+ "@esbuild/darwin-arm64": "0.17.19",
+ "@esbuild/darwin-x64": "0.17.19",
+ "@esbuild/freebsd-arm64": "0.17.19",
+ "@esbuild/freebsd-x64": "0.17.19",
+ "@esbuild/linux-arm": "0.17.19",
+ "@esbuild/linux-arm64": "0.17.19",
+ "@esbuild/linux-ia32": "0.17.19",
+ "@esbuild/linux-loong64": "0.17.19",
+ "@esbuild/linux-mips64el": "0.17.19",
+ "@esbuild/linux-ppc64": "0.17.19",
+ "@esbuild/linux-riscv64": "0.17.19",
+ "@esbuild/linux-s390x": "0.17.19",
+ "@esbuild/linux-x64": "0.17.19",
+ "@esbuild/netbsd-x64": "0.17.19",
+ "@esbuild/openbsd-x64": "0.17.19",
+ "@esbuild/sunos-x64": "0.17.19",
+ "@esbuild/win32-arm64": "0.17.19",
+ "@esbuild/win32-ia32": "0.17.19",
+ "@esbuild/win32-x64": "0.17.19"
+ }
+ },
+ "node_modules/lit": {
+ "version": "2.7.5",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit/reactive-element": "^1.6.0",
+ "lit-element": "^3.3.0",
+ "lit-html": "^2.7.0"
+ }
+ },
+ "node_modules/lit-element": {
+ "version": "3.3.2",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.1.0",
+ "@lit/reactive-element": "^1.3.0",
+ "lit-html": "^2.7.0"
+ }
+ },
+ "node_modules/lit-html": {
+ "version": "2.7.4",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.6",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/postcss": {
+ "version": "8.4.24",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.24.0",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
+ "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/vite": {
+ "version": "4.3.9",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.17.5",
+ "postcss": "^8.4.23",
+ "rollup": "^3.21.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/projects/lit-ts/package.json b/projects/lit-ts/package.json
new file mode 100644
index 0000000..2132c24
--- /dev/null
+++ b/projects/lit-ts/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "maxgraph-ts-example-integrating-in-lit",
+ "private": true,
+ "version": "0.0.0",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build --base ./",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@maxgraph/core": "0.2.1",
+ "lit": "~2.7.5"
+ },
+ "devDependencies": {
+ "vite": "~4.3.9",
+ "typescript": "~5.1.6"
+ }
+}
diff --git a/projects/lit-ts/src/custom-shapes.ts b/projects/lit-ts/src/custom-shapes.ts
new file mode 100644
index 0000000..e0fc162
--- /dev/null
+++ b/projects/lit-ts/src/custom-shapes.ts
@@ -0,0 +1,43 @@
+// TODO fully duplicated with other projects
+
+import {AbstractCanvas2D, CellRenderer, type ColorValue, EllipseShape, Rectangle, RectangleShape} from '@maxgraph/core';
+
+export function registerCustomShapes(): void {
+ console.info('Registering custom shapes...');
+ // @ts-ignore TODO fix CellRenderer. Calls to this function are also marked as 'ts-ignore' in CellRenderer
+ CellRenderer.registerShape('customRectangle', CustomRectangleShape);
+ // @ts-ignore
+ CellRenderer.registerShape('customEllipse', CustomEllipseShape);
+ console.info('Custom shapes registered');
+}
+
+class CustomRectangleShape extends RectangleShape {
+
+ constructor(bounds: Rectangle, fill: ColorValue, stroke: ColorValue) {
+ super(bounds, fill, stroke, 3);
+ this.isRounded = true; // force rounded shape
+ }
+
+ paintBackground(c: AbstractCanvas2D, x: number, y: number, w: number, h: number): void {
+ c.setFillColor('Chartreuse');
+ super.paintBackground(c, x, y, w, h);
+ }
+
+ paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
+ c.setStrokeColor('Black');
+ super.paintVertexShape(c, x, y, w, h);
+ }
+
+}
+
+class CustomEllipseShape extends EllipseShape {
+ constructor(bounds: Rectangle, fill: string, stroke: string) {
+ super(bounds, fill, stroke, 5);
+ }
+
+ paintVertexShape(c: AbstractCanvas2D, x: number, y: number, w: number, h: number) {
+ c.setFillColor('Yellow');
+ c.setStrokeColor('Red');
+ super.paintVertexShape(c, x, y, w, h);
+ }
+}
diff --git a/projects/lit-ts/src/index.ts b/projects/lit-ts/src/index.ts
new file mode 100644
index 0000000..14d9440
--- /dev/null
+++ b/projects/lit-ts/src/index.ts
@@ -0,0 +1,49 @@
+import './style.css';
+import {type CellStyle, Graph, InternalEvent, RubberBandHandler} from '@maxgraph/core';
+import {registerCustomShapes} from "./custom-shapes";
+import {html, LitElement} from "lit";
+import { customElement } from "lit/decorators.js";
+
+// TODO mainly duplicated with other projects
+const initializeGraph = (container: HTMLElement) => {
+ // Disables the built-in context menu
+ InternalEvent.disableContextMenu(container);
+
+ const graph = new Graph(container);
+ graph.setPanning(true); // Use mouse right button for panning
+ // WARN: as the maxGraph css files are not available in the npm package (at least for now), dedicated CSS class must be defined in style.css
+ new RubberBandHandler(graph); // Enables rubber band selection
+
+ // shapes and styles
+ registerCustomShapes();
+ // @ts-ignore TODO fix TS2532: Object is possibly 'undefined'.
+ graph.getStylesheet().getDefaultEdgeStyle().edgeStyle = 'orthogonalEdgeStyle'; // TODO use constants.EDGESTYLE instead of 'orthogonalEdgeStyle'
+
+ // Gets the default parent for inserting new cells. This
+ // is normally the first child of the root (ie. layer 0).
+ const parent = graph.getDefaultParent();
+
+ // Adds cells to the model in a single step
+ graph.batchUpdate(() => {
+ const vertex01 = graph.insertVertex(parent, null, 'a regular rectangle', 10, 10, 100, 100);
+ const vertex02 = graph.insertVertex(parent, null, 'a regular ellipse', 350, 90, 50, 50, {shape: 'ellipse', fillColor: 'orange'});
+ graph.insertEdge(parent, null, 'a regular edge', vertex01, vertex02);
+
+ // insert vertices using custom shapes
+ // TODO type issue in CellStyle type, shape should allow string to manage custom implementation
+ const vertex11 = graph.insertVertex(parent, null, 'a custom rectangle', 20, 200, 100, 100, /**/{shape: 'customRectangle'});
+ const vertex12 = graph.insertVertex(parent, null, 'a custom ellipse', 150, 350, 70, 70, /**/{shape: 'customEllipse'});
+ graph.insertEdge(parent, null, 'another edge', vertex11, vertex12);
+ });
+};
+
+@customElement("maxgraph-graph")
+export class GraphElement extends LitElement {
+ firstUpdated(): void {
+ initializeGraph(this.renderRoot.querySelector("#graph-container"));
+ }
+
+ render() {
+ return html`
`;
+ }
+}
diff --git a/projects/lit-ts/src/style.css b/projects/lit-ts/src/style.css
new file mode 100644
index 0000000..1a5bc9e
--- /dev/null
+++ b/projects/lit-ts/src/style.css
@@ -0,0 +1,37 @@
+/*TODO fully duplicated with other projects*/
+
+body {
+ font-family: Avenir, Helvetica, Arial, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ color: #2c3e50;
+}
+
+h1 {
+ text-align: center;
+ margin-top: 3rem;
+}
+
+footer {
+ position: absolute;
+ bottom: 1rem;
+ right: 1rem;
+ z-index: 1;
+ font-weight: 800;
+}
+
+#graph-container {
+ border: #B0B0B0 1px solid;
+ height: 70vh;
+ overflow: hidden;
+}
+
+/* For rubber band selection as we don't have access to the maxGraph CSS files in the project */
+div.mxRubberband {
+ position: absolute;
+ overflow: hidden;
+ border-style: solid;
+ border-width: 2px;
+ border-color: #b18426;
+ background: #db9b0b;
+}
diff --git a/projects/lit-ts/src/vite-env.d.ts b/projects/lit-ts/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/projects/lit-ts/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/projects/lit-ts/tsconfig.json b/projects/lit-ts/tsconfig.json
new file mode 100644
index 0000000..03048da
--- /dev/null
+++ b/projects/lit-ts/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "module": "esnext",
+ "lib": ["es2017", "dom", "dom.iterable"],
+ "outDir": "./build",
+ "rootDir": "./src",
+ "strict": true,
+ "declaration": false,
+ "noEmit": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true,
+ "moduleResolution": "node",
+ "allowSyntheticDefaultImports": true,
+ "experimentalDecorators": true,
+ "forceConsistentCasingInFileNames": true
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": []
+}