Skip to content
Snippets Groups Projects
Commit f896d95b authored by Maximilian Giller's avatar Maximilian Giller :squid:
Browse files

Refined graph implementation

parent 2500cabd
No related branches found
No related tags found
1 merge request!2Implemented editor in the react framework
Pipeline #56353 failed
......@@ -3,22 +3,59 @@ import {Link} from "./link";
import {NodeType} from "./nodetype";
import {Node} from "./node";
import {GLOBAL_PARAMS} from "../helper/serializableitem";
import { GraphElement } from "./graphelement";
const GRAPH_PARAMS = ["nodes", "links", "types", ...GLOBAL_PARAMS];
const GRAPH_PARAMS = [...GLOBAL_PARAMS];
const GRAPH_DATA_PARAMS = ["nodes", "links", "types"];
type GraphData = { nodes: Node[], links: Link[], types: NodeType[] };
export class Graph extends ManagedData {
public nodes: Node[];
public links: Link[];
public types: NodeType[];
public data: GraphData;
private nextNodeId: number = 0;
private nextLinkId: number = 0;
private nextTypeId: number = 0;
// Callbacks
public onChangeCallbacks: { (data: any): void; } [];
constructor(data: any) {
constructor(data: GraphData) {
super(data);
this.onChangeCallbacks = [];
// TODO: Parse all node types
this.prepareIds(data);
}
/**
* Determines the highest, used ids for GraphElements in data for later use.
* @param data Data to analyse.
*/
private prepareIds(data: GraphData) {
if (data.links.length > 0) {
this.nextLinkId = this.getHighestId(data.links) + 1;
}
if (data.nodes.length > 0) {
this.nextNodeId = this.getHighestId(data.nodes) + 1;
}
if (data.types.length > 0) {
this.nextTypeId = this.getHighestId(data.types) + 1;
}
}
/**
* Finds the highest id from a list of graph elements.
* @param elements List of elements containing element with highest id.
* @returns Highest id in list.
*/
private getHighestId(elements: GraphElement[]): number {
let highest: number = 0;
elements.forEach((element) => {
if (highest < element.id) {
highest = element.id;
}
});
return highest;
}
/**
......@@ -33,7 +70,6 @@ export class Graph extends ManagedData {
* Triggers change event on data-redo.
*/
protected onRedo() {
// TODO: Actually read new data state
this.triggerOnChange();
}
......@@ -41,19 +77,33 @@ export class Graph extends ManagedData {
* Triggers change event on data-undo.
*/
protected onUndo() {
// TODO: Actually read new data state
this.triggerOnChange();
}
protected storableData(data: any): any {
// TODO: Ideally use data parameter
return {
...this.serialize()
};
protected storableData(data: GraphData): any {
let clean: GraphData;
clean.links = data.links.map((link) => link.getCleanInstance());
clean.nodes = data.nodes.map((node) => node.getCleanInstance());
clean.types = data.types.map((type) => type.getCleanInstance());
return clean;
}
serialize(): any {
return this.serializeProperties(GRAPH_PARAMS);
return this.serializeData(this.data);
}
/**
* Takes a data object and serializes it.
* @param data GraphData object to serialize.
* @returns Serialized data.
*/
private serializeData(data: GraphData) : any {
return {
...this.serializeProperties(GRAPH_PARAMS),
...this.serializeProperties(GRAPH_DATA_PARAMS, data),
}
}
/**
......@@ -62,12 +112,15 @@ export class Graph extends ManagedData {
* @returns True, if successful.
*/
public addNode(node: Node) {
if (this.nodes.includes(node)) {
if (this.data.nodes.includes(node)) {
return true; // Already exists in graph.
}
// TODO: Maybe set node id
this.nodes.push(node);
// Update id
node.id = this.nextNodeId;
this.nextNodeId += 1;
this.data.nodes.push(node);
this.triggerOnChange();
// TODO: Use toString implementation of node
......@@ -82,11 +135,11 @@ export class Graph extends ManagedData {
* @returns True, if successful.
*/
public deleteNode(node: Node): boolean {
if (!this.nodes.includes(node)) {
if (!this.data.nodes.includes(node)) {
return true; // Doesn't even exist in graph to begin with.
}
this.nodes.filter((n: Node) => n !== node);
this.data.nodes.filter((n: Node) => n !== node);
try {
// No save points should be created when deleting the links
......@@ -113,12 +166,15 @@ export class Graph extends ManagedData {
* @returns True, if successful.
*/
public addLink(link: Link): boolean {
if (this.links.includes(link)) {
if (this.data.links.includes(link)) {
return true; // Already exists in graph.
}
// TODO: Maybe set link id
this.links.push(link);
// Updateid
link.id = this.nextLinkId;
this.nextLinkId += 1;
this.data.links.push(link);
this.triggerOnChange();
// TODO: Use toString implementation of link
......@@ -133,11 +189,11 @@ export class Graph extends ManagedData {
* @returns True, if successful.
*/
public deleteLink(link: Link): boolean {
if (!this.links.includes(link)) {
if (!this.data.links.includes(link)) {
return true; // Doesn't even exist in graph to begin with.
}
this.links.filter((l: Link) => l !== link);
this.data.links.filter((l: Link) => l !== link);
this.triggerOnChange();
// TODO: Use toString implementation of link
......
import {GLOBAL_PARAMS, SerializableItem} from "../helper/serializableitem";
import { Graph } from "./graph";
import { GraphElement } from "./graphelement";
const NODE_TYPE_PARAMS = ["name", "color", ...GLOBAL_PARAMS];
export class NodeType extends SerializableItem {
export class NodeType extends GraphElement {
public name: string;
public color: string;
serialize(): any {
return this.serializeProperties(NODE_TYPE_PARAMS);
}
public delete(): boolean {
// TODO: Implement
throw new Error("Function \"delete()\" has not been implemented.");
}
public add(graph: Graph = this.graph): boolean {
// TODO: Implement
throw new Error("Function \"add(graph)\" has not been implemented.");
}
public getCleanInstance(): any {
return this.serialize();
}
}
\ No newline at end of file
......@@ -6,7 +6,7 @@ import {array} from "prop-types";
export const GLOBAL_PARAMS = ["id"];
export class SerializableItem {
public id: string; // Serialized objects need to be unique.
public id: number; // Serialized objects need to be unique.
/**
* Returns the current object in its serialized form.
......@@ -27,10 +27,11 @@ export class SerializableItem {
/**
* A generic way to create a new object with all the desired parameters of the current one.
* @param params List of parameters to include in the new object.
* @param data The data object to be serialized. The current object by default.
* @protected
* @returns New object containing all the desired properties.
*/
protected serializeProperties(params: string[]): any {
protected serializeProperties(params: string[], data: any = this): any {
const serialized: any = {};
params.forEach((param) => {
......
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