Skip to content
Snippets Groups Projects
node.ts 4.01 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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;
    
    }
    
    // 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;
    
    }
    
    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 vx?: number;
        public vy?: number;
    
        public fx?: number;
        public fy?: 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);
    
        }
    
        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;
        }
    }