import { GraphElement } from "./graphelement"; import { Node } from "./node"; import { NodeType } from "./nodetype"; import { Graph } from "./graph"; export interface LinkData { source: number; target: number; type?: string; } export interface SimLinkData extends LinkData { index: number; } export interface GraphLink { id: number; source: Node; target: Node; type?: NodeType; // Properties used by the force graph simulation index?: number; } export class Link extends GraphElement<LinkData, SimLinkData> implements GraphLink { public source: Node; public target: Node; type?: NodeType; // These parameters will be added by the force graph implementation public index?: number; constructor(source?: Node, target?: Node, graph?: Graph) { super(0, graph); this.source = source; this.target = target; } /** * Id of the source node. * @returns Source id. */ public get sourceId(): number { return this.source.id; } /** * Id of the target node. * @returns Target id. */ public get targetId(): number { return this.target.id; } public delete() { return this.graph.deleteLink(this.id); } /** * 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 toJSONSerializableObject(): LinkData { return { source: this.source.id, target: this.target.id, }; } public toHistorySerializableObject(): SimLinkData { return { ...this.toJSONSerializableObject(), index: this.index }; } public toString(): string { return this.source.toString() + " -> " + this.target.toString(); } public isInitialized(): boolean { return ( super.isInitialized() && this.source != undefined && this.target != undefined ); } public equals(other: GraphElement<LinkData, SimLinkData>): boolean { if (other.constructor != this.constructor) { return false; } const link = other as Link; return ( link.sourceId === this.sourceId && link.targetId === this.targetId ); } }