Newer
Older
import { Link } from "../common/graph/link";
import { NodeType, NodeTypeData } from "../common/graph/nodetype";
import { Node, NodeData, SimNodeData } from "../common/graph/node";
import * as Common from "../common/graph/graph";
import { History } from "../common/history";
import { GraphContent, GraphData, SimGraphData } from "../common/graph/graph";
export class DynamicGraph extends Common.Graph {
public history: History<SimGraphData>;
constructor(data?: GraphContent) {
super(data);
if (data != undefined) {
this.history = new History<SimGraphData>(
this,
20,
"Created new graph."
);
}
}
public fromSerializedObject(data: GraphData | SimGraphData): DynamicGraph {
super.fromSerializedObject(data);
this.history = new History<SimGraphData>(
this,
20,
"Created new graph."
);
}
public createObjectGroup(data?: NodeTypeData): NodeType {
if (data == undefined) {
data = {
id: 0,
name: "Unnamed",
color: "#000000",
};
}
return super.createObjectGroup(data);
}
public createNode(
data?: NodeData | SimNodeData,
x?: number,
y?: number,
vx?: number,
vy?: number
): Node {
if (data == undefined) {
data = {
id: 0,
name: "Undefined",
type: this.objectGroups[0].id,
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
};
}
return super.createNode(data);
}
getLink(
sourceId: number,
targetId: number,
directionSensitive = true
): Link {
return this.links.find((l) => {
if (l.sourceId === sourceId && l.targetId === targetId) {
return true;
}
// Check other direction if allowed
return (
!directionSensitive &&
l.sourceId === targetId &&
l.targetId === sourceId
);
});
}
public createLink(source: number, target: number): Link {
const link = this.getLink(source, target, false);
if (link !== undefined) {
return link; // Already exists in graph.
}
return super.createLink(source, target);
}
/**
* Goes over all nodes and finds the closest node based on distance.
* @returns Closest node and distance. Undefined, if no closest node can be found.
*/
public getClosestNode(
x: number,
y: number,
exclude?: Node
): {
node: Node;
distance: number;
} {
// Iterate over all nodes, keep the one with the shortest distance
let closestDistance = Number.MAX_VALUE;
let closestNode: Node = undefined;
this.nodes.forEach((node) => {
return; // Don't compare to itself
}
const currentDistance = Math.hypot(x - node.x, y - node.y);
if (closestDistance > currentDistance) {
closestDistance = currentDistance;
closestNode = node;
}
});
return { node: closestNode, distance: closestDistance };
}
}