Newer
Older
import { Graph } from "./graph";
import { GraphElement } from "./graphelement";
import { NodeType } from "./nodetype";
import { Link } from "./link";
interface NodeProperties {
name: string;
description?: string;
icon?: string;
banner?: string;
video?: string;
references?: string[];
}
export interface NodeData extends NodeProperties {
/**
* This interfaces provides a data representation for a simple "flat" node without object pointers.
* Can be used to store nodes in JSON format.
*/
id: number;
type: string;
}
// Based on https://github.com/d3/d3-force#simulation_nodes
export interface SimNodeData extends NodeData {
/**
* This interface serves as a data representation for the history of the editor.
* Same as the JSON representation + additional parameters related to the simulation.
* This ensures that nodes from the history can are restored with the same visual state.
*/
index: number;
x: number;
y: number;
vx: number;
vy: number;
fx: number;
fy: number;
}
export interface GraphNode extends NodeProperties {
/**
* Node representation in a Graph. Contains values for easy traversal and force graph simulation properties.
*/
id: number;
type: NodeType;
// Properties used for graph traversal
neighbors: Node[];
links: Link[];
// Properties used by the force graph simulation
index?: number;
x?: number;
y?: number;
z?: number;
vx?: number;
vy?: number;
vz?: number;
fx?: number;
fy?: number;
fz?: number;
}
export class Node
extends GraphElement<NodeData, SimNodeData>
implements GraphNode
{
public name: string;
public description: string;
public type: NodeType;
public icon: string;
public banner: string;
public video: string;
public references: string[];
public neighbors: Node[];
public links: Link[];
// These parameters will be added by the force graph implementation
public index?: number;
public x?: number;
public y?: number;
public z?: number;
public vx?: number;
public vy?: number;
public vz?: number;
public fx?: number;
public fy?: number;
public fz?: number;
constructor(graph?: Graph) {
super(0, graph);
this.neighbors = [];
this.links = [];
}
public setType(typeId: number) {
const newType = this.graph.nameToObjectGroup.get(String(typeId)); // TODO
// Exists?
if (newType === undefined) {
return;
}
this.type = newType;
}
public delete() {
return this.graph.deleteNode(this.id);
}
/**
* Connects this node to a given node. Only works if they are in the same graph.
* @param node Other node to connect.
* @returns The created link, if successful, otherwise undefined.
*/
public connect(node: Node): Link {
if (this.graph !== node.graph) {
throw new Error("The connected nodes are not on the same graph!");
}
return this.graph.createLink(this.id, node.id);
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
}
public toJSONSerializableObject(): NodeData {
return {
id: this.id,
name: this.name,
description: this.description,
icon: this.icon,
banner: this.banner,
video: this.video,
references: this.references,
type: this.type.name,
};
}
public toHistorySerializableObject(): SimNodeData {
return {
...this.toJSONSerializableObject(),
index: this.index,
x: this.x,
y: this.y,
vx: this.vx,
vy: this.vy,
fx: this.fx,
fy: this.fy,
};
}
public fromSerializedObject(data: NodeData | SimNodeData): Node {
Object.assign(this, data);
this.type = undefined; // Remove string type again if undefined as it may be a string.
return this;
}
public toString(): string {
return this.name;
}
}