110 lines
3.3 KiB
TypeScript
Raw Normal View History

2020-05-17 17:17:39 +02:00
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of graphviz-builder which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
2023-03-25 14:17:58 +01:00
import { GraphStyles } from '../enums/Styles';
2020-05-06 20:24:37 +02:00
import { GraphLayouts } from '../enums/GraphLayouts';
2020-04-24 12:02:32 +02:00
import { Element } from './Element';
2020-04-17 15:43:34 +02:00
import { Edge } from './Edge';
2020-04-24 12:02:32 +02:00
import { Node } from './Node';
2020-04-24 17:01:26 +02:00
import { Color } from './Color';
2020-04-17 15:43:34 +02:00
2020-04-24 12:02:32 +02:00
export class Graph extends Element {
2020-04-17 15:43:34 +02:00
public children: Array<Graph> = [];
2020-04-24 12:02:32 +02:00
public nodes: Array<Node> = [];
2020-04-17 15:43:34 +02:00
public is_root = false;
2020-04-24 12:02:32 +02:00
public edges: Array<Edge> = [];
2020-04-24 17:01:26 +02:00
public style?: GraphStyles;
public color?: Color;
2020-04-28 08:39:57 +02:00
public directional = true;
2020-04-28 12:30:45 +02:00
public overlap?: boolean | string;
public splines?: boolean | string;
2020-04-28 10:52:02 +02:00
public layout?: GraphLayouts;
2020-04-17 15:43:34 +02:00
2020-04-28 10:52:02 +02:00
private get attributes (): Array<{name: string; value: string}> {
2020-04-24 17:01:26 +02:00
const attributes = [];
2020-04-28 10:52:02 +02:00
2020-04-28 10:58:37 +02:00
if (typeof this.color !== 'undefined')
2020-04-24 17:01:26 +02:00
attributes.push ({ name: 'color', value: this.color.toString () });
2020-04-28 10:58:37 +02:00
if (typeof this.style !== 'undefined')
2020-04-24 17:01:26 +02:00
attributes.push ({ name: 'style', value: this.style.toString () });
2020-04-28 10:58:37 +02:00
if (typeof this.overlap !== 'undefined')
2020-04-28 10:52:02 +02:00
attributes.push ({ name: 'overlap', value: this.overlap.toString () });
2020-04-28 10:58:37 +02:00
if (typeof this.splines !== 'undefined')
2020-04-28 10:52:02 +02:00
attributes.push ({ name: 'splines', value: this.splines.toString () });
2020-04-28 10:58:37 +02:00
if (typeof this.layout !== 'undefined')
2020-04-28 10:52:02 +02:00
attributes.push ({ name: 'layout', value: this.layout.toString () });
return attributes;
}
2020-04-24 17:01:26 +02:00
2020-04-28 10:52:02 +02:00
// eslint-disable-next-line @typescript-eslint/naming-convention
public toString (): string {
const header = this.parent
? `subgraph cluster_${this.full_name}`
: `${this.directional ? 'di' : ''}graph ${this.full_name}`;
let attrs = `\n${this.attributes.map ((v) => `${v.name} = ${v.value}`)
2020-04-27 18:57:23 +02:00
.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`;
2020-04-24 12:21:26 +02:00
2020-04-27 18:57:23 +02:00
if (attrs === '\n\n')
2020-04-24 17:01:26 +02:00
attrs = '';
2020-04-27 18:57:23 +02:00
if (children === '\n\n')
2020-04-24 12:21:26 +02:00
children = '';
2020-04-27 18:57:23 +02:00
if (nodes === '\n\n')
2020-04-24 12:21:26 +02:00
nodes = '';
2020-04-27 18:57:23 +02:00
if (edges === '\n\n')
2020-04-24 12:21:26 +02:00
edges = '';
2020-04-27 18:57:23 +02:00
const indented = `${attrs}${children}${nodes}${edges}`
.replace (/\n$/u, '')
.replace (/^/gmu, ' ')
.split ('\n')
.map ((v) => v.trimRight ())
.join ('\n');
return `${header} {${indented}\n}`
2020-04-24 12:02:32 +02:00
.replace (/^\s+$/gmu, '');
}
2021-05-02 11:30:21 +02:00
public add_node (constructor: string | ((n: Node) => void)): string {
2020-04-27 18:57:23 +02:00
const node = new Node ('unnamed', this.full_name);
2020-04-24 14:05:58 +02:00
if (typeof constructor === 'string') {
2020-04-27 18:57:23 +02:00
node.name = constructor;
node.label = constructor;
2020-04-24 14:05:58 +02:00
}
2020-04-27 18:57:23 +02:00
else { constructor (node); }
2020-04-24 12:02:32 +02:00
this.nodes.push (node);
2020-04-27 16:03:48 +02:00
return node.full_name;
2020-04-24 12:02:32 +02:00
}
2021-05-02 11:30:21 +02:00
public add_graph (constructor: string | ((g: Graph) => void)): string {
2020-04-24 14:05:58 +02:00
const graph = new Graph ('unnamed', this.full_name);
2020-04-28 10:52:02 +02:00
2020-04-28 09:59:24 +02:00
graph.directional = this.directional;
2020-04-27 18:57:23 +02:00
if (typeof constructor === 'string')
graph.name = constructor;
else
constructor (graph);
2020-04-24 14:05:58 +02:00
this.children.push (graph);
2020-04-27 16:03:48 +02:00
return graph.full_name;
2020-04-24 12:02:32 +02:00
}
public add_edge (origin: string, target: string): void {
2020-04-28 08:39:57 +02:00
this.edges.push (new Edge (origin, target, this.directional));
2020-04-17 15:43:34 +02:00
}
}