### 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
```