From a025a754a245e702d3acaecda53504bcceab9170 Mon Sep 17 00:00:00 2001 From: Guillaume Fontorbe Date: Fri, 2 Feb 2024 15:08:57 +0100 Subject: [PATCH 1/3] Flowchart library Signed-off-by: Guillaume Fontorbe --- examples/flowchart/css/diagram.css | 1 + examples/flowchart/src/data.ts | 41 +- examples/flowchart/src/di.config.ts | 36 +- examples/flowchart/src/views.tsx | 118 ---- examples/package.json | 1 + packages/sprotty-library/.gitignore | 1 + packages/sprotty-library/package.json | 49 ++ .../src/flowchart/container.ts | 78 +++ .../sprotty-library/src/flowchart/index.ts | 19 + .../sprotty-library/src/flowchart/model.ts | 93 +++ .../sprotty-library/src/flowchart/views.tsx | 624 ++++++++++++++++++ packages/sprotty-library/src/index.ts | 17 + packages/sprotty-library/tsconfig.json | 19 + packages/sprotty-library/tsconfig.src.json | 17 + tsconfig.build.json | 1 + 15 files changed, 947 insertions(+), 168 deletions(-) delete mode 100644 examples/flowchart/src/views.tsx create mode 100644 packages/sprotty-library/.gitignore create mode 100644 packages/sprotty-library/package.json create mode 100644 packages/sprotty-library/src/flowchart/container.ts create mode 100644 packages/sprotty-library/src/flowchart/index.ts create mode 100644 packages/sprotty-library/src/flowchart/model.ts create mode 100644 packages/sprotty-library/src/flowchart/views.tsx create mode 100644 packages/sprotty-library/src/index.ts create mode 100644 packages/sprotty-library/tsconfig.json create mode 100644 packages/sprotty-library/tsconfig.src.json diff --git a/examples/flowchart/css/diagram.css b/examples/flowchart/css/diagram.css index 7751e8d..acd83a1 100644 --- a/examples/flowchart/css/diagram.css +++ b/examples/flowchart/css/diagram.css @@ -34,6 +34,7 @@ .sprotty-node { stroke: var(--black); stroke-width: var(--stroke-normal); + fill: var(--white); } .sprotty-node.terminal { diff --git a/examples/flowchart/src/data.ts b/examples/flowchart/src/data.ts index 14f5eac..82aee1b 100644 --- a/examples/flowchart/src/data.ts +++ b/examples/flowchart/src/data.ts @@ -14,13 +14,18 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ +import { + Decision, + Process, + Terminal +} from "sprotty-library"; import { SEdge, SGraph, SLabel, SModelRoot, SNode } from "sprotty-protocol"; export function initializeModel(): SModelRoot { const nodes: SNode[] = []; const edges: SEdge[] = []; - const node0: SNode = { + const node0: Terminal = { id: '0', type: 'node:terminal', position: { x: 150, y: 10 }, @@ -42,7 +47,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node0); - const node1: SNode = { + const node1: Process = { id: '1', type: 'node:process', position: { x: 109.15, y: 153.9 }, @@ -63,7 +68,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node1); - const node2: SNode = { + const node2: Decision = { id: '2', type: 'node:decision', position: { x: 71.4, y: 297.8 }, @@ -86,7 +91,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node2); - const node3: SNode = { + const node3: Process = { id: '3', type: 'node:process', position: { x: 102.35, y: 517.8 }, @@ -107,7 +112,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node3); - const node4: SNode = { + const node4: Decision = { id: '4', type: 'node:decision', position: { x: 411.1, y: 297.8 }, @@ -130,10 +135,10 @@ export function initializeModel(): SModelRoot { }; nodes.push(node4); - const node5: SNode = { + const node5: Process = { id: '5', type: 'node:process', - position: { x: 395.7, y: 517.8}, + position: { x: 395.7, y: 517.8 }, children: [{ id: '5_label', text: 'Wait for available nurse', @@ -152,7 +157,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node5); - const node6: SNode = { + const node6: Process = { id: '6', type: 'node:process', position: { x: 722.3, y: 335.85 }, @@ -174,7 +179,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node6); - const node7: SNode = { + const node7: Decision = { id: '7', type: 'node:decision', position: { x: 736, y: 479.75 }, @@ -197,10 +202,10 @@ export function initializeModel(): SModelRoot { }; nodes.push(node7); - const node8: SNode = { + const node8: Process = { id: '8', type: 'node:process', - position: { x: 720.5, y: 699.75}, + position: { x: 720.5, y: 699.75 }, children: [{ id: '8_label', text: 'Wait for available doctor', @@ -219,7 +224,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node8); - const node9: SNode = { + const node9: Process = { id: '9', type: 'node:process', position: { x: 1055.7, y: 517.8 }, @@ -241,7 +246,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node9); - const node10: SNode = { + const node10: Decision = { id: '10', type: 'node:decision', position: { x: 1074.9, y: 661.7 }, @@ -264,7 +269,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node10); - const node11: SNode = { + const node11: Decision = { id: '11', type: 'node:decision', position: { x: 1065.75, y: 881.7 }, @@ -287,7 +292,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node11); - const node12: SNode = { + const node12: Process = { id: '12', type: 'node:process', position: { x: 1099.7, y: 1101.7 }, @@ -309,7 +314,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node12); - const node13: SNode = { + const node13: Terminal = { id: '13', type: 'node:terminal', position: { x: 1143.25, y: 1245.6 }, @@ -331,7 +336,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node13); - const node14: SNode = { + const node14: Process = { id: '14', type: 'node:process', position: { x: 1385.4, y: 699.75 }, @@ -353,7 +358,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node14); - const node15: SNode = { + const node15: Process = { id: '15', type: 'node:process', position: { x: 1386.1, y: 919.75 }, diff --git a/examples/flowchart/src/di.config.ts b/examples/flowchart/src/di.config.ts index 4221e8a..528de67 100644 --- a/examples/flowchart/src/di.config.ts +++ b/examples/flowchart/src/di.config.ts @@ -16,54 +16,25 @@ import { Container, ContainerModule } from "inversify"; import { - CircularNodeView, ConsoleLogger, LogLevel, - SCompartmentImpl, - SCompartmentView, - SEdgeImpl, - SGraphImpl, - SGraphView, - SLabelImpl, - SLabelView, - SNodeImpl, - SPortImpl, - SRoutingHandleImpl, - SRoutingHandleView, TYPES, - configureModelElement, configureViewerOptions, - editLabelFeature, - loadDefaultModules, - moveFeature, - selectFeature + loadDefaultModules } from "sprotty"; +import { flowchartModule } from 'sprotty-library'; import { FlowchartModelSource } from "./model-source"; -import { DecisionNodeView, EdgeLabel, EdgeWithArrow, ProcessNodeView, TerminalNodeView } from "./views"; export default (containerId: string) => { require('../css/diagram.css'); - const flowchartModule = new ContainerModule((bind, unbind, isBound, rebind) => { + const module = new ContainerModule((bind, unbind, isBound, rebind) => { bind(TYPES.ModelSource).to(FlowchartModelSource).inSingletonScope(); rebind(TYPES.ILogger).to(ConsoleLogger).inSingletonScope(); rebind(TYPES.LogLevel).toConstantValue(LogLevel.log); const context = { bind, unbind, isBound, rebind }; - configureModelElement(context, 'graph', SGraphImpl, SGraphView); - configureModelElement(context, 'node:terminal', SNodeImpl, TerminalNodeView); - configureModelElement(context, 'node:process', SNodeImpl, ProcessNodeView); - configureModelElement(context, 'node:decision', SNodeImpl, DecisionNodeView); - configureModelElement(context, 'label', SLabelImpl, SLabelView, {enable: [editLabelFeature]}); - configureModelElement(context, 'label:edge', SLabelImpl, EdgeLabel, {enable: [moveFeature, selectFeature, editLabelFeature]}); - configureModelElement(context, 'edge', SEdgeImpl, EdgeWithArrow); - configureModelElement(context, 'routing-point', SRoutingHandleImpl, SRoutingHandleView); - configureModelElement(context, 'volatile-routing-point', SRoutingHandleImpl, SRoutingHandleView); - configureModelElement(context, 'port:in', SPortImpl, CircularNodeView); - configureModelElement(context, 'port:out', SPortImpl, CircularNodeView); - configureModelElement(context, 'compartment', SCompartmentImpl, SCompartmentView); - configureViewerOptions(context, { needsClientLayout: true, }); @@ -72,5 +43,6 @@ export default (containerId: string) => { const container = new Container(); loadDefaultModules(container); container.load(flowchartModule); + container.load(module); return container; }; diff --git a/examples/flowchart/src/views.tsx b/examples/flowchart/src/views.tsx deleted file mode 100644 index 8740763..0000000 --- a/examples/flowchart/src/views.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2024 TypeFox and others. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the Eclipse - * Public License v. 2.0 are satisfied: GNU General Public License, version 2 - * with the GNU Classpath Exception which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - ********************************************************************************/ -/** @jsx svg */ -import { PolylineEdgeView, SEdgeImpl, SLabelImpl, isEdgeLayoutable, setAttr, svg } from 'sprotty'; - -import { injectable } from "inversify"; -import { VNode } from "snabbdom"; -import { IViewArgs, RenderingContext, SShapeElementImpl, ShapeView } from "sprotty"; -import { Hoverable, Point, Selectable, getSubType, toDegrees } from "sprotty-protocol"; - -@injectable() -export class TerminalNodeView extends ShapeView { - override render(node: Readonly, context: RenderingContext, args?: IViewArgs): VNode | undefined { - if (!this.isVisible(node, context)) { - return undefined; - } - - return - - {/* {label.text} */} - {context.renderChildren(node)} - ; - } -} - -@injectable() -export class ProcessNodeView extends ShapeView { - override render(node: Readonly, context: RenderingContext, args?: IViewArgs): VNode | undefined { - if (!this.isVisible(node, context)) { - return undefined; - } - - return - - {context.renderChildren(node)} - ; - } -} - -@injectable() -export class DecisionNodeView extends ShapeView { - override render(node: Readonly, context: RenderingContext, args?: IViewArgs): VNode | undefined { - const width = node.size.width; - const height = node.size.height; - - if (!this.isVisible(node, context)) { - return undefined; - } - - return - - {context.renderChildren(node)} - ; - } -} - -@injectable() -export class EdgeLabel extends ShapeView { - override render(label: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { - if (!isEdgeLayoutable(label) && !this.isVisible(label, context)) { - return undefined; - } - const vnode = {label.text}; - const subType = getSubType(label); - if (subType) { - setAttr(vnode, 'class', subType); - } - - return - - {vnode} - ; - } -} - -@injectable() -export class EdgeWithArrow extends PolylineEdgeView { - - protected override renderAdditionals(edge: SEdgeImpl, segments: Point[], context: RenderingContext): VNode[] { - const p1 = segments[segments.length - 1]; - const p2 = segments[segments.length - 2]; - - return [ - - ]; - } - - angle(x0: Point, x1: Point): number { - return toDegrees(Math.atan2(x1.y - x0.y, x1.x - x0.x)); - } -} diff --git a/examples/package.json b/examples/package.json index 644c1f1..1282d8c 100644 --- a/examples/package.json +++ b/examples/package.json @@ -9,6 +9,7 @@ "reflect-metadata": "~0.1.14", "sprotty": "^1.1.0", "sprotty-elk": "^1.1.0", + "sprotty-library": "^0.0.1", "ws": "^8.14.2" }, "devDependencies": { diff --git a/packages/sprotty-library/.gitignore b/packages/sprotty-library/.gitignore new file mode 100644 index 0000000..12c18d4 --- /dev/null +++ b/packages/sprotty-library/.gitignore @@ -0,0 +1 @@ +/lib/ diff --git a/packages/sprotty-library/package.json b/packages/sprotty-library/package.json new file mode 100644 index 0000000..46d16c3 --- /dev/null +++ b/packages/sprotty-library/package.json @@ -0,0 +1,49 @@ +{ + "name": "sprotty-library", + "version": "0.0.1", + "description": "Views and elements library for Sprotty", + "license": "(EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0)", + "keywords": [ + "eclipse", + "graphics", + "diagram", + "modeling", + "visualization", + "svg" + ], + "homepage": "https://github.com/eclipse-sprotty/sprotty", + "bugs": "https://github.com/eclipse-sprotty/sprotty/issues", + "author": { + "name": "Eclipse Sprotty" + }, + "peerDependencies": { + "inversify": "~6.0.2" + }, + "dependencies": { + "sprotty": "^1.1.0", + "sprotty-protocol": "^1.1.0" + }, + "devDependencies": {}, + "repository": { + "type": "git", + "url": "https://github.com/eclipse-sprotty/sprotty", + "directory": "packages/sprotty-library" + }, + "volta": { + "node": "18.19.0", + "yarn": "1.22.21" + }, + "scripts": { + "clean": "shx rm -fr lib artifacts *.tsbuildinfo", + "build": "tsc", + "watch": "tsc --watch", + "test": "vitest run --config ../../vite.config.ts" + }, + "files": [ + "lib", + "css", + "src" + ], + "main": "lib/index", + "types": "lib/index" +} \ No newline at end of file diff --git a/packages/sprotty-library/src/flowchart/container.ts b/packages/sprotty-library/src/flowchart/container.ts new file mode 100644 index 0000000..7f9003b --- /dev/null +++ b/packages/sprotty-library/src/flowchart/container.ts @@ -0,0 +1,78 @@ +/******************************************************************************** + * Copyright (c) 2024 TypeFox and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the Eclipse + * Public License v. 2.0 are satisfied: GNU General Public License, version 2 + * with the GNU Classpath Exception which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + ********************************************************************************/ + +import { ContainerModule } from "inversify"; +import { SEdgeImpl, SGraphImpl, SGraphView, SLabelImpl, SLabelView, SNodeImpl, SRoutingHandleImpl, SRoutingHandleView, configureModelElement } from "sprotty"; +import { + AlternateProcessNodeView, + CommentNodeView, + DataNodeView, + DatabaseNodeView, + DecisionNodeView, + DelayNodeView, + DisplayNodeView, + DocumentNodeView, + EdgeLabelView, + EdgeWithArrow, + InputOutputNodeView, + ManualInputNodeView, + ManualOperationNodeView, + MultiDocumentNodeView, + OffPageConnectorNodeView, + OnPageConnectorNodeView, + PredefinedProcessNodeView, + PreparationNodeView, + ProcessNodeView, + TerminalNodeView +} from "./views.js"; + +export const flowchartModule = new ContainerModule((bind, unbind, isBound, rebind) => { + + const context = { bind, unbind, isBound, rebind }; + + // Register graph + configureModelElement(context, 'graph', SGraphImpl, SGraphView); + + // Register nodes + configureModelElement(context, 'node:terminal', SNodeImpl, TerminalNodeView); + configureModelElement(context, 'node:process', SNodeImpl, ProcessNodeView); + configureModelElement(context, 'node:decision', SNodeImpl, DecisionNodeView); + configureModelElement(context, 'node:input', SNodeImpl, InputOutputNodeView); + configureModelElement(context, 'node:output', SNodeImpl, InputOutputNodeView); + configureModelElement(context, 'node:comment', SNodeImpl, CommentNodeView); + configureModelElement(context, 'node:predefined-process', SNodeImpl, PredefinedProcessNodeView); + configureModelElement(context, 'node:on-page-connector', SNodeImpl, OnPageConnectorNodeView); + configureModelElement(context, 'node:off-page-connector', SNodeImpl, OffPageConnectorNodeView); + configureModelElement(context, 'node:delay', SNodeImpl, DelayNodeView); + configureModelElement(context, 'node:alternate-process', SNodeImpl, AlternateProcessNodeView); + configureModelElement(context, 'node:data', SNodeImpl, DataNodeView); + configureModelElement(context, 'node:document', SNodeImpl, DocumentNodeView); + configureModelElement(context, 'node:multi-document', SNodeImpl, MultiDocumentNodeView); + configureModelElement(context, 'node:preparation', SNodeImpl, PreparationNodeView); + configureModelElement(context, 'node:display', SNodeImpl, DisplayNodeView); + configureModelElement(context, 'node:manual-input', SNodeImpl, ManualInputNodeView); + configureModelElement(context, 'node:manual-operation', SNodeImpl, ManualOperationNodeView); + configureModelElement(context, 'node:database', SNodeImpl, DatabaseNodeView); + + // Register labels + configureModelElement(context, 'label', SLabelImpl, SLabelView); + configureModelElement(context, 'label:edge', SLabelImpl, EdgeLabelView); + + // Register edges + configureModelElement(context, 'edge', SEdgeImpl, EdgeWithArrow); + configureModelElement(context, 'routing-point', SRoutingHandleImpl, SRoutingHandleView); + configureModelElement(context, 'volatile-routing-point', SRoutingHandleImpl, SRoutingHandleView); +}); diff --git a/packages/sprotty-library/src/flowchart/index.ts b/packages/sprotty-library/src/flowchart/index.ts new file mode 100644 index 0000000..00a892d --- /dev/null +++ b/packages/sprotty-library/src/flowchart/index.ts @@ -0,0 +1,19 @@ +/******************************************************************************** + * Copyright (c) 2024 TypeFox and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the Eclipse + * Public License v. 2.0 are satisfied: GNU General Public License, version 2 + * with the GNU Classpath Exception which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + ********************************************************************************/ + +export * from './container'; +export * from './model'; +export * from './views'; diff --git a/packages/sprotty-library/src/flowchart/model.ts b/packages/sprotty-library/src/flowchart/model.ts new file mode 100644 index 0000000..47b73d7 --- /dev/null +++ b/packages/sprotty-library/src/flowchart/model.ts @@ -0,0 +1,93 @@ +/******************************************************************************** + * Copyright (c) 2024 TypeFox and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the Eclipse + * Public License v. 2.0 are satisfied: GNU General Public License, version 2 + * with the GNU Classpath Exception which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + ********************************************************************************/ + +import { SNode } from "sprotty-protocol"; + +export interface Terminal extends SNode { + type: 'node:terminal' +} + +export interface Process extends SNode { + type: 'node:process' +} + +export interface Decision extends SNode { + type: 'node:decision' +} + +export interface Input extends SNode { + type: 'node:input' +} + +export interface Output extends SNode { + type: 'node:output' +} + +export interface Comment extends SNode { + type: 'node:comment' +} + +export interface PredefinedProcess extends SNode { + type: 'node:predefined-process' +} + +export interface OnPageConnector extends SNode { + type: 'node:on-page-connector' +} + +export interface OffPageConnector extends SNode { + type: 'node:off-page-connector' +} + +export interface Delay extends SNode { + type: 'node:delay' +} + +export interface AlternateProcess extends SNode { + type: 'node:alternate-process' +} + +export interface Data extends SNode { + type: 'node:data' +} + +export interface Document extends SNode { + type: 'node:document' +} + +export interface MultiDocument extends SNode { + type: 'node:multi-document' +} + +export interface Preparation extends SNode { + type: 'node:preparation' +} + +export interface Display extends SNode { + type: 'node:display' +} + +export interface ManualInput extends SNode { + type: 'node:manual-input' +} + +export interface ManualOperation extends SNode { + type: 'node:manual-operation' +} + +export interface Database extends SNode { + type: 'node:database' +} diff --git a/packages/sprotty-library/src/flowchart/views.tsx b/packages/sprotty-library/src/flowchart/views.tsx new file mode 100644 index 0000000..fd08699 --- /dev/null +++ b/packages/sprotty-library/src/flowchart/views.tsx @@ -0,0 +1,624 @@ +/******************************************************************************** + * Copyright (c) 2024 TypeFox and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the Eclipse + * Public License v. 2.0 are satisfied: GNU General Public License, version 2 + * with the GNU Classpath Exception which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + ********************************************************************************/ + +/** @jsx svg */ +import { injectable } from "inversify"; +import { VNode } from "snabbdom"; +import { IViewArgs, PolylineEdgeView, RenderingContext, SEdgeImpl, SLabelImpl, SShapeElementImpl, ShapeView, isEdgeLayoutable, setAttr, svg } from "sprotty"; +import { Hoverable, Point, Selectable, getSubType, toDegrees } from "sprotty-protocol"; + +@injectable() +export class TerminalNodeView extends ShapeView { + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M${node.size.height / 2} 0 + A${node.size.height / 2} ${node.size.height / 2} 0 0 0 ${node.size.height / 2} ${node.size.height} + H${node.size.width - node.size.height / 2} + A${node.size.height / 2} ${node.size.height / 2} 0 0 0 ${node.size.width - node.size.height / 2} 0 + Z`; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class ProcessNodeView extends ShapeView { + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class DecisionNodeView extends ShapeView { + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M${node.size.width / 2} 0 + L${node.size.width} ${node.size.height / 2} + L${node.size.width / 2} ${node.size.height} + L0 ${node.size.height / 2} + Z`; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class InputOutputNodeView extends ShapeView { + protected offset = 10; + protected skew = -10; + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + const transform = `skewX(${this.skew})`; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class CommentNodeView extends ShapeView { + protected offset = 10; + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M0 ${node.size.height / 2} + H${this.offset} + M${this.offset * 2} 0 + H${this.offset} + V${node.size.height} + H${this.offset * 2} + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class PredefinedProcessNodeView extends ShapeView { + protected sideWidth = 20; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M0 0 + H${node.size.width} + V${node.size.height} + H0 + V0 + M${this.sideWidth} 0 + V${node.size.height} + M${node.size.width - this.sideWidth} 0 + V${node.size.height} + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class OnPageConnectorNodeView extends ShapeView { + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class OffPageConnectorNodeView extends ShapeView { + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M0 0 + H${node.size.width} + V${node.size.height / 2} + L${node.size.width / 2} ${node.size.height} + L0 ${node.size.height / 2} + Z`; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class DelayNodeView extends ShapeView { + protected radius = 10; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M${this.radius} 0 + H${node.size.width - node.size.height / 2} + A${node.size.height / 2} ${node.size.height / 2} 0 0 1 ${node.size.width - node.size.height / 2} ${node.size.height} + H${this.radius} + A${this.radius} ${this.radius} 0 0 1 ${0} ${node.size.height - this.radius} + V${this.radius} + A${this.radius} ${this.radius} 0 0 1 ${this.radius} 0 + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class AlternateProcessNodeView extends ShapeView { + protected radius = 10; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!this.isVisible(node, context)) { + return undefined; + } + const path = ` + M${this.radius} 0 + H${node.size.width - this.radius} + A${this.radius} ${this.radius} 0 0 1 ${node.size.width} ${this.radius} + V${node.size.height - this.radius} + A${this.radius} ${this.radius} 0 0 1 ${node.size.width - this.radius} ${node.size.height} + H${this.radius} + A${this.radius} ${this.radius} 0 0 1 ${0} ${node.size.height - this.radius} + V${this.radius} + A${this.radius} ${this.radius} 0 0 1 ${this.radius} 0 + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class DataNodeView extends ShapeView { + protected radius = 10; + protected skew = -10; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M${this.radius} 0 + H${node.size.width - this.radius} + A${this.radius} ${this.radius} 0 0 1 ${node.size.width} ${this.radius} + V${node.size.height - this.radius} + A${this.radius} ${this.radius} 0 0 1 ${node.size.width - this.radius} ${node.size.height} + H${this.radius} + A${this.radius} ${this.radius} 0 0 1 ${0} ${node.size.height - this.radius} + V${this.radius} + A${this.radius} ${this.radius} 0 0 1 ${this.radius} 0 + `; + + const transform = `skewX(${this.skew})`; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class DocumentNodeView extends ShapeView { + protected curvature = 30; + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M0 0 + H${node.size.width} + V${node.size.height} + C ${node.size.width / 2} ${node.size.height - this.curvature}, ${node.size.width / 2} ${node.size.height + this.curvature}, 0 ${node.size.height} + Z + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class MultiDocumentNodeView extends ShapeView { + protected curvature = 30; + protected radius = 10; + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M ${this.radius} 0 + H${node.size.width - this.radius} + A${this.radius} ${this.radius} 0 0 1 ${node.size.width} ${this.radius} + V${node.size.height} + C ${node.size.width / 2} ${node.size.height - this.curvature}, ${node.size.width / 2} ${node.size.height + this.curvature}, 0 ${node.size.height} + V${this.radius} + A${this.radius} ${this.radius} 0 0 1 ${this.radius} 0 + M${this.radius} 0 + A${this.radius} ${this.radius} 0 0 1 ${this.radius * 2} ${-this.radius} + H${node.size.width} + A${this.radius} ${this.radius} 0 0 1 ${node.size.width + this.radius} ${0} + V${node.size.height - this.radius} + L${node.size.width} ${node.size.height - this.radius * 1.3} + M${this.radius * 2} ${-this.radius} + A${this.radius} ${this.radius} 0 0 1 ${this.radius * 3} ${-this.radius * 2} + H${node.size.width + this.radius} + A${this.radius} ${this.radius} 0 0 1 ${node.size.width + this.radius * 2} ${-this.radius} + V${node.size.height - this.radius * 2} + L${node.size.width + this.radius} ${node.size.height - this.radius * 2.3} + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class PreparationNodeView extends ShapeView { + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M0 ${node.size.height / 2} + L${node.size.height / 2} 0 + H${node.size.width - node.size.height / 2} + L${node.size.width} ${node.size.height / 2} + L${node.size.width - node.size.height / 2} ${node.size.height} + H${node.size.height / 2} + L0 ${node.size.height / 2} + Z + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class DisplayNodeView extends ShapeView { + protected offset = 50; + protected radius = 25; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M0 ${node.size.height / 2} + C ${this.offset * 0.4} ${node.size.height / 2 * 0.3}, ${this.offset * 0.4} ${node.size.height / 2 * 0.2}, ${this.offset} 0 + H${node.size.width - this.radius} + A${this.radius} ${node.size.height / 2} 0 0 1 ${node.size.width - this.radius} ${node.size.height} + H${this.offset} + C ${this.offset * 0.4} ${node.size.height / 2 + node.size.height / 2 * 0.8}, + ${this.offset * 0.4} ${node.size.height / 2 + node.size.height / 2 * 0.6}, 0 ${node.size.height / 2} + Z + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class ManualInputNodeView extends ShapeView { + protected offset = 30; + protected radius = 10; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M ${this.radius} 0 + L ${node.size.width - this.radius} ${-this.offset} + A ${this.radius} ${this.radius} 0 0 1 ${node.size.width} ${-this.offset + this.radius} + V ${node.size.height - this.radius} + A ${this.radius} ${this.radius} 0 0 1 ${node.size.width - this.radius} ${node.size.height} + H ${this.radius} + A ${this.radius} ${this.radius} 0 0 1 0 ${node.size.height - this.radius} + V ${this.radius} + A ${this.radius} ${this.radius} 0 0 1 ${this.radius} 0 + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class ManualOperationNodeView extends ShapeView { + protected offset = 15; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M 0 0 + H ${node.size.width} + L ${node.size.width - this.offset} ${node.size.height} + H ${this.offset} + Z + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class DatabaseNodeView extends ShapeView { + protected radius = 10; + + override render(node: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + + if (!this.isVisible(node, context)) { + return undefined; + } + + const path = ` + M 0 0 + A${node.size.width / 2} ${this.radius} 0 0 0 ${node.size.width} 0 + A${node.size.width / 2} ${this.radius} 0 0 0 0 0 + V${node.size.height} + A${node.size.width / 2} ${this.radius} 0 0 0 ${node.size.width} ${node.size.height} + V0 + `; + + return + + {context.renderChildren(node)} + ; + } +} + +@injectable() +export class EdgeLabelView extends ShapeView { + override render(label: Readonly, context: RenderingContext, args?: IViewArgs | undefined): VNode | undefined { + if (!isEdgeLayoutable(label) && !this.isVisible(label, context)) { + return undefined; + } + const vnode = {label.text}; + const subType = getSubType(label); + if (subType) { + setAttr(vnode, 'class', subType); + } + + return + + {vnode} + ; + } +} + +@injectable() +export class EdgeWithArrow extends PolylineEdgeView { + protected override renderAdditionals(edge: SEdgeImpl, segments: Point[], context: RenderingContext): VNode[] { + const p1 = segments[segments.length - 1]; + const p2 = segments[segments.length - 2]; + + return [ + + ]; + } + + angle(x0: Point, x1: Point): number { + return toDegrees(Math.atan2(x1.y - x0.y, x1.x - x0.x)); + } +} diff --git a/packages/sprotty-library/src/index.ts b/packages/sprotty-library/src/index.ts new file mode 100644 index 0000000..0a73f78 --- /dev/null +++ b/packages/sprotty-library/src/index.ts @@ -0,0 +1,17 @@ +/******************************************************************************** + * Copyright (c) 2024 TypeFox and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the Eclipse + * Public License v. 2.0 are satisfied: GNU General Public License, version 2 + * with the GNU Classpath Exception which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + ********************************************************************************/ + +export * from './flowchart'; diff --git a/packages/sprotty-library/tsconfig.json b/packages/sprotty-library/tsconfig.json new file mode 100644 index 0000000..0f0c8c9 --- /dev/null +++ b/packages/sprotty-library/tsconfig.json @@ -0,0 +1,19 @@ +// this file is required for VSCode to work properly +{ + "extends": "./tsconfig.src.json", + "compilerOptions": { + "noEmit": true, + "rootDir": ".", + "jsx": "react" + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "lib", + "node_modules" + ], + "references": [ + { "path": "../sprotty-protocol/tsconfig.src.json" } +], +} diff --git a/packages/sprotty-library/tsconfig.src.json b/packages/sprotty-library/tsconfig.src.json new file mode 100644 index 0000000..4a22a15 --- /dev/null +++ b/packages/sprotty-library/tsconfig.src.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib" + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "**/*.spec.ts", + "**/*.spec.tsx", + "lib", + "node_modules" + ], +} \ No newline at end of file diff --git a/tsconfig.build.json b/tsconfig.build.json index 3148f8d..390a7e6 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -8,6 +8,7 @@ { "path": "./packages/sprotty-elk/tsconfig.src.json" }, { "path": "./packages/sprotty-elk/tsconfig.test.json" }, { "path": "./packages/generator-sprotty/tsconfig.json" }, + { "path": "./packages/sprotty-library/tsconfig.src.json" }, { "path": "./examples/tsconfig.json" } ] } \ No newline at end of file From b91587f349f14eb36049418a7b9903875570f272 Mon Sep 17 00:00:00 2001 From: Guillaume Fontorbe Date: Wed, 21 Feb 2024 11:45:27 +0100 Subject: [PATCH 2/3] Comments by spoenemann Signed-off-by: Guillaume Fontorbe --- examples/flowchart/src/data.ts | 38 ++++++++++++-------------- examples/flowchart/src/di.config.ts | 8 +++--- examples/flowchart/src/model-source.ts | 27 ------------------ examples/flowchart/src/standalone.ts | 3 +- packages/sprotty-library/package.json | 6 +--- packages/sprotty-library/src/index.ts | 3 +- 6 files changed, 26 insertions(+), 59 deletions(-) delete mode 100644 examples/flowchart/src/model-source.ts diff --git a/examples/flowchart/src/data.ts b/examples/flowchart/src/data.ts index 82aee1b..8d1b6f1 100644 --- a/examples/flowchart/src/data.ts +++ b/examples/flowchart/src/data.ts @@ -14,18 +14,14 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { - Decision, - Process, - Terminal -} from "sprotty-library"; +import { Flowchart } from "sprotty-library"; import { SEdge, SGraph, SLabel, SModelRoot, SNode } from "sprotty-protocol"; export function initializeModel(): SModelRoot { const nodes: SNode[] = []; const edges: SEdge[] = []; - const node0: Terminal = { + const node0: Flowchart.Terminal = { id: '0', type: 'node:terminal', position: { x: 150, y: 10 }, @@ -47,7 +43,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node0); - const node1: Process = { + const node1: Flowchart.Process = { id: '1', type: 'node:process', position: { x: 109.15, y: 153.9 }, @@ -68,7 +64,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node1); - const node2: Decision = { + const node2: Flowchart.Decision = { id: '2', type: 'node:decision', position: { x: 71.4, y: 297.8 }, @@ -91,7 +87,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node2); - const node3: Process = { + const node3: Flowchart.Process = { id: '3', type: 'node:process', position: { x: 102.35, y: 517.8 }, @@ -112,7 +108,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node3); - const node4: Decision = { + const node4: Flowchart.Decision = { id: '4', type: 'node:decision', position: { x: 411.1, y: 297.8 }, @@ -135,7 +131,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node4); - const node5: Process = { + const node5: Flowchart.Process = { id: '5', type: 'node:process', position: { x: 395.7, y: 517.8 }, @@ -157,7 +153,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node5); - const node6: Process = { + const node6: Flowchart.Process = { id: '6', type: 'node:process', position: { x: 722.3, y: 335.85 }, @@ -179,7 +175,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node6); - const node7: Decision = { + const node7: Flowchart.Decision = { id: '7', type: 'node:decision', position: { x: 736, y: 479.75 }, @@ -202,7 +198,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node7); - const node8: Process = { + const node8: Flowchart.Process = { id: '8', type: 'node:process', position: { x: 720.5, y: 699.75 }, @@ -224,7 +220,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node8); - const node9: Process = { + const node9: Flowchart.Process = { id: '9', type: 'node:process', position: { x: 1055.7, y: 517.8 }, @@ -246,7 +242,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node9); - const node10: Decision = { + const node10: Flowchart.Decision = { id: '10', type: 'node:decision', position: { x: 1074.9, y: 661.7 }, @@ -269,7 +265,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node10); - const node11: Decision = { + const node11: Flowchart.Decision = { id: '11', type: 'node:decision', position: { x: 1065.75, y: 881.7 }, @@ -292,7 +288,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node11); - const node12: Process = { + const node12: Flowchart.Process = { id: '12', type: 'node:process', position: { x: 1099.7, y: 1101.7 }, @@ -314,7 +310,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node12); - const node13: Terminal = { + const node13: Flowchart.Terminal = { id: '13', type: 'node:terminal', position: { x: 1143.25, y: 1245.6 }, @@ -336,7 +332,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node13); - const node14: Process = { + const node14: Flowchart.Process = { id: '14', type: 'node:process', position: { x: 1385.4, y: 699.75 }, @@ -358,7 +354,7 @@ export function initializeModel(): SModelRoot { }; nodes.push(node14); - const node15: Process = { + const node15: Flowchart.Process = { id: '15', type: 'node:process', position: { x: 1386.1, y: 919.75 }, diff --git a/examples/flowchart/src/di.config.ts b/examples/flowchart/src/di.config.ts index 528de67..afd0064 100644 --- a/examples/flowchart/src/di.config.ts +++ b/examples/flowchart/src/di.config.ts @@ -17,19 +17,19 @@ import { Container, ContainerModule } from "inversify"; import { ConsoleLogger, + LocalModelSource, LogLevel, TYPES, configureViewerOptions, loadDefaultModules } from "sprotty"; -import { flowchartModule } from 'sprotty-library'; -import { FlowchartModelSource } from "./model-source"; +import { Flowchart } from 'sprotty-library'; export default (containerId: string) => { require('../css/diagram.css'); const module = new ContainerModule((bind, unbind, isBound, rebind) => { - bind(TYPES.ModelSource).to(FlowchartModelSource).inSingletonScope(); + bind(TYPES.ModelSource).to(LocalModelSource).inSingletonScope(); rebind(TYPES.ILogger).to(ConsoleLogger).inSingletonScope(); rebind(TYPES.LogLevel).toConstantValue(LogLevel.log); @@ -42,7 +42,7 @@ export default (containerId: string) => { const container = new Container(); loadDefaultModules(container); - container.load(flowchartModule); + container.load(Flowchart.flowchartModule); container.load(module); return container; }; diff --git a/examples/flowchart/src/model-source.ts b/examples/flowchart/src/model-source.ts deleted file mode 100644 index 44ea589..0000000 --- a/examples/flowchart/src/model-source.ts +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2024 TypeFox and others. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the Eclipse - * Public License v. 2.0 are satisfied: GNU General Public License, version 2 - * with the GNU Classpath Exception which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - ********************************************************************************/ - -import { injectable } from "inversify"; -import { LocalModelSource } from "sprotty"; -import { initializeModel } from "./data"; - -@injectable() -export class FlowchartModelSource extends LocalModelSource { - constructor() { - super(); - this.currentRoot = initializeModel(); - } -} diff --git a/examples/flowchart/src/standalone.ts b/examples/flowchart/src/standalone.ts index 3f1f832..3375306 100644 --- a/examples/flowchart/src/standalone.ts +++ b/examples/flowchart/src/standalone.ts @@ -17,11 +17,12 @@ import { LocalModelSource, TYPES } from 'sprotty'; import { BringToFrontAction, FitToScreenAction } from 'sprotty-protocol'; import createContainer from './di.config'; +import { initializeModel } from './data'; export default async function runFlowchart() { const container = createContainer('sprotty'); const modelSource = container.get(TYPES.ModelSource); - await modelSource.updateModel(); + await modelSource.updateModel(initializeModel()); const bringToFrontAction: BringToFrontAction = { kind: 'bringToFront', diff --git a/packages/sprotty-library/package.json b/packages/sprotty-library/package.json index 46d16c3..d8afe5c 100644 --- a/packages/sprotty-library/package.json +++ b/packages/sprotty-library/package.json @@ -16,12 +16,8 @@ "author": { "name": "Eclipse Sprotty" }, - "peerDependencies": { - "inversify": "~6.0.2" - }, "dependencies": { - "sprotty": "^1.1.0", - "sprotty-protocol": "^1.1.0" + "sprotty": "^1.1.0" }, "devDependencies": {}, "repository": { diff --git a/packages/sprotty-library/src/index.ts b/packages/sprotty-library/src/index.ts index 0a73f78..1e31792 100644 --- a/packages/sprotty-library/src/index.ts +++ b/packages/sprotty-library/src/index.ts @@ -13,5 +13,6 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ +import * as Flowchart from './flowchart'; -export * from './flowchart'; +export { Flowchart }; From dad688afb66ad9f72908be7eb9588374487446bc Mon Sep 17 00:00:00 2001 From: Guillaume Fontorbe Date: Wed, 21 Feb 2024 14:59:22 +0100 Subject: [PATCH 3/3] More specific model elements Signed-off-by: Guillaume Fontorbe --- .../src/flowchart/container.ts | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/packages/sprotty-library/src/flowchart/container.ts b/packages/sprotty-library/src/flowchart/container.ts index 7f9003b..610b2e5 100644 --- a/packages/sprotty-library/src/flowchart/container.ts +++ b/packages/sprotty-library/src/flowchart/container.ts @@ -15,7 +15,19 @@ ********************************************************************************/ import { ContainerModule } from "inversify"; -import { SEdgeImpl, SGraphImpl, SGraphView, SLabelImpl, SLabelView, SNodeImpl, SRoutingHandleImpl, SRoutingHandleView, configureModelElement } from "sprotty"; +import { + CircularNode, + DiamondNode, + RectangularNode, + SEdgeImpl, + SGraphImpl, + SGraphView, + SLabelImpl, + SLabelView, + SRoutingHandleImpl, + SRoutingHandleView, + configureModelElement +} from "sprotty"; import { AlternateProcessNodeView, CommentNodeView, @@ -47,25 +59,25 @@ export const flowchartModule = new ContainerModule((bind, unbind, isBound, rebin configureModelElement(context, 'graph', SGraphImpl, SGraphView); // Register nodes - configureModelElement(context, 'node:terminal', SNodeImpl, TerminalNodeView); - configureModelElement(context, 'node:process', SNodeImpl, ProcessNodeView); - configureModelElement(context, 'node:decision', SNodeImpl, DecisionNodeView); - configureModelElement(context, 'node:input', SNodeImpl, InputOutputNodeView); - configureModelElement(context, 'node:output', SNodeImpl, InputOutputNodeView); - configureModelElement(context, 'node:comment', SNodeImpl, CommentNodeView); - configureModelElement(context, 'node:predefined-process', SNodeImpl, PredefinedProcessNodeView); - configureModelElement(context, 'node:on-page-connector', SNodeImpl, OnPageConnectorNodeView); - configureModelElement(context, 'node:off-page-connector', SNodeImpl, OffPageConnectorNodeView); - configureModelElement(context, 'node:delay', SNodeImpl, DelayNodeView); - configureModelElement(context, 'node:alternate-process', SNodeImpl, AlternateProcessNodeView); - configureModelElement(context, 'node:data', SNodeImpl, DataNodeView); - configureModelElement(context, 'node:document', SNodeImpl, DocumentNodeView); - configureModelElement(context, 'node:multi-document', SNodeImpl, MultiDocumentNodeView); - configureModelElement(context, 'node:preparation', SNodeImpl, PreparationNodeView); - configureModelElement(context, 'node:display', SNodeImpl, DisplayNodeView); - configureModelElement(context, 'node:manual-input', SNodeImpl, ManualInputNodeView); - configureModelElement(context, 'node:manual-operation', SNodeImpl, ManualOperationNodeView); - configureModelElement(context, 'node:database', SNodeImpl, DatabaseNodeView); + configureModelElement(context, 'node:terminal', RectangularNode, TerminalNodeView); + configureModelElement(context, 'node:process', RectangularNode, ProcessNodeView); + configureModelElement(context, 'node:decision', DiamondNode, DecisionNodeView); + configureModelElement(context, 'node:input', RectangularNode, InputOutputNodeView); + configureModelElement(context, 'node:output', RectangularNode, InputOutputNodeView); + configureModelElement(context, 'node:comment', RectangularNode, CommentNodeView); + configureModelElement(context, 'node:predefined-process', RectangularNode, PredefinedProcessNodeView); + configureModelElement(context, 'node:on-page-connector', CircularNode, OnPageConnectorNodeView); + configureModelElement(context, 'node:off-page-connector', RectangularNode, OffPageConnectorNodeView); + configureModelElement(context, 'node:delay', RectangularNode, DelayNodeView); + configureModelElement(context, 'node:alternate-process', RectangularNode, AlternateProcessNodeView); + configureModelElement(context, 'node:data', RectangularNode, DataNodeView); + configureModelElement(context, 'node:document', RectangularNode, DocumentNodeView); + configureModelElement(context, 'node:multi-document', RectangularNode, MultiDocumentNodeView); + configureModelElement(context, 'node:preparation', RectangularNode, PreparationNodeView); + configureModelElement(context, 'node:display', RectangularNode, DisplayNodeView); + configureModelElement(context, 'node:manual-input', RectangularNode, ManualInputNodeView); + configureModelElement(context, 'node:manual-operation', RectangularNode, ManualOperationNodeView); + configureModelElement(context, 'node:database', RectangularNode, DatabaseNodeView); // Register labels configureModelElement(context, 'label', SLabelImpl, SLabelView);