import { LineMaterial } from "three-fatline"; export interface GraphNode extends NodeData { x: number; y: number; z: number; vx: number; vy: number; vz: number; fx: number; fy: number; fz: number; color: string; } export interface GraphLink extends LinkData { material?: LineMaterial; } export interface LinkData { source: NodeData; target: NodeData; type?: string; } export interface NodeData { id: string; name: string; description?: string; type?: string; video?: string; neighbors: NodeData[]; links: LinkData[]; } export interface Coordinate { x: number; y: number; z: number; } export class Graph { public nodes: NodeData[]; public links: LinkData[]; private idToNode: Map<string, NodeData>; constructor(nodes: NodeData[], links: LinkData[]) { this.nodes = nodes; this.links = links; this.idToNode = new Map<string, NodeData>(); nodes.forEach((node) => { this.idToNode.set(node.id, node); }); this.updateNodeData(); } resetNodeData() { for (const node of this.nodes) { node.neighbors = []; node.links = []; } } /** * Updates the graph data structure to contain additional values. * Creates a 'neighbors' and 'links' array for each node object. */ updateNodeData() { this.resetNodeData(); this.links.forEach((link) => { const a = link.source; const b = link.target; a.neighbors.push(b); b.neighbors.push(a); a.links.push(link); b.links.push(link); }); } node(id: string): NodeData { return this.idToNode.get(id); } /** * Returns an array containing the different edge types of the graph. * @returns {*[]} */ getLinkClasses(): string[] { const linkClasses: string[] = []; this.links.forEach((link) => linkClasses.push(link.type)); return [...new Set(linkClasses)].map((c) => String(c)); } getNodeClasses(): string[] { const nodeClasses: string[] = []; this.nodes.forEach((node) => nodeClasses.push(node.type)); return [...new Set(nodeClasses)].map((c) => String(c)); } view( nodeTypes: Map<string, boolean>, linkTypes: Map<string, boolean> ): Graph { return new Graph( this.nodes.filter((l) => nodeTypes.get(l.type)), this.links.filter((l) => linkTypes.get(l.type)) ); } }