trassel
Version:
Graph computing in JavaScript
219 lines (218 loc) • 12.8 kB
TypeScript
/**
* The data store class is responsible to storing and managing all edges and nodes.
* The data store can execute computations such as bringing nodes offline from the graph
* or computing components and paths.
*/
export default class DataManager {
/**
* Constructor
* @param {import("./model/ibasicnode").IBasicNode[]} nodes
* @param {import("./model/ibasicnode").IBasicEdge[]} edges
*/
constructor(nodes?: import("./model/ibasicnode").IBasicNode[], edges?: import("./model/ibasicnode").IBasicEdge[]);
/**
* All Nodes in the data manager regardless of online/offline status
* @type {import("./model/nodeid").NodeID[]} */
allNodes: import("./model/nodeid").NodeID[];
/**
* All edges in the data manager regardless of online/offline status
* @type {import("./model/ibasicedge").IBasicEdge[]} */
allEdges: import("./model/ibasicedge").IBasicEdge[];
/**
* A set that contains all currently online nodes. Used for example when we want to process a large dataset
* but only want to expose a small subset of data to an application, renderer or other process.
* @type {Set<import("./model/nodeid").NodeID>} */
onlineNodes: Set<import("./model/nodeid").NodeID>;
/**
* A lookup table for node objects. Generally "nodes" in the data manager are just IDs
* @type {Map<import("./model/nodeid").NodeID, import("./model/ibasicnode").IBasicNode>} */
nodeLookupMap: Map<import("./model/nodeid").NodeID, import("./model/ibasicnode").IBasicNode>;
/**
* A lookup table where the keys are sourceNodes and targets are targetNodes, their full weight and all relevant edge objects.
* @type {Map<import("./model/nodeid").NodeID, { id: import("./model/nodeid").NodeID, edges: import("./model/ibasicedge").IBasicEdge[], weight: number }[]>} */
sourceToTargetMap: Map<import("./model/nodeid").NodeID, {
id: import("./model/nodeid").NodeID;
edges: import("./model/ibasicedge").IBasicEdge[];
weight: number;
}[]>;
/**
* A lookup table where the keys are targetNodes and targets are sourceNodes, their full weight and all relevant edge objects.
* @type {Map<import("./model/nodeid").NodeID, { id: import("./model/nodeid").NodeID, edges: import("./model/ibasicedge").IBasicEdge[], weight: number }[]>} */
targetToSourceMap: Map<import("./model/nodeid").NodeID, {
id: import("./model/nodeid").NodeID;
edges: import("./model/ibasicedge").IBasicEdge[];
weight: number;
}[]>;
/**
* A lookup table for undirected edges (basically merging sourceToTarget and targetToSource.
* @type {Map<import("./model/nodeid").NodeID, { id: import("./model/nodeid").NodeID, edges: import("./model/ibasicedge").IBasicEdge[], weight: number }[]>} */
nodeToNeighborsMap: Map<import("./model/nodeid").NodeID, {
id: import("./model/nodeid").NodeID;
edges: import("./model/ibasicedge").IBasicEdge[];
weight: number;
}[]>;
/**
* Edge indexes mapping an edge to how many other edges share the same sources and targets and what index it has.
* This information is useful for renderers to determine angles and bends of edges to minimize overlap.
* E.g. if there are two edges connecting node X and node Y, then these would overlap visually.
* @type {Map<string, {total: number, index: number}>}
*/
edgeIndexes: Map<string, {
total: number;
index: number;
}>;
/**
* This is a counter for each node of how many offline edges in the graph connects with it.
* This information is useful to renderers when displaying partial information, and showing meta data about hidden points.
* E.g. a badge on a node in the graph with "42" on it, indicating 42 hidden connections.
* @type {Map<import("./model/nodeid").NodeID, {sourceNode: number, targetNode: number, internal: number}>}
*/
offlineEdgeCounter: Map<import("./model/nodeid").NodeID, {
sourceNode: number;
targetNode: number;
internal: number;
}>;
/**
* Updates the data in the manager
* @param {import("./model/ibasicnode").IBasicNode[]} nodes - New nodes
* @param {import("./model/ibasicedge").IBasicEdge[]} edges - New Edges
*/
updateNodesAndEdges(nodes: import("./model/ibasicnode").IBasicNode[], edges: import("./model/ibasicedge").IBasicEdge[]): void;
/**
* Updates all edge meta data structures.
*/
updateMetaData(): void;
/**
* Computes online nodes
* @returns {import("./model/ibasicnode").IBasicNode[]} node
*/
getOnlineNodes(): import("./model/ibasicnode").IBasicNode[];
/**
* Computes offline nodes
* @returns {import("./model/ibasicnode").IBasicNode[]} node
*/
getOfflineNodes(): import("./model/ibasicnode").IBasicNode[];
/**
* Computes online edges
* @returns {import("./model/ibasicedge").IBasicEdge[]} edge
*/
getOnlineEdges(): import("./model/ibasicedge").IBasicEdge[];
/**
* Computes offline edges
* @returns {import("./model/ibasicedge").IBasicEdge[]} edge
*/
getOfflineEdges(): import("./model/ibasicedge").IBasicEdge[];
/**
* Checks if an edge is online
* @param {import("./model/ibasicnode").IBasicEdge} edge
* @returns {boolean}
*/
isEdgeOnline(edge: any): boolean;
/**
* Checks if a node is online
* @param {string} nodeID
* @returns {boolean}
*/
isNodeOnline(nodeID: string): boolean;
/**
* Brings the list of node IDs offline
* @param {import("./model/nodeid").NodeID[]} nodeIDs
*/
bringNodesOffline(nodeIDs: import("./model/nodeid").NodeID[]): void;
/**
* Brings the list of node IDs online
* @param {import("./model/nodeid").NodeID[]} nodeIDs
*/
bringNodesOnline(nodeIDs: import("./model/nodeid").NodeID[]): void;
bringAllNodesOffline(): void;
bringAllNodesOnline(): void;
/**
* Retrieves all neighbors for a given nodeID
* @param {import("./model/nodeid").NodeID} nodeID - ID od the node neighbors should be retrieved for
* @param {boolean} isDirected - Only traverse edges where the input node is the sourceNode
* @param {boolean} useOnlyOnline - Only traverse neighbors that are online
* @param {boolean} ignoreInternalEdges - Ignore self-edges
* @returns {import("./model/nodeid").NodeID[]}
*/
getNeighbors(nodeID: import("./model/nodeid").NodeID, isDirected?: boolean, useOnlyOnline?: boolean, ignoreInternalEdges?: boolean): import("./model/nodeid").NodeID[];
/**
* Computes collateral nodes in implodes or explode operations from a root node (I.e. bringing connected neighbors online/offline)
* This function will not apply any changes, but return an array with affected nodes
* The function exists specifically to help applications that implement implode/explode functionality in graphs
* and need to compute what nodes should be brough online/offline.
* @param {import("./model/nodeid").NodeID} nodeID
* @param {boolean} isBringOnline - If true neighbors will be brought online otherwise offline
* @param {boolean} isDirected - If true then operation will be directed
* @param {"single"|"recursive"|"leafs"} mode - Single means all neighbors are affected, leafs means only neighbors with no other neighbors are affected, recursive means neighbors recursively are affected.
* @returns {import("./model/nodeid").NodeID[]} - Affected nodes
*/
computeImplodeOrExplodeNode(nodeID: import("./model/nodeid").NodeID, isBringOnline?: boolean, isDirected?: boolean, mode?: "single" | "recursive" | "leafs"): import("./model/nodeid").NodeID[];
/**
* Specifically meant to support renderers in determining optimal target positions for nodes that are being brough online.
* Accepts an array of node IDs and origin coordinates where the nodes should be animated from.
* Returns an array of vertices with optimal positions based on other neighbors present in the graph, or in the case of leafs a circle around the origin.
* Note(!) that this function expects all nodes and edges to have been initialized into GraphNodes and GraphEdges in order to compute this information.
* @param {import("./model/nodeid").NodeID[]} nodeIDs - Array of node IDs
* @param {number} distance - Default distance from origin position to put nodes (for non-average values only!)
* @param {number} originX - Start position for the transition
* @param {number} originY - Start position for the transition
* @returns {{id: import("./model/nodeid").NodeID, x: number, y: numer}[]} - Target coordinates
*/
stageNodePositions(nodeIDs?: import("./model/nodeid").NodeID[], distance?: number, originX?: number, originY?: number): {
id: import("./model/nodeid").NodeID;
x: number;
y: numer;
}[];
/**
* Computes the shortest path from one node to another. Returns an array with the nodeIDs, or null if there is no path.
* @param {import("./model/nodeid").NodeID} startNode - Node ID where the road starts
* @param {import("./model/nodeid").NodeID} endNode - Node ID where the road ends
* @param {boolean} useOnlyOnline - If true the shortest path will only be computed for live nodes
* @param {boolean} isDirected - If true then operation will be directed
* @return {import("./model/nodeid").NodeID[]} - Array of node IDs from startnode to endnode containing the (a) shortest path
*/
findShortestPathUnweighted(startNode: import("./model/nodeid").NodeID, endNode: import("./model/nodeid").NodeID, useOnlyOnline?: boolean, isDirected?: boolean): import("./model/nodeid").NodeID[];
/**
* Computes the shortest path from one node to another. Returns an array with the nodeIDs, or null if there is no path.
* This is basically Dijkstra's algorithm:
* https://en.wikipedia.org/wiki/Dijkstra's_algorithm
* @param {import("./model/nodeid").NodeID} startNode - Node ID where the road starts
* @param {import("./model/nodeid").NodeID} endNode - Node ID where the road ends
* @param {boolean} useOnlyOnline - If true the shortest path will only be computed for live nodes
* @param {boolean} isDirected - If true then operation will be directed
* @param {boolean} aggregateEdgeWeights - If true then weights for all edges between a set of nodes are aggregated and treated as a single edge
* @return {{id: import("./model/nodeid").NodeID, cost: number}[]} - Array of nodes and costs from startnode to endnode containing the (a) cheapest path
*/
findShortestPathWeighted(startNode: import("./model/nodeid").NodeID, endNode: import("./model/nodeid").NodeID, useOnlyOnline?: boolean, isDirected?: boolean, aggregateEdgeWeights?: boolean): {
id: import("./model/nodeid").NodeID;
cost: number;
}[];
/**
* Computes strongly connected components in the graph.
* Basically an implementation of Kosoraju's algorithm.
* https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
* @param {boolean} useOnlyOnline - If true the shortest path will only be computed for live nodes
* @return {("./model/nodeid").NodeID[][]} - Strongly connected components.
*/
computeStronglyConnectedComponents(useOnlyOnline?: boolean): ("./model/nodeid");
/**
* Executes a breadth-first search in the graph given a start node.
* Each node encountered will be handed off to a callback function provided,
* If the callback function returns true then that branch will be terminated.
* @param {import("./model/nodeid").NodeID} startNode
* @param {(import("./model/nodeid").NodeID) => void|true} callback
* @param {boolean} useOnlyOnline - If true only online nodes will be processed
* @param {boolean} isDirected - If true then traversal will be directed
*/
BFS(startNode: import("./model/nodeid").NodeID, callback: any, useOnlyOnline?: boolean, isDirected?: boolean): void;
/**
* Executes a depth-first search in the graph given a start node.
* Each node encountered will be handed off to a callback function provided,
* If the callback function returns true then that branch will be terminated.
* @param {import("./model/nodeid").NodeID} startNode
* @param {(import("./model/nodeid").NodeID) => void|true} callback
* @param {boolean} useOnlyOnline - If true only online nodes will be processed
* @param {boolean} isDirected - If true then traversal will be directed
*/
DFS(startNode: import("./model/nodeid").NodeID, callback: any, useOnlyOnline?: boolean, isDirected?: boolean): void;
}