Skip to content
Snippets Groups Projects
Commit f8c505ef authored by Matthias Konitzny's avatar Matthias Konitzny :fire:
Browse files

Simplified node, link and nodetype creation

parent b557e57e
No related branches found
No related tags found
No related merge requests found
...@@ -55,25 +55,29 @@ export class Graph ...@@ -55,25 +55,29 @@ export class Graph
this.initialized = false; this.initialized = false;
return; return;
} }
this.reset();
Object.assign(this, data); Object.assign(this, data);
this.nameToObjectGroup = new Map<string, NodeType>();
this.objectGroups.forEach((group) => this.objectGroups.forEach((group) =>
this.nameToObjectGroup.set(group.name, group) this.nameToObjectGroup.set(group.name, group)
); );
this.idToNode = new Map<number, Node>();
this.nodes.forEach((node) => { this.nodes.forEach((node) => {
this.idToNode.set(node.id, node); this.idToNode.set(node.id, node);
}); });
this.idToLink = new Map<number, Link>();
this.links.forEach((link) => { this.links.forEach((link) => {
this.idToLink.set(link.id, link); this.idToLink.set(link.id, link);
}); });
} }
private reset() {
this.nodes = [];
this.links = [];
this.nameToObjectGroup = new Map<string, NodeType>();
this.idToNode = new Map<number, Node>();
this.idToLink = new Map<number, Link>();
}
public toJSONSerializableObject(): GraphData { public toJSONSerializableObject(): GraphData {
return { return {
nodes: this.nodes.map((node) => node.toJSONSerializableObject()), nodes: this.nodes.map((node) => node.toJSONSerializableObject()),
...@@ -95,57 +99,24 @@ export class Graph ...@@ -95,57 +99,24 @@ export class Graph
} }
public fromSerializedObject(data: GraphData | SimGraphData): Graph { public fromSerializedObject(data: GraphData | SimGraphData): Graph {
let objectGroups: Array<NodeType>; this.reset();
if (data.objectGroups === undefined) { if (data.objectGroups === undefined) {
objectGroups = this.createObjectGroupsFromStrings(data.nodes); this.createObjectGroupsFromStrings(data.nodes);
} else { } else {
objectGroups = this.createObjectGroupsFromObjects( data.objectGroups.forEach((group) =>
data.objectGroups this.createObjectGroup(group.name, group.color)
); );
} }
this.nameToObjectGroup = new Map<string, NodeType>(); data.nodes.forEach((node) => this.createNode(node));
objectGroups.forEach((group) => data.links.forEach((link) => this.createLink(link.source, link.target));
this.nameToObjectGroup.set(group.name, group)
);
this.nodes = this.createNodes(data.nodes);
this.idToNode = new Map<number, Node>();
this.nodes.forEach((node) => {
this.idToNode.set(node.id, node);
});
this.links = data.links.map((link, i) => {
const l = new Link();
l.id = i;
l.source = this.idToNode.get(link.source);
l.target = this.idToNode.get(link.target);
return l;
});
this.idToLink = new Map<number, Link>();
this.links.forEach((link) => {
this.idToLink.set(link.id, link);
});
this.updateNodeData(); this.updateNodeData();
return this; return this;
} }
private createNodes(nodeJSONData: NodeData[]): Array<Node> {
const nodes: Array<Node> = [];
for (const nodeData of nodeJSONData) {
const node = new Node();
node.fromSerializedObject(nodeData);
node.type = this.nameToObjectGroup.get(nodeData.type);
node.neighbors = [];
node.links = [];
nodes.push(node);
}
return nodes;
}
private createObjectGroupsFromStrings(nodes: NodeData[]): Array<NodeType> { private createObjectGroupsFromStrings(nodes: NodeData[]): Array<NodeType> {
const objectGroups: NodeType[] = []; const objectGroups: NodeType[] = [];
const nodeClasses: string[] = []; const nodeClasses: string[] = [];
...@@ -153,26 +124,14 @@ export class Graph ...@@ -153,26 +124,14 @@ export class Graph
const nodeTypes = [...new Set(nodeClasses)].map((c) => String(c)); const nodeTypes = [...new Set(nodeClasses)].map((c) => String(c));
for (let i = 0; i < nodeTypes.length; i++) { for (let i = 0; i < nodeTypes.length; i++) {
const nodeType = new NodeType(); this.createObjectGroup(
nodeType.fromSerializedObject({ nodeTypes[i],
id: i, Config.COLOR_PALETTE[i % Config.COLOR_PALETTE.length]
name: nodeTypes[i], );
color: Config.COLOR_PALETTE[i % Config.COLOR_PALETTE.length],
});
} }
return objectGroups; return objectGroups;
} }
private createObjectGroupsFromObjects(
groups: NodeTypeData[]
): Array<NodeType> {
return groups.map((group) => {
const t = new NodeType();
t.fromSerializedObject(group);
return t;
});
}
/** /**
* Updates the graph data structure to contain additional values. * Updates the graph data structure to contain additional values.
* Creates a 'neighbors' and 'links' array for each node object. * Creates a 'neighbors' and 'links' array for each node object.
...@@ -197,53 +156,61 @@ export class Graph ...@@ -197,53 +156,61 @@ export class Graph
return this.idToNode.get(id); return this.idToNode.get(id);
} }
private checkNode(node: Node) { private addNode(node: Node) {
for (const neighbor of node.neighbors) { node.id = this.nodes.length;
if (this.idToNode.get(neighbor.id) === undefined) { this.nodes.push(node);
return false; this.idToNode.set(node.id, node);
}
}
for (const link of node.links) {
if (this.idToLink.get(link.id) === undefined) {
return false;
}
}
return node.isInitialized();
} }
private checkLink(link: Link) { public createNode(data?: NodeData): Node {
return ( const node = new Node(this);
link.isInitialized() && node.fromSerializedObject(data);
!( node.type = this.nameToObjectGroup.get(data.type);
this.idToNode.get(link.source.id) === undefined || node.neighbors = [];
this.idToNode.get(link.target.id) === undefined node.links = [];
) this.addNode(node);
); return node;
} }
public addNode(node: Node) { public createLink(source: number, target: number): Link {
node.id = this.nodes.length; if (source === target) {
console.warn(
"Attempting to create a link where source equals target"
);
return;
}
if (!this.checkNode(node)) { const sourceNode = this.idToNode.get(source);
return false; const targetNode = this.idToNode.get(target);
if (sourceNode === undefined || targetNode === undefined) {
console.warn("Tried to create a link between nonexisting nodes!");
return;
} }
this.nodes.push(node); const link = new Link(sourceNode, targetNode, this);
this.idToNode.set(node.id, node); sourceNode.links.push(link);
return true; targetNode.links.push(link);
this.addLink(link);
return link;
} }
public addLink(link: Link) { public createObjectGroup(name?: string, color?: string): NodeType {
link.id = this.links.length; const group = new NodeType(name, color, this);
this.addObjectGroup(group);
return group;
}
if (!this.checkLink(link)) { private addObjectGroup(group: NodeType) {
return false; group.id = this.objectGroups.length;
} this.objectGroups.push(group);
this.nameToObjectGroup.set(group.name, group); // TODO: Replace with id
}
private addLink(link: Link) {
link.id = this.links.length;
this.links.push(link); this.links.push(link);
this.idToLink.set(link.id, link); this.idToLink.set(link.id, link);
return true;
} }
public deleteLink(id: number) { public deleteLink(id: number) {
......
...@@ -35,8 +35,10 @@ export class Link ...@@ -35,8 +35,10 @@ export class Link
// These parameters will be added by the force graph implementation // These parameters will be added by the force graph implementation
public index?: number; public index?: number;
constructor(graph: Graph = undefined) { constructor(source?: Node, target?: Node, graph?: Graph) {
super(0, graph); super(0, graph);
this.source = source;
this.target = target;
} }
/** /**
......
...@@ -82,7 +82,7 @@ export class Node ...@@ -82,7 +82,7 @@ export class Node
public fx?: number; public fx?: number;
public fy?: number; public fy?: number;
constructor(graph: Graph = undefined) { constructor(graph?: Graph) {
super(0, graph); super(0, graph);
this.neighbors = []; this.neighbors = [];
this.links = []; this.links = [];
...@@ -127,16 +127,7 @@ export class Node ...@@ -127,16 +127,7 @@ export class Node
throw new Error("The connected nodes are not on the same graph!"); throw new Error("The connected nodes are not on the same graph!");
} }
const link = new Link(this.graph); return this.graph.createLink(this.id, node.id);
link.source = this;
link.target = node;
if (this.graph.addLink(link)) {
this.neighbors.push(node);
node.neighbors.push(this);
return link;
}
} }
public toJSONSerializableObject(): NodeData { public toJSONSerializableObject(): NodeData {
......
import { GraphElement } from "./graphelement"; import { GraphElement } from "./graphelement";
import { Node } from "./node";
import { Graph } from "./graph";
export interface NodeTypeData { export interface NodeTypeData {
id: number; id: number;
...@@ -14,6 +16,12 @@ export class NodeType ...@@ -14,6 +16,12 @@ export class NodeType
public name: string; public name: string;
public color: string; public color: string;
constructor(name?: string, color?: string, graph?: Graph) {
super(0, graph);
this.name = name;
this.color = color;
}
toJSONSerializableObject(): NodeTypeData { toJSONSerializableObject(): NodeTypeData {
return { id: this.id, name: this.name, color: this.color }; return { id: this.id, name: this.name, color: this.color };
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment