Skip to content
Snippets Groups Projects
link.ts 3.2 KiB
Newer Older
import { GraphElement } from "./graphelement";
import { Graph } from "./graph";
import { Node } from "./node";
import { GLOBAL_PARAMS } from "../helper/serializableitem";

const LINK_PARAMS = ["source", "target", ...GLOBAL_PARAMS];
const LINK_SIM_PARAMS = ["index"];

export class Link extends GraphElement {
    public source: Node;
    public target: Node;

    private _sourceId: number;
    private _targetId: number;

    constructor(graph: Graph = undefined) {
        super(graph);
        this.isLink = true;
    }

    /**
     * Id of the source node.
     * @returns Source id.
     */
    public get sourceId(): number {
        if (this.source == undefined) {
            return this._sourceId;
        }

        return this.source.id;
    }

    /**
     * Removes stored node object and just saves the id instead.
     * @param value New source id value.
     */
    public set sourceId(value: number) {
        this._sourceId = value;
        this.source = undefined;
    }

    /**
     * Id of the target node.
     * @returns Target id.
     */
    public get targetId(): number {
        if (this.target == undefined) {
            return this._targetId;
        }

        return this.target.id;
    }

    /**
     * Removes stored node object and just saves the id instead.
     * @param value New target id value.
     */
    public set targetId(value: number) {
        this._targetId = value;
        this.target = undefined;
    }

    public delete() {
        return this.graph.deleteLink(this);
    }

    public add(graph: Graph = this.graph) {
        this.graph = graph;
        if (this.graph == undefined) {
            return false;
        }

        return this.graph.addLink(this);
    }

    /**
     * Determines if the given node is part of the link structure.
     * @param node Node to check for.
     * @returns True, if node is either source or target node of link.
     */
    public contains(node: Node): boolean {
        return this.source === node || this.target === node;
    }

    public serialize(): any {
        return this.serializeProperties(LINK_PARAMS);
    }

    public getCleanInstance(): any {
        return {
            ...this.serialize(),
            ...this.serializeProperties(LINK_SIM_PARAMS),

    public static parse(raw: any): Link {
        const link: Link = new Link();

        if (isNaN(Number(raw.source))) {
            // Source not given as id, but probably as node object
            link.sourceId = raw.source.id;
            link.targetId = raw.target.id;
        } else {
            link.sourceId = Number(raw.source);
            link.targetId = Number(raw.target);
        }

        // Try to parse simulation parameters
        LINK_SIM_PARAMS.forEach((param) => {
            if (raw[param] === undefined) {
                return;
            }

            (link as any)[param] = raw[param];
        });

    public toString(): string {
        let source: any = this.source;
        let target: any = this.target;

        if (this.source == undefined || this.target == undefined) {
            source = this.sourceId;
            target = this.targetId;
        }
        return source.toString() + " -> " + target.toString();
    }