/
model.ts
340 lines (295 loc) · 10.2 KB
/
model.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/********************************************************************************
* Copyright (c) 2021-2023 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 { Bounds, Point, Dimension } from './utils/geometry';
import { hasOwnProperty } from './utils/object';
/**
* Base type for all elements of the diagram model.
* Each model element must have a unique ID and a type that is used to look up its view.
*/
export interface SModelElement {
type: string
id: string
children?: SModelElement[]
cssClasses?: string[]
}
/**
* Base type for the root element of the diagram model tree.
*/
export interface SModelRoot extends SModelElement {
canvasBounds?: Bounds
revision?: number
}
/**
* Usually the root of a model is also a viewport.
*/
export interface ViewportRootElement extends SModelRoot, Partial<Viewport>, Partial<BoundsAware> {
}
/**
* Root element for graph-like models.
*/
export interface SGraph extends ViewportRootElement, Partial<LayoutableChild> {
children: SModelElement[]
/** @deprecated Use `position` and `size` instead. */
bounds?: Bounds
}
export interface SShapeElement extends SModelElement, Partial<LayoutableChild> {
}
/**
* Model element class for nodes, which are the main entities in a graph. A node can be connected to
* another node via an SEdge. Such a connection can be direct, i.e. the node is the source or target of
* the edge, or indirect through a port, i.e. it contains an SPort which is the source or target of the edge.
*/
export interface SNode extends SShapeElement, Partial<LayoutContainer>, Partial<Selectable>, Partial<Hoverable>, Partial<Fadeable> {
anchorKind?: string
}
/**
* A port is a connection point for edges. It should always be contained in an SNode.
*/
export interface SPort extends SShapeElement, Partial<Selectable>, Partial<Hoverable>, Partial<Fadeable> {
anchorKind?: string
}
/**
* Model element class for edges, which are the connectors in a graph. An edge has a source and a target,
* each of which can be either a node or a port. The source and target elements are referenced via their ids.
*/
export interface SEdge extends SModelElement, Partial<Selectable>, Partial<Hoverable>, Partial<Fadeable> {
sourceId: string
targetId: string
routerKind?: string
routingPoints?: Point[]
}
/**
* A label can be attached to a node, edge, or port, and contains some text to be rendered in its view.
*/
export interface SLabel extends SShapeElement, Partial<Selectable>, Partial<Alignable> {
text: string
}
/**
* A compartment is used to group multiple child elements such as labels of a node. Usually a `vbox`
* or `hbox` layout is used to arrange these children.
*/
export interface SCompartment extends SShapeElement, Partial<LayoutContainer> {
}
/**
* A viewport has a scroll position and a zoom factor. Usually these properties are
* applied to the root element to enable navigating through the diagram.
*/
export interface Viewport extends Scrollable, Zoomable {
}
/**
* A scrollable element has a scroll position, which indicates the top left corner of the
* visible area.
*/
export interface Scrollable {
scroll: Point
}
export function isScrollable(element: SModelElement | Scrollable): element is Scrollable {
return hasOwnProperty(element, 'scroll');
}
/**
* A zoomable element can be scaled so it appears smaller or larger than its actual size.
* The zoom value 1 is the default scale where the content is drawn with its actual size.
*/
export interface Zoomable {
zoom: number
}
export function isZoomable(element: SModelElement | Zoomable): element is Zoomable {
return hasOwnProperty(element, 'zoom');
}
/**
* An element that can be placed at a specific location using its position property.
* Feature extension interface for `moveFeature`.
*/
export interface Locateable {
position: Point
}
/**
* Model elements that implement this interface have a position and a size.
*/
export interface BoundsAware extends Locateable {
size: Dimension
}
/**
* Feature extension interface for `layoutableChildFeature`. This is used when the parent
* element has a `layout` property (meaning it's a `LayoutContainer`).
*/
export interface LayoutableChild extends BoundsAware {
layoutOptions?: ModelLayoutOptions
}
/**
* Layout options of a `LayoutableChild`.
*/
export interface ModelLayoutOptions {
hAlign?: HAlignment
hGap?: number
vAlign?: VAlignment
vGap?: number
paddingTop?: number
paddingRight?: number
paddingBottom?: number
paddingLeft?: number
paddingFactor?: number
minWidth?: number
minHeight?: number
resizeContainer?: boolean
[key: string]: string | number | boolean | undefined
};
export type HAlignment = 'left' | 'center' | 'right';
export type VAlignment = 'top' | 'center' | 'bottom';
/**
* Used to identify model elements that specify a layout to apply to their children.
*/
export interface LayoutContainer extends LayoutableChild {
layout: LayoutKind
}
/**
* Type for the layout property of a `LayoutContainer`.
*/
export type LayoutKind = 'stack' | 'vbox' | 'hbox' | (string & {});
/**
* Feature extension interface for `alignFeature`.
* Used to adjust elements whose bounding box is not at the origin, e.g. labels
* or pre-rendered SVG figures.
*/
export interface Alignable {
alignment: Point
}
/**
* Feature extension interface for `selectFeature`. The selection status is often considered
* in the frontend views, e.g. by switching CSS classes.
*/
export interface Selectable {
selected: boolean
}
/**
* Feature extension interface for `hoverFeedbackFeature`. The hover feedback status is often
* considered in the frontend views, e.g. by switching CSS classes.
*/
export interface Hoverable {
hoverFeedback: boolean
}
/**
* Feature extension interface for `fadeFeature`. Fading is mostly used to animate when an element
* appears or disappears.
*/
export interface Fadeable {
opacity: number
}
/**
* Feature extension interface for `expandFeature`.
* Model elements that implement this interface can be expanded and collapsed.
*/
export interface Expandable {
expanded: boolean
}
/**
* Model elements implementing this interface can be displayed on a projection bar.
* _Note:_ If set, the projectedBounds property will be prefered over the model element bounds.
* Otherwise model elements also have to be `BoundsAware` so their projections can be shown.
*/
export interface Projectable {
projectionCssClasses: string[],
projectedBounds?: Bounds,
}
/**
* Feature extension interface for `edgeLayoutFeature`. This is often applied to
* {@link SLabel} elements to specify their placement along the containing edge.
*/
export interface EdgeLayoutable {
edgePlacement: EdgePlacement
}
export type EdgeSide = 'left' | 'right' | 'top' | 'bottom' | 'on';
/**
* Each label attached to an edge can be placed on the edge in different ways.
* With this interface the placement of such a single label is defined.
*/
export interface EdgePlacement {
/**
* true, if the label should be rotated to touch the edge tangentially
*/
rotate: boolean;
/**
* where is the label relative to the line's direction
*/
side: EdgeSide;
/**
* between 0 (source anchor) and 1 (target anchor)
*/
position: number;
/**
* space between label and edge/connected nodes
*/
offset: number;
/**
* where should the label be moved when move feature is enabled.
* 'edge' means the label is moved along the edge, 'free' means the label is moved freely, 'none' means the label can not be moved.
* Default is 'edge'.
*/
moveMode?: 'edge' | 'free' | 'none';
}
/**
* Buttons are elements that can react to clicks. A button handler can be registered in the frontend.
*/
export interface SButton extends SShapeElement {
pressed: boolean
enabled: boolean
}
/**
* An issue marker is used to display a symbol about an error or a warning attached to another model element.
*/
export interface SIssueMarker extends SShapeElement {
issues: SIssue[]
}
export type SIssueSeverity = 'error' | 'warning' | 'info';
export interface SIssue {
message: string
severity: SIssueSeverity
}
/**
* Root model element class for HTML content. Usually this is rendered with a `div` DOM element.
*/
export interface HtmlRoot extends SModelRoot {
classes?: string[]
}
/**
* Pre-rendered elements contain HTML or SVG code to be transferred to the DOM. This can be useful to
* render complex figures or to compute the view on the server instead of the client code.
*/
export interface PreRenderedElement extends SModelElement {
code: string
}
/**
* Same as PreRenderedElement, but with a position and a size.
*/
export interface ShapedPreRenderedElement extends PreRenderedElement {
position?: Point
size?: Dimension
}
/**
* A `foreignObject` element to be transferred to the DOM within the SVG.
*
* This can be useful to to benefit from e.g. HTML rendering features, such as line wrapping, inside of
* the SVG diagram. Note that `foreignObject` is not supported by all browsers and SVG viewers may not
* support rendering the `foreignObject` content.
*
* If no dimensions are specified in the schema element, this element will obtain the dimension of
* its parent to fill the entire available room. Thus, this element requires specified bounds itself
* or bounds to be available for its parent.
*/
export interface ForeignObjectElement extends ShapedPreRenderedElement {
/** The namespace to be assigned to the elements inside of the `foreignObject`. */
namespace: string
}