-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathNodeModel.ts
149 lines (128 loc) · 3.43 KB
/
NodeModel.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
import * as _ from 'lodash';
import { DiagramModel } from '../../models/DiagramModel';
import { PortModel } from '../port/PortModel';
import { LinkModel } from '../link/LinkModel';
import { Point, Rectangle } from '@projectstorm/geometry';
import {
BaseEntityEvent,
BaseModelListener,
BasePositionModel,
BasePositionModelGenerics,
DeserializeEvent
} from '@projectstorm/react-canvas-core';
import { DiagramEngine } from '../../DiagramEngine';
export interface NodeModelListener extends BaseModelListener {
positionChanged?(event: BaseEntityEvent<NodeModel>): void;
}
export interface NodeModelGenerics extends BasePositionModelGenerics {
LISTENER: NodeModelListener;
PARENT: DiagramModel;
}
export class NodeModel<G extends NodeModelGenerics = NodeModelGenerics> extends BasePositionModel<G> {
protected ports: { [s: string]: PortModel };
// calculated post rendering so routing can be done correctly
width: number;
height: number;
constructor(options: G['OPTIONS']) {
super(options);
this.ports = {};
this.width = 0;
this.height = 0;
}
getBoundingBox(): Rectangle {
return Rectangle.fromPointAndSize(this.getPosition(), this.width, this.height);
}
setPosition(point: Point): void;
setPosition(x: number, y: number): void;
setPosition(x: number | Point, y?: number): void {
const old = this.position;
if (x instanceof Point) {
super.setPosition(x);
} else {
super.setPosition(x, y);
}
//also update the port co-ordinates (for make glorious speed)
_.forEach(this.ports, (port) => {
port.setPosition(port.getX() + this.position.x - old.x, port.getY() + this.position.y - old.y);
});
}
deserialize(event: DeserializeEvent<this>) {
super.deserialize(event);
//deserialize ports
_.forEach(event.data.ports, (port: any) => {
let portOb = (event.engine as DiagramEngine).getFactoryForPort(port.type).generateModel({});
portOb.deserialize({
...event,
data: port
});
// the links need these
event.registerModel(portOb);
this.addPort(portOb);
});
}
serialize() {
return {
...super.serialize(),
ports: _.map(this.ports, (port) => {
return port.serialize();
})
};
}
doClone(lookupTable = {}, clone) {
// also clone the ports
clone.ports = {};
_.forEach(this.ports, (port) => {
clone.addPort(port.clone(lookupTable));
});
}
remove() {
super.remove();
_.forEach(this.ports, (port) => {
_.forEach(port.getLinks(), (link) => {
link.remove();
});
});
}
getPortFromID(id): PortModel | null {
for (var i in this.ports) {
if (this.ports[i].getID() === id) {
return this.ports[i];
}
}
return null;
}
getLink(id: string): LinkModel {
for (let portID in this.ports) {
const links = this.ports[portID].getLinks();
if (links[id]) {
return links[id];
}
}
}
getPort(name: string): PortModel | null {
return this.ports[name];
}
getPorts(): { [s: string]: PortModel } {
return this.ports;
}
removePort(port: PortModel) {
// clear the port from the links
for (let link of _.values(port.getLinks())) {
link.clearPort(port);
}
//clear the parent node reference
if (this.ports[port.getName()]) {
this.ports[port.getName()].setParent(null);
delete this.ports[port.getName()];
}
}
addPort(port: PortModel): PortModel {
port.setParent(this);
this.ports[port.getName()] = port;
return port;
}
updateDimensions({ width, height }: { width: number; height: number }) {
this.width = width;
this.height = height;
}
}