### Install Sprotty Core and Development Dependencies Source: https://sprotty.org/docs/learn/getting-started Installs the necessary Sprotty core libraries, inversify for dependency injection (specifying a compatible version), reflect-metadata, and development tools like TypeScript and esbuild. ```bash # Core dependencies npm install sprotty inversify@^6.1.3 reflect-metadata # Development dependencies npm install typescript esbuild --save-dev ``` -------------------------------- ### Install Sprotty Yeoman Generator Source: https://sprotty.org/docs/learn/getting-started Installs Yeoman and the Sprotty generator globally. This is the first step for the recommended 'Fast Track' project setup. ```bash npm install -g yo generator-sprotty ``` -------------------------------- ### Initialize New Project Directory and npm Package Source: https://sprotty.org/docs/learn/getting-started Creates a new directory for your project and initializes it as an npm package. This sets up the basic project structure and package management. ```bash mkdir hello-world cd hello-world npm init -y ``` -------------------------------- ### Complete package.json Configuration Source: https://sprotty.org/docs/learn/getting-started This is the complete package.json file for a Sprotty project after setup. It includes essential dependencies like 'sprotty', 'inversify', and 'reflect-metadata', as well as development dependencies such as 'esbuild' and 'typescript'. The 'scripts' section contains the build command. ```json { "name": "hello-world", "version": "1.0.0", "description": "A simple Sprotty diagram", "scripts": { "build": "esbuild ./src/index.ts --bundle --sourcemap --outfile=./static/index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "inversify": "^6.1.3", "reflect-metadata": "^0.2.2", "sprotty": "^1.4.0" }, "devDependencies": { "esbuild": "^0.25.3", "typescript": "^5.8.3" } } ``` -------------------------------- ### Configure package.json for Sprotty Project Source: https://sprotty.org/docs/learn/getting-started Replaces the default package.json content with a simplified version suitable for a Sprotty project. This ensures basic configuration is in place. ```json { "name": "hello-world", "version": "1.0.0", "description": "A simple Sprotty diagram", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" } } ``` -------------------------------- ### Generate Sprotty Project with Yeoman Source: https://sprotty.org/docs/learn/getting-started Runs the Sprotty Yeoman generator to create a new project. Follow the prompts to configure your project; accepting defaults is recommended for beginners. ```bash yo sprotty ``` -------------------------------- ### Create Project Directory Structure Source: https://sprotty.org/docs/learn/getting-started Creates the 'src' directory for TypeScript source files and the 'static' directory for HTML, CSS, and compiled JavaScript files. ```bash mkdir src static ``` -------------------------------- ### Initialize TypeScript Configuration Source: https://sprotty.org/docs/learn/getting-started Initializes the TypeScript compiler configuration file (tsconfig.json) in your project. This sets up how TypeScript files will be compiled. ```bash npx tsc --init ``` -------------------------------- ### Content of static/index.html Source: https://sprotty.org/docs/learn/getting-started The HTML structure for displaying a Sprotty diagram. It includes a title, links to the JavaScript and CSS files, and a div element where the diagram will be rendered. ```html My First Sprotty Diagram
``` -------------------------------- ### Create Static HTML Page for Diagram Source: https://sprotty.org/docs/learn/getting-started Creates the index.html file within the 'static' directory. This file serves as the entry point for displaying the Sprotty diagram in a web browser. ```bash touch static/index.html ``` -------------------------------- ### Server-side DiagramServer Setup with WebSockets Source: https://sprotty.org/docs/recipes/model-sources Provides an example of setting up a Node.js WebSocket server and integrating Sprotty's DiagramServer to handle diagram generation and actions. ```javascript // Creating a new websocket server const wss = new WebSocketServer.Server({ port: 8080 }); // create our DiagramServices const elkFactory: ElkFactory = () => new SocketElkServer(); const services: DiagramServices = { DiagramGenerator: new RandomGraphGenerator(), ModelLayoutEngine: new ElkLayoutEngine(elkFactory) } // Creating connection using websocket wss.on("connection", ws => { const diagramServer = new DiagramServer(action => { ws.send(JSON.stringify(action)); }, services) ws.on('message' data => { diagramServer.accept(data.action); }); }); ``` -------------------------------- ### Add esbuild Build Script to package.json Source: https://sprotty.org/docs/learn/getting-started This snippet shows how to add a 'build' script to your package.json file. This script utilizes esbuild to bundle your TypeScript entry point, generate source maps, and output a JavaScript file to the static directory. ```json "scripts": { "build": "esbuild ./src/index.ts --bundle --sourcemap --outfile=./static/index.js" } ``` -------------------------------- ### Setup InversifyJS Container Source: https://sprotty.org/docs/learn/dependency-injection Initializes an InversifyJS dependency injection container, loads Sprotty's default modules for core functionality, and then loads custom application modules. The configured container is returned for use in the application. ```javascript const container = new Container(); loadDefaultModules(container); container.load(myModule); return container; ``` -------------------------------- ### Create Sprotty DI Container Source: https://sprotty.org/docs/recipes/dependency-injection Defines the main DI container setup for Sprotty applications. It loads default modules, custom modules, and configures model elements and viewer options. ```typescript export const createContainer = (containerId: string) => { const myModule = new ContainerModule((bind, unbind, isBound, rebind) => { bind(TYPES.ModelSource).to(LocalModelSource).inSingletonScope(); const context = { bind, unbind, isBound, rebind }; configureModelElement(context, 'graph', SGraphImpl, SGraphView); configureModelElement(context, 'task', SNodeImpl, TaskNodeView); configureModelElement(context, 'edge', SEdgeImpl, PolylineEdgeView); configureViewerOptions(context, { needsClientLayout: false, baseDiv: containerId }); }); const container = new Container(); loadDefaultModules(container); container.load(myModule, edgeIntersectionModule); return container; }; ``` -------------------------------- ### LocalModelSource Example Source: https://sprotty.org/docs/recipes/model-sources Demonstrates setting an initial model schema and dynamically adding new nodes to a Sprotty graph using the `LocalModelSource`. It highlights the use of `sprotty-protocol` interfaces for defining model elements and event listeners for user interactions. ```typescript import {SNode} from 'sprotty-protocol'; export default runExample() { const container = createContainer('sprotty-showcase'); const modelSource = container.get(TYPES.ModelSource); modelSource.setModel({ type: 'graph' children: [ { type: 'node', id: 'main_node', text: 'node1', position: {x: 0, y: 0} } ] }); document.getElementById('addButton').addEventListener('click', () => { modelSource.addElements([ { parentId: 'graph', element: { type: 'node', id: 'new_node', text: 'new node', position: {x: 100, y: 100} } }]) }) } ``` -------------------------------- ### InversifyJS Multi-Binding Example Source: https://sprotty.org/docs/recipes/dependency-injection Demonstrates how to inject multiple implementations of an interface using `@multiInject` and `@optional`. This is useful when a specific type can have several associated processors or handlers. ```typescript @multiInject(TYPES.VNodePostprocessor) @optional() protected postprocessors: VNodePostprocessor[] ``` -------------------------------- ### Sprotty Model Element Data Structure Source: https://sprotty.org/docs/recipes/dependency-injection An example of a data structure representing a 'task' model element within Sprotty. It includes properties like type, id, name, and state, which Sprotty uses to instantiate and render corresponding view components. ```typescript { type: 'task', id: 'task01', name: 'First Task', isFinished: true, ... } ``` -------------------------------- ### Custom Model Source Proxy Implementation (WebWorker) Source: https://sprotty.org/docs/recipes/model-sources An example of creating a custom Sprotty ModelSource proxy by extending DiagramServerProxy, designed for communication with a DiagramServer running in a Web Worker. ```typescript export class WebWorkerDiagramProxy extends DiagramServerProxy { constructor(private worker: Worker) { super() const proxy = this; worker.onmessage = function(event) { proxy.messageReceived(event.data) } } protected sendMessage(message: ActionMessage): void { this.worker.postMessage(JSON.stringify(message)); } } ``` -------------------------------- ### Apply CSS Classes on User Interaction Source: https://sprotty.org/docs/recipes/styling Demonstrates how to apply CSS classes to SVG elements in Sprotty views based on node properties like selection and hover feedback. The `RectangularNodeView` example shows how `node.selected` and `node.hoverFeedback` are mapped to `class-selected` and `class-mouseover` respectively. This relies on features like `selectFeature` and `hoverFeedbackFeature` being enabled. ```typescript export class RectangularNodeView extends ShapeView { render(node: Readonly, context: RenderingContext, args?: IViewArgs): VNode | undefined { if (!this.isVisible(node, context)) { return undefined; } return {context.renderChildren(node)} ; } } ``` -------------------------------- ### Sprotty SCompartment Layout Example Source: https://sprotty.org/docs/recipes/micro-layout This TypeScript code snippet demonstrates how to use SCompartments to group SModelElements and define complex layouts within a Sprotty graph. It showcases nested compartments with 'vbox' and 'hbox' layouts, along with layout options for padding and CSS classes for styling. ```TypeScript export const graph: SGraph = { type: 'graph', id: 'graph', children: [ { type: 'node', id: 'node01', layout: 'vbox', children: [ { type: 'comp', id: 'comp01', cssClasses: ['red-outline'], layout: 'hbox', layoutOptions: { paddingTop: 5, paddingBottom: 5, paddingLeft: 5, paddingRight: 5, }, children: [ { type: 'node', id: 'node02', size: { width: 25, height: 25 }, }, { type: 'node', id: 'node03', size: { width: 25, height: 25 }, }, { type: 'comp', id: 'comp02', cssClasses: ['red-outline'], layout: 'vbox', layoutOptions: { paddingTop: 5, paddingBottom: 5, paddingLeft: 5, paddingRight: 5, }, children: [ { type: 'node', id: 'node04', size: { width: 25, height: 25 }, }, { type: 'node', id: 'node05', size: { width: 25, height: 25 }, }, ] } ] }, { type: 'comp', id: 'comp05', cssClasses: ['red-outline'], layout: 'hbox', layoutOptions: { paddingTop: 5, paddingBottom: 5, paddingLeft: 5, paddingRight: 5, }, children: [ { type: 'comp', id: 'comp03', cssClasses: ['red-outline'], layout: 'vbox', layoutOptions: { paddingTop: 5, paddingBottom: 5, paddingLeft: 5, paddingRight: 5, }, children: [ { type: 'node', id: 'node06', size: { width: 25, height: 25 }, }, { type: 'node', id: 'node07', size: { width: 25, height: 25 }, }, { type: 'comp', id: 'comp04', cssClasses: ['red-outline'], layout: 'hbox', layoutOptions: { paddingTop: 5, paddingBottom: 5, paddingLeft: 5, paddingRight: 5, }, } ] } ] } ] } ] } ``` -------------------------------- ### Style Node Projections with CSS Source: https://sprotty.org/docs/recipes/custom-interactions Provides an example of how to style the HTML elements representing node projections in the Sprotty projection bars using CSS classes. ```css .svg-projection { background-color: rgba(255, 153, 0, 0.5); } ``` -------------------------------- ### Sprotty Diagram Views and SVG Elements Source: https://sprotty.org/docs/recipes/styling Sprotty provides predefined views to render diagram elements like nodes, edges, and labels. Each view maps to a specific SVG element, enabling consistent visualization. These views are fundamental for applying styles via CSS classes. ```APIDOC Sprotty Diagram Views: Node Views: - CircularNodeView: Renders a node as a "circle" SVG element. - RectangularNodeView: Renders a node as a "rect" SVG element. - DiamondNodeView: Renders a node as a "polygon" SVG element. Edge Views: - PolylineEdgeView: Renders an edge as a "path" SVG element, representing a succession of straight lines. - JumpingPolylineEdgeView: Renders an edge as a "path" SVG element, including arcs at intersections. - PolylineEdgeViewWithGapsOnIntersections: Renders an edge as a "path" SVG element, with gaps at intersections. - BezierCurveEdgeView: Renders an edge as a "path" SVG element, using Bezier curves. Label Views: - SLabelView: Renders a label as a "text" SVG element. ``` -------------------------------- ### Add Custom CSS Classes to Sprotty Elements Source: https://sprotty.org/docs/recipes/styling Demonstrates how to apply specific CSS classes to individual Sprotty elements by adding a `cssClasses` property to the `SModelElement`. This allows for styling beyond the default type-based classes. ```typescript const myNode: SNode = { id: 'node1', type: 'node:my-node', cssClasses: ['special-node', 'some-other-css-class'] // ... other properties }; // This node would receive classes: 'sprotty-node', 'my-node', 'special-node', 'some-other-css-class' ``` -------------------------------- ### Apply Conditional CSS Classes in Custom Sprotty Views Source: https://sprotty.org/docs/recipes/styling Illustrates creating a custom Sprotty view to render diagram elements. It shows how to use the `class-name={boolean}` syntax within JSX to conditionally apply CSS classes to SVG elements based on element properties, enabling dynamic styling. ```typescript class MyNodeImpl extends SNodeImpl { value: number; } class MyNodeView extends ShapeView { render(node: MyNodeImpl, context: RenderingContext, args?: ViewArgs): VNode | undefined { return = 10} /> {context.renderChildren(node)} ; } } ``` -------------------------------- ### Sprotty Default CSS Classes for Styling Source: https://sprotty.org/docs/recipes/styling Sprotty applies default CSS classes to the generated SVG elements, facilitating straightforward styling of diagram components. These classes allow for uniform styling across all nodes, ports, edges, and labels, or targeted styling for specific elements. ```APIDOC Sprotty Default CSS Classes: - sprotty-graph: Applied to the root SVG element of the diagram. - sprotty-node: Applied to SVG elements representing nodes. - sprotty-port: Applied to SVG elements representing ports. - sprotty-edge: Applied to SVG elements representing edges. - sprotty-label: Applied to SVG elements representing labels. Example CSS: .sprotty-node { fill: lightblue; stroke: steelblue; stroke-width: 2px; } .sprotty-edge { stroke: gray; stroke-width: 1px; fill: none; } ``` -------------------------------- ### Sprotty Application Entry Point (TypeScript) Source: https://sprotty.org/docs/learn/putting-it-together Creates the main entry point for a Sprotty application. It initializes the dependency injection container, loads model data using `LocalModelSource`, and sets the graph data for rendering. ```typescript import 'reflect-metadata'; import { LocalModelSource, TYPES } from 'sprotty'; import createContainer from './di.config'; import { graph } from './model-source'; document.addEventListener('DOMContentLoaded', () => { const container = createContainer('sprotty-diagram'); const modelSource = container.get(TYPES.ModelSource); modelSource.setModel(graph); }); ``` -------------------------------- ### Build Sprotty Application (Bash) Source: https://sprotty.org/docs/learn/putting-it-together Command to build the Sprotty application. This typically compiles TypeScript code and bundles assets for deployment. ```bash npm run build ``` -------------------------------- ### Viewer Rendering Process Source: https://sprotty.org/docs/recipes/architecture-overview Depicts the workflow of the Sprotty Viewer, from receiving an SModel to rendering it in the DOM via a VirtualDOM. ```mermaid flowchart LR; Viewer ViewRegistry Views VirtualDOM DOM Viewer --> ViewRegistry ViewRegistry --> Views Views -->|render| VirtualDOM VirtualDOM -->|patch| DOM DOM -->|event| Viewer ``` -------------------------------- ### Sprotty Project Structure Source: https://sprotty.org/docs/learn/dependency-injection Illustrates a typical file structure for a Sprotty project after integrating dependency injection. It highlights key directories and files, including the new `src/di.config.ts` which serves as the central configuration for connecting models and views. ```plaintext hello-world/ ├── node_modules/ # Dependencies installed by npm ├── package.json # Project configuration ├── package-lock.json # Dependency lock file ├── tsconfig.json # TypeScript configuration ├── src/ │ ├── model.ts # Custom node type definitions │ ├── model-source.ts # Diagram model data structure │ ├── views.tsx # Custom view implementations │ └── di.config.ts # Dependency injection configuration └── static/ ├── index.html # HTML entry point └── styles.css # CSS styling for the diagram ``` -------------------------------- ### Client-side WebSocket Diagram Server Proxy Usage Source: https://sprotty.org/docs/recipes/model-sources Demonstrates how to obtain and use the WebSocketDiagramServerProxy on the client-side to listen for WebSocket connections and handle diagram actions. ```javascript const modelSource = container.get(TYPES.ModelSource); modelSource.listen(websocket); ``` -------------------------------- ### Load ElkLayoutModule to Container Source: https://sprotty.org/docs/sprotty-elk/introduction Illustrates the final step of loading the necessary modules, including the elkLayoutModule and custom modules, into the main Sprotty container. ```typescript const container = new Container(); loadDefaultModules(container); container.load(elkLayoutModule, myModule); return container; ``` -------------------------------- ### Register Sprotty Layout Preprocessor Source: https://sprotty.org/docs/sprotty-elk/introduction Shows how to bind a custom `ILayoutPreprocessor` implementation to the dependency injection container using `ContainerModule`. This makes the custom preprocessor available to the `ElkLayoutEngine`. ```typescript const myModule = new ContainerModule((bind, unbind, isBound, rebind) => { // ... other bindings bind(ILayoutPreprocessor).to(Preprocessor).inSingletonScope(); }); ``` -------------------------------- ### Create Elk Factory Source: https://sprotty.org/docs/sprotty-elk/introduction Defines how to create a new ElkFactory instance, which is responsible for initializing the ELK layout engine. It allows configuration of algorithms and layout options. ```typescript import { ElkFactory } from 'sprotty-elk/lib/inversify'; import ElkConstructor from 'elkjs/lib/elk.bundled.js'; export default (containerId: string) => { // ... const elkFactory: ElkFactory = () => new ElkConstructor({ algorithms: [], // array of layout algorithms to be integrated into the layout engine defaultLayoutOptions: {}, workerUrl: 'url' // URL to the ELK worker (elk-worker.js) }); } ``` -------------------------------- ### Configure Sprotty Viewer Options Source: https://sprotty.org/docs/learn/dependency-injection Sets configuration options for the Sprotty diagram viewer. This includes specifying whether the client should handle layout (`needsClientLayout`) and identifying the base HTML element (`baseDiv`) for rendering the diagram. ```javascript configureViewerOptions(context, { needsClientLayout: false, baseDiv: containerId }); ``` -------------------------------- ### SModel Element Hierarchy Source: https://sprotty.org/docs/recipes/architecture-overview Illustrates the inheritance structure of Sprotty's SModel elements, including base classes and custom extensions. ```mermaid flowchart BT; SModelElementImpl SShapeElementImpl SEdgeImpl SNodeImpl SPortImpl SLabelImpl CustomEdge CustomNode CustomPort CustomLabel SShapeElementImpl --> SModelElementImpl SEdgeImpl --> SModelElementImpl CustomEdge -.-> SEdgeImpl SNodeImpl --> SShapeElementImpl CustomNode -.-> SNodeImpl SPortImpl --> SShapeElementImpl CustomPort -.-> SPortImpl SLabelImpl --> SShapeElementImpl CustomLabel -.-> SLabelImpl ``` -------------------------------- ### Sprotty Core Data Flow Source: https://sprotty.org/docs/recipes/architecture-overview Illustrates the fundamental unidirectional cyclic flow of information between Sprotty's main components: ActionDispatcher, CommandStack, and Viewer. ```flowchart flowchart TD; ActionDispatcher CommandStack Viewer ActionDispatcher -->|Command| CommandStack CommandStack -->|SModel| Viewer Viewer -->|Action| ActionDispatcher ``` -------------------------------- ### Implement Sprotty Layout Preprocessor Source: https://sprotty.org/docs/sprotty-elk/introduction Demonstrates implementing the `ILayoutPreprocessor` interface to define custom preprocessing steps for an ELK graph generated from a Sprotty SModel. The `preprocess` method receives the ELK graph, Sprotty graph, and index for modifications. ```typescript @injectable() export class MyLayoutPreprocessor implements ILayoutPreprocessor { preprocess(elkGraph: ElkNode, sgraph: SGraph, index: SModelIndex): void { // apply preprocessing to the ELK graph } } ``` -------------------------------- ### Sprotty Communication Protocols Source: https://sprotty.org/docs/recipes/actions-and-protocols Describes three communication protocols based on layout computation location (server-only, client-only, or both). Configuration options for client and server dictate the protocol used. ```apidoc Protocol 1: No Layout Computation / Server-Only Layout Description: The server provides a model with complete layout information, requiring no further client processing. Sequence: Client -> Server: RequestModelAction Server -> Client: SetModelAction Server -> Client: UpdateModelAction (when model changes) Protocol 2: Client-Only Layout Description: The server provides a model without layout information, and the client computes the layout. Protocol 3: Client and Server Layout Description: Layout computation is distributed between the client and server. Client-side Configuration: configureViewerOptions(context, { needsClientLayout: boolean, needsServerLayout: boolean, baseDiv: string }); Server-side Configuration: diagramServer.setNeedsClientLayout(boolean); diagramServer.setNeedsServerLayout(boolean); ``` -------------------------------- ### Sprotty Actions Overview Source: https://sprotty.org/docs/recipes/actions-and-protocols Defines key actions used for communication between Sprotty client and server, distinguished by their KIND property. Actions are plain JSON serializable objects. ```apidoc ComputedBoundsAction: Sent from the client to the model source to transmit the result of bounds computation for micro-layout. This is sent as a response to a RequestBoundsAction. RequestBoundsAction: Sent from the model source to the client to request bounds for the given model. This triggers the micro-layout computation. RequestModelAction: Sent from client to model source to request a new model. Usually, this is the first action sent to initiate the communication. Optionally this can contain an `options` object containing configuration for the `DiagramServer`, like properties for `needsClientLayout` and `needsServerLayout`. SetModelAction: Sent from the model source to the client to set the model. It contains the schema for the new graph. Should a model already exist in the client, it is overwritten. UpdateModelAction: Sent from model source to client to update the current model. Allows animating the transition from the old to the new model and contains properties for the transition. For more info on existing actions see: https://github.com/eclipse-sprotty/sprotty/blob/master/packages/sprotty-protocol/src/actions.ts ``` -------------------------------- ### Retrieve Model Source from DI Source: https://sprotty.org/docs/recipes/model-sources Shows how to obtain an instance of the configured model source from the dependency injection container. This retrieved instance can then be used for further configuration or interaction with the diagramming system. ```typescript const modelSource = container.get(TYPES.ModelSource); ``` -------------------------------- ### Enable Client-Side Layout Engine Source: https://sprotty.org/docs/recipes/micro-layout Activates the micro-layout engine by setting the 'needsClientLayout' property to true in the inversify container configuration. This is a prerequisite for using layout properties on nodes. ```TypeScript import { ContainerModule } from 'inversify'; import { configureViewerOptions } from '@sprotty/core'; const module = new ContainerModule((bind, unbind, isBound, rebind) => { const context = {bind, unbind, isBound, rebind}; // ... other configurations configureViewerOptions(context, { needsClientLayout: true }); }); ``` -------------------------------- ### Configure Sprotty Viewer Options (Client-Side) Source: https://sprotty.org/docs/recipes/actions-and-protocols Configures viewer options on the client-side, typically within a dependency injection container. This sets preferences for layout computation and the base DOM element. ```typescript configureViewerOptions(context, { needsClientLayout: false, needsServerLayout: true, baseDiv: containerId }); ``` -------------------------------- ### Bind ElkLayoutEngine to ContainerModule Source: https://sprotty.org/docs/sprotty-elk/introduction Binds the ElkLayoutEngine to the Sprotty container, making it available as the implementation for the IModelLayoutEngine interface. ```typescript const myModule = new ContainerModule((bind, unbind, isBound, rebind) => { // ... bind(TYPES.IModelLayoutEngine).toService(ElkLayoutEngine); }); ``` -------------------------------- ### Configure Model Element with Features Source: https://sprotty.org/docs/recipes/dependency-injection Demonstrates how to configure a model element, linking it to specific view components and enabling/disabling Sprotty features. This allows customization of default behaviors like dragging or selection. ```typescript configureModelElement(context, 'task', SNodeImpl, TaskNodeView, { enable: [customFeature], disable: [moveFeature] }); ``` -------------------------------- ### Configure Diagram Server Layout (Server-Side) Source: https://sprotty.org/docs/recipes/actions-and-protocols Sets layout preferences directly on the DiagramServer instance. This determines whether the server participates in layout computation. ```javascript diagramServer.setNeedsClientLayout(false); diagramServer.setNeedsServerLayout(true); ``` -------------------------------- ### Bind Postprocessor in TypeScript ContainerModule Source: https://sprotty.org/docs/sprotty-elk/introduction Shows how to register a custom `ILayoutPostprocessor` implementation within a `ContainerModule` using dependency injection. This ensures the custom postprocessor is available for use by the `ElkLayoutEngine`. ```TypeScript const myModule = new ContainerModule((bind, unbind, isBound, rebind) => { ... bind(ILayoutPostprocessor).to(Postprocessor).inSingletonScope(); }); ``` -------------------------------- ### Implement Custom Layout Postprocessor in TypeScript Source: https://sprotty.org/docs/sprotty-elk/introduction Demonstrates how to create a custom layout postprocessor by implementing the `ILayoutPostprocessor` interface. The `postprocess` method receives the ELK graph, Sprotty graph, and index to modify the graph after layout. ```TypeScript @injectable() export class MyLayoutPostprocessor implements ILayoutPostprocessor { postprocess(elkGraph: ElkNode, sgraph: SGraph, index: SModelIndex): void { // apply postprocessing to the ELK graph } } ``` -------------------------------- ### SNodeImpl Default Features Source: https://sprotty.org/docs/ref/features Demonstrates how `SNodeImpl` implements default features by extending `SConnectableElementImpl` and listing features like connectable, deletable, select, bounds, move, layoutContainer, fade, hoverFeedback, and popup. ```TypeScript export class SNodeImpl extends SConnectableElementImpl implements Selectable, Fadeable, Hoverable { static readonly DEFAULT_FEATURES = [connectableFeature, deletableFeature, selectFeature, boundsFeature, moveFeature, layoutContainerFeature, fadeFeature, hoverFeedbackFeature, popupFeature]; ... } ``` -------------------------------- ### Client and Server Layout Sequence Diagram Source: https://sprotty.org/docs/recipes/actions-and-protocols Depicts the client and server layout scenario in Sprotty. The client sends `ComputedBoundsAction` to the server, which then applies its layout engine and sends back an `UpdateModelAction`. ```sequenceDiagram sequenceDiagram participant C as Client participant S as Server Note over C,S: Client requests model C ->> S: RequestModelAction S ->> C: RequestBoundsAction C ->> S: ComputedBoundsAction S ->> C: UpdateModelAction Note over C,S: Server updates model loop when model changes S ->> C: RequestBoundsAction C ->> S: ComputedBoundsAction S ->> C: UpdateModelAction end ``` -------------------------------- ### Configure Sprotty ELK Layout Options Source: https://sprotty.org/docs/sprotty-elk/introduction Illustrates extending `DefaultLayoutConfigurator` to provide custom layout options for ELK. Override methods like `graphOptions`, `nodeOptions`, `edgeOptions`, `labelOptions`, and `portOptions` to apply specific configurations. Refer to ELK documentation for available options. ```typescript export class MyLayoutConfigurator extends DefaultLayoutConfigurator { // options for the graph element protected override graphOptions(sgraph: SGraph, index: SModelIndex): LayoutOptions | undefined { return {"optionKey": "optionValue"}; } // options for node elements protected override nodeOptions(snode: SNode, index: SModelIndex): LayoutOptions | undefined { return {"optionKey": "optionValue"}; } // options for edge elements protected override edgeOptions(sedge: SEdge, index: SModelIndex): LayoutOptions | undefined { return {"optionKey": "optionValue"}; } // options for label elements protected override labelOptions(slabel: SLabel, index: SModelIndex): LayoutOptions | undefined { return {"optionKey": "optionValue"}; } // options for port elements protected override portOptions(sport: SPort, index: SModelIndex): LayoutOptions | undefined { return {"optionKey": "optionValue"}; } } ``` -------------------------------- ### Client-Only Layout Sequence Diagram Source: https://sprotty.org/docs/recipes/actions-and-protocols Illustrates the client-only layout scenario in Sprotty. The server sends `RequestBoundsAction`, and the client applies updated bounds locally without forwarding `ComputedBoundsAction` back to the server. ```sequenceDiagram sequenceDiagram participant C as Client participant S as Server Note over C,S: Client requests model C->>S: RequestModelAction rect rgb(240, 240, 180, .4) S->>C: RequestBoundsAction end Note over C,S: Server updates model loop when model changes rect rgb(240, 240, 180, .4) S->>C: RequestBoundsAction end end ``` -------------------------------- ### Register Model Source with DI Source: https://sprotty.org/docs/recipes/model-sources Demonstrates how to register a model source implementation (e.g., LocalModelSource or DiagramServerProxy) within the front-end dependency injection container. This is a crucial step for Sprotty to manage diagram data. ```typescript bind(TYPES.ModelSource).to(ModelSourceClassOrProxy).inSingletonScope(); ``` -------------------------------- ### Action Dispatcher and Model Source Interaction Source: https://sprotty.org/docs/recipes/architecture-overview Depicts the bidirectional communication between the ActionDispatcher and the ModelSource, used for injecting external data or applying edits. ```flowchart flowchart LR; ModelSource ActionDispatcher ModelSource -->|Action| ActionDispatcher ActionDispatcher -->|Action| ModelSource ``` -------------------------------- ### SShapeElementImpl API Source: https://sprotty.org/docs/ref/smodel An abstract base class for Sprotty elements that possess a defined position and size. It provides fundamental properties for layout and positioning within the diagram. ```APIDOC SShapeElementImpl: description: Abstract class for elements with a position and size. properties: position: Point - The position of the element. Defaults to {x: 0, y: 0}. size: Dimension - The size of the element. Defaults to {width: -1, height: -1}. layoutOptions: ModelLayoutOptions - Optional: Options for the layout of the element. inheritance: SChildElementImpl -> SParentElementImpl -> SModelElementImpl ``` -------------------------------- ### Sprotty Custom Component with InversifyJS Source: https://sprotty.org/docs/recipes/dependency-injection Illustrates creating a custom Sprotty component, such as a view, using InversifyJS for dependency injection. Components must be annotated with `@injectable()` to be managed by the container. ```typescript @injectable() export class PolylineEdgeView extends RoutableView { @inject(EdgeRouterRegistry) edgeRouterRegistry: EdgeRouterRegistry; ... } ``` -------------------------------- ### Sprotty Sizing and Positioning Properties Source: https://sprotty.org/docs/recipes/micro-layout Configures the minimum dimensions of a container and whether its size is dependent on its children. Also clarifies child element positioning. ```APIDOC Sizing and Positioning Properties: - minWidth: number Description: Sets the minimal width of a container (in pixels). - minHeight: number Description: Sets the minimal height of a container (in pixels). - resizeContainer: boolean Description: Indicates if the size of a container is dependent on the size of its children. Child Positioning: The position of children elements (given as x-y coordinates) is always relative to their parents. For example, to position a child at the top-left corner of its parent, set its position to {x: 0, y: 0}. ``` -------------------------------- ### Define Graph with Different Layouts Source: https://sprotty.org/docs/recipes/micro-layout Demonstrates defining a Sprotty graph with multiple SNode elements, each configured with a different layout ('vbox', 'hbox', 'stack') and containing SLabel children. This showcases how layout properties affect child arrangement. ```TypeScript import { SGraph, SNode, SLabel } from '@sprotty/core'; export const graph: SGraph = { type: 'graph', id: 'graph', children: [ // Node using 'vbox' layout { type: 'node', id: 'node01', layout: 'vbox', children: [ { id: 'label01-1', text: 'I am using a', type: 'label', }, { id: 'label01-2', text: 'vbox', type: 'label', cssClasses: ['layout-label'] }, { id: 'label01-3', text: 'layout', type: 'label', }, ] }, // Node using 'hbox' layout { type: 'node', id: 'node02', layout: 'hbox', position: { x: 100, y: 0 }, children: [ { id: 'label02-1', text: 'I am using a', type: 'label', }, { id: 'label02-2', text: 'hbox', type: 'label', cssClasses: ['layout-label'] }, { id: 'label02-3', text: 'layout', type: 'label', }, ] }, // Node using 'stack' layout { type: 'node', id: 'node03', layout: 'stack', position: { x: 265, y: 0 }, children: [ { id: 'label03-1', text: 'I am using a', type: 'label', }, { id: 'label03-2', text: 'stack', type: 'label', cssClasses: ['layout-label'] }, { id: 'label03-3', text: 'layout', type: 'label', }, ] }, ] }; ``` -------------------------------- ### DiagramServices Interface Definition Source: https://sprotty.org/docs/recipes/model-sources Defines the TypeScript interface for DiagramServices, outlining the mandatory DiagramGenerator and optional ModelLayoutEngine and ServerActionHandlerRegistry components required for the DiagramServer. ```typescript export interface DiagramServices { readonly DiagramGenerator: IDiagramGenerator readonly ModelLayoutEngine?: IModelLayoutEngine readonly ServerActionHandlerRegistry?: ServerActionHandlerRegistry } ``` -------------------------------- ### Bind ElkFactory to ContainerModule Source: https://sprotty.org/docs/sprotty-elk/introduction Shows how to bind the created ElkFactory to the Sprotty dependency injection container using InversifyJS. ```typescript const myModule = new ContainerModule((bind, unbind, isBound, rebind) => { // ... bind(ElkFactory).toFactory(elkFactory); }); ``` -------------------------------- ### Configure Sprotty Model Elements Source: https://sprotty.org/docs/learn/dependency-injection Maps model element types (e.g., 'graph', 'task') to their corresponding model implementation classes and view implementation classes. This allows Sprotty to correctly render different parts of the diagram based on their type. The mapping is crucial for defining element behavior and appearance. ```javascript const context = { bind, unbind, isBound, rebind }; configureModelElement(context, 'graph', SGraphImpl, SGraphView); configureModelElement(context, 'task', RectangularNode, TaskNodeView); configureModelElement(context, 'edge', SEdgeImpl, PolylineEdgeView); configureModelElement(context, 'routing-point', SRoutingHandleImpl, SRoutingHandleView); configureModelElement(context, 'volatile-routing-point', SRoutingHandleImpl, SRoutingHandleView); ``` -------------------------------- ### Configure Dependency Injection for Action Dispatcher Source: https://sprotty.org/docs/recipes/dependency-injection Configures the dependency injection container to bind the ActionDispatcher to its interface (TYPES.IActionDispatcher) in a singleton scope. It also registers a provider for IActionDispatcherProvider, enabling the resolution of the ActionDispatcher through a factory function. ```TypeScript bind(TYPES.IActionDispatcher).to(ActionDispatcher).inSingletonScope(); bind(TYPES.IActionDispatcherProvider).toProvider(ctx => { return () => { return new Promise((resolve) => { resolve(ctx.container.get(TYPES.IActionDispatcher)); }); }; }); ``` -------------------------------- ### Sprotty Root and Graph Elements Source: https://sprotty.org/docs/ref/smodel Documents root element classes like SModelRootImpl and SGraphImpl, detailing canvas bounds, revision numbers, and layout options for diagram roots. ```APIDOC SModelRootImpl: Inheritance: SParentElementImpl -> SModelElementImpl Properties: canvasBounds: Bounds - The bounds of the canvas, determining diagram size. Defaults to {x: 0, y: 0, width: -1, height: -1}. revision: number (optional) - The model revision number, incremented on changes. Description: The base class for the root element of the diagram model, containing actual model elements in its 'children' property. ``` ```APIDOC SGraphImpl: Inheritance: ViewportRootModel -> SModelRootImpl -> SParentElementImpl -> SModelElementImpl Properties: layoutOptions: ModelLayoutOptions (optional) - Options for the layout of the diagram. Description: The root element for graph-based diagrams, inheriting from SModelRootImpl. ``` -------------------------------- ### SEdgeImpl API Documentation Source: https://sprotty.org/docs/ref/smodel Represents connectors between elements in a diagram, linking a source and a target. Edges can be selected and provide hover feedback. ```APIDOC SEdgeImpl: Description: These are the connectors for the diagram model. An edge has a source and a target. Each of which can either be a node or a port. The source and target elements are referenced by their id (inherited from SRoutableElementImpl) and can be resolved via the index stored in the root element. Properties: selected: boolean - Indicates if the edge is selected. Defaults to false. hoverFeedback: boolean - Indicates if the edge should show hover feedback. Defaults to false. opacity: number - The opacity of the edge. Defaults to 1. Inheritance: SRoutableElementImpl -> SChildElementImpl -> SParentElementImpl -> SModelElementImpl Default Features: editFeature deletableFeature selectFeature fadeFeature hoverFeedbackFeature ```