75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { Element } from './Element';
|
|
import { Edge } from './Edge';
|
|
import { Node } from './Node';
|
|
import { GraphStyles } from './Styles';
|
|
import { Color } from './Color';
|
|
|
|
export class Graph extends Element {
|
|
public children: Array<Graph> = [];
|
|
public nodes: Array<Node> = [];
|
|
public is_root = false;
|
|
public edges: Array<Edge> = [];
|
|
public style?: GraphStyles;
|
|
public color?: Color;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
public toString (level = 0): 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 (level + 1))
|
|
.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 = '';
|
|
|
|
return `${header} {${attrs}${children}${nodes}${edges}}`
|
|
.replace (/\n/gu, `\n${' '.repeat (level)}`)
|
|
.replace (/^\s+$/gmu, '');
|
|
}
|
|
|
|
public add_node (constructor: ((g: Node) => void) | string): void {
|
|
if (typeof constructor === 'string') {
|
|
this.nodes.push (new Node (constructor, this.full_name, constructor));
|
|
return;
|
|
}
|
|
const node = new Node ('unnamed', this.full_name);
|
|
constructor (node);
|
|
this.nodes.push (node);
|
|
}
|
|
|
|
public add_graph (constructor: ((g: Graph) => void) | string): void {
|
|
if (typeof constructor === 'string') {
|
|
this.children.push (new Graph (constructor, this.full_name));
|
|
return;
|
|
}
|
|
const graph = new Graph ('unnamed', this.full_name);
|
|
constructor (graph);
|
|
this.children.push (graph);
|
|
}
|
|
|
|
public add_edge (origin: string, target: string): void {
|
|
this.edges.push (
|
|
new Edge (`${this.full_name}_${origin}`, `${this.full_name}_${target}`)
|
|
);
|
|
}
|
|
}
|