diff --git a/src/editor/js/structures/graph/graph.ts b/src/editor/js/structures/graph/graph.ts index 2b7fc38a4869a942e313b0872b689354d47857bb..ccadd99f98741d380b98f0c3581592754d3c01c0 100644 --- a/src/editor/js/structures/graph/graph.ts +++ b/src/editor/js/structures/graph/graph.ts @@ -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 diff --git a/src/editor/js/structures/graph/nodetype.ts b/src/editor/js/structures/graph/nodetype.ts index c7a10697bc02b73ae2a0f4d12ac81cf6ef334c85..d2c56b48749ed8c51cbe5df89c542d861001aa1f 100644 --- a/src/editor/js/structures/graph/nodetype.ts +++ b/src/editor/js/structures/graph/nodetype.ts @@ -1,12 +1,28 @@ 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 diff --git a/src/editor/js/structures/helper/serializableitem.ts b/src/editor/js/structures/helper/serializableitem.ts index 672c164039edd6d180f00355d934477ca3b3f5d0..793400acc00c85586a9e4c81484336ac40600c01 100644 --- a/src/editor/js/structures/helper/serializableitem.ts +++ b/src/editor/js/structures/helper/serializableitem.ts @@ -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) => {