Skip to content
Snippets Groups Projects
graph.ts 3.38 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { Link } from "../common/graph/link";
    
    import { NodeType, NodeTypeData } from "../common/graph/nodetype";
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
    import { Node, NodeData, SimNodeData } from "../common/graph/node";
    
    import * as Common from "../common/graph/graph";
    
    import { History } from "../common/history";
    
    import { GraphContent, GraphData, SimGraphData } from "../common/graph/graph";
    
    
    export class DynamicGraph extends Common.Graph {
    
        public history: History<SimGraphData>;
    
    
        constructor(data?: GraphContent) {
            super(data);
    
            if (data != undefined) {
                this.history = new History<SimGraphData>(
                    this,
                    20,
                    "Created new graph."
                );
            }
        }
    
        public fromSerializedObject(data: GraphData | SimGraphData): DynamicGraph {
            super.fromSerializedObject(data);
    
            this.history = new History<SimGraphData>(
                this,
                20,
                "Created new graph."
            );
    
    
            return this;
    
        public createObjectGroup(data: NodeTypeData): NodeType {
            if (data.name == undefined) {
                data.name = "Unnamed";
    
            if (data.color == undefined) {
                data.color = "#000000";
    
            return super.createObjectGroup(data);
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
        public createNode(
            data?: NodeData | SimNodeData,
            x?: number,
            y?: number,
            vx?: number,
            vy?: number
        ): Node {
    
            if (data == undefined) {
                data = {
                    id: 0,
                    name: "Undefined",
    
                    type: this.objectGroups[0].id,
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
                    x: x,
                    y: y,
                    vx: vx,
                    vy: vy,
    
                };
            }
            return super.createNode(data);
        }
    
        getLink(
            sourceId: number,
            targetId: number,
            directionSensitive = true
        ): Link {
            return this.links.find((l) => {
                if (l.sourceId === sourceId && l.targetId === targetId) {
                    return true;
                }
    
                // Check other direction if allowed
                return (
                    !directionSensitive &&
                    l.sourceId === targetId &&
                    l.targetId === sourceId
                );
            });
        }
    
        public createLink(source: number, target: number): Link {
            const link = this.getLink(source, target, false);
            if (link !== undefined) {
                return link; // Already exists in graph.
            }
    
            return super.createLink(source, target);
        }
    
        /**
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
         * Goes over all nodes and finds the closest node based on distance.
    
         * @returns Closest node and distance. Undefined, if no closest node can be found.
         */
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
        public getClosestNode(
            x: number,
            y: number,
            exclude?: Node
        ): {
    
            node: Node;
            distance: number;
        } {
            // Iterate over all nodes, keep the one with the shortest distance
            let closestDistance = Number.MAX_VALUE;
            let closestNode: Node = undefined;
            this.nodes.forEach((node) => {
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
                if (node.equals(exclude)) {
    
    Matthias Konitzny's avatar
    Matthias Konitzny committed
                const currentDistance = Math.hypot(x - node.x, y - node.y);
    
    
                if (closestDistance > currentDistance) {
                    closestDistance = currentDistance;
                    closestNode = node;
                }
            });
    
            return { node: closestNode, distance: closestDistance };
        }
    }