import { Element } from './Element'; import { Edge } from './Edge'; import { Node } from './Node'; import { GraphStyles, NodeStyles } from './Styles'; import { Color } from './Color'; interface NodeOptions { name: string; label: string; style: NodeStyles; color: Color; } export class Graph extends Element { public children: Array = []; public nodes: Array = []; public is_root = false; public edges: Array = []; public style?: GraphStyles; public color?: Color; // eslint-disable-next-line @typescript-eslint/naming-convention public toString (): string { const header = this.parent ? `subgraph cluster_${this.full_name}` : `digraph ${this.full_name}`; const attributes = []; if (this.color) attributes.push ({ name: 'color', value: this.color.toString () }); if (this.style) attributes.push ({ name: 'style', value: this.style.toString () }); let attrs = `\n${attributes.map ((v) => `${v.name} = ${v.value}`) .join ('\n')}\n`; let children = `\n${this.children.map ((c) => c.toString ()) .join ('\n')}\n`; let nodes = `\n${this.nodes.map ((c) => c.toString ()) .join ('\n')}\n`; let edges = `\n${this.edges.map ((c) => c.toString ()) .join ('\n')}\n`; if (attrs === '\n\n') attrs = ''; if (children === '\n\n') children = ''; if (nodes === '\n\n') nodes = ''; if (edges === '\n\n') edges = ''; const indented = `${attrs}${children}${nodes}${edges}` .replace (/\n$/u, '') .replace (/^/gmu, ' ') .split ('\n') .map ((v) => v.trimRight ()) .join ('\n'); return `${header} {${indented}\n}` .replace (/^\s+$/gmu, ''); } public add_node (constructor: ((n: Node) => void) | string): string { const node = new Node ('unnamed', this.full_name); if (typeof constructor === 'string') { node.name = constructor; node.label = constructor; } else { constructor (node); } this.nodes.push (node); return node.full_name; } public add_graph (constructor: ((g: Graph) => void) | string): string { const graph = new Graph ('unnamed', this.full_name); if (typeof constructor === 'string') graph.name = constructor; else constructor (graph); this.children.push (graph); return graph.full_name; } public add_edge (origin: string, target: string): void { this.edges.push (new Edge (origin, target)); } }