Stream: allow edge attributes, autoclose nodes
This commit is contained in:
parent
920dc74d9c
commit
b11b2f5f2b
16
CHANGELOG.md
Normal file
16
CHANGELOG.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 1.2.0
|
||||||
|
|
||||||
|
Stream:
|
||||||
|
|
||||||
|
- automatically end node instructions
|
||||||
|
- allow attributes on edges
|
||||||
|
|
||||||
|
## 1.1.0
|
||||||
|
|
||||||
|
Allow creating graphs using a stream
|
||||||
|
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
initial version
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -5,7 +5,7 @@ pipeline {
|
|||||||
VERSION = VersionNumber([
|
VERSION = VersionNumber([
|
||||||
versionNumberString:
|
versionNumberString:
|
||||||
'${BUILDS_ALL_TIME}',
|
'${BUILDS_ALL_TIME}',
|
||||||
versionPrefix: '1.1.',
|
versionPrefix: '1.2.',
|
||||||
worstResultForIncrement: 'SUCCESS'
|
worstResultForIncrement: 'SUCCESS'
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# @sapphirecode/graphviz-builder
|
# @sapphirecode/graphviz-builder
|
||||||
|
|
||||||
version: 1.1.x
|
version: 1.2.x
|
||||||
|
|
||||||
constructing graphviz files using an easy typescript interface
|
constructing graphviz files using an easy typescript interface
|
||||||
|
|
||||||
|
@ -22,7 +22,11 @@ interface Stringable {
|
|||||||
|
|
||||||
export class GraphStream extends Transform {
|
export class GraphStream extends Transform {
|
||||||
private _path: string[] = [];
|
private _path: string[] = [];
|
||||||
private _state: GraphStreamCommand | '' = '';
|
private _state: (GraphStreamCommand | '')[] = [
|
||||||
|
'',
|
||||||
|
''
|
||||||
|
];
|
||||||
|
|
||||||
private _directional = false;
|
private _directional = false;
|
||||||
|
|
||||||
public get path (): string {
|
public get path (): string {
|
||||||
@ -33,6 +37,16 @@ export class GraphStream extends Transform {
|
|||||||
return ' '.repeat (this._path.length);
|
return ' '.repeat (this._path.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private finish_node ():void {
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
'ce',
|
||||||
|
'cn'
|
||||||
|
].includes (this._state[1])
|
||||||
|
)
|
||||||
|
this.push ('\n');
|
||||||
|
}
|
||||||
|
|
||||||
private expect_state (instr: GraphStreamCommand): void {
|
private expect_state (instr: GraphStreamCommand): void {
|
||||||
const states: (GraphStreamCommand|'')[] = [];
|
const states: (GraphStreamCommand|'')[] = [];
|
||||||
if ([
|
if ([
|
||||||
@ -47,24 +61,21 @@ export class GraphStream extends Transform {
|
|||||||
'csg',
|
'csg',
|
||||||
'ce'
|
'ce'
|
||||||
].includes (instr))
|
].includes (instr))
|
||||||
states.push ('en', 'at', 'eg', 'cug', 'cdg', 'csg', 'ce');
|
states.push ('at', 'eg', 'cug', 'cdg', 'csg', 'ce', 'cn');
|
||||||
|
|
||||||
switch (instr) {
|
switch (instr) {
|
||||||
case 'en':
|
|
||||||
states.push ('cn', 'at');
|
|
||||||
break;
|
|
||||||
case 'at':
|
case 'at':
|
||||||
states.push ('cn', 'cug', 'cdg', 'csg');
|
states.push ('cn', 'cug', 'cdg', 'csg', 'ce');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!states.includes (this._state)) {
|
if (!states.includes (this._state[1])) {
|
||||||
throw new Error (`invalid state to execute command ${
|
throw new Error (`invalid state to execute command ${
|
||||||
translate_command (instr)}
|
translate_command (instr)}
|
||||||
expected: ${states.map ((s) => translate_command (s))
|
expected: ${states.map ((s) => translate_command (s))
|
||||||
.join (', ')}
|
.join (', ')}
|
||||||
actual: ${translate_command (this._state)}`);
|
actual: ${translate_command (this._state[1])}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,24 +100,27 @@ export class GraphStream extends Transform {
|
|||||||
this._directional = true;
|
this._directional = true;
|
||||||
break;
|
break;
|
||||||
case 'csg': // create subgraph
|
case 'csg': // create subgraph
|
||||||
|
this.finish_node ();
|
||||||
this.push (
|
this.push (
|
||||||
`${this.level}subgraph cluster_${this.path}_${instr.args[0]} {\n`
|
`${this.level}subgraph cluster_${this.path}_${instr.args[0]} {\n`
|
||||||
);
|
);
|
||||||
this._path.push (instr.args[0]);
|
this._path.push (instr.args[0]);
|
||||||
break;
|
break;
|
||||||
case 'eg': // end graph
|
case 'eg': // end graph
|
||||||
|
this.finish_node ();
|
||||||
this._path.pop ();
|
this._path.pop ();
|
||||||
this.push (`${this.level}}\n\n`);
|
this.push (`${this.level}}\n\n`);
|
||||||
break;
|
break;
|
||||||
case 'cn': // create node
|
case 'cn': // create node
|
||||||
|
this.finish_node ();
|
||||||
this.push (`${this.level}${this.path}_${instr.args[0]}`);
|
this.push (`${this.level}${this.path}_${instr.args[0]}`);
|
||||||
break;
|
break;
|
||||||
case 'en': // end node
|
|
||||||
this.push ('\n');
|
|
||||||
break;
|
|
||||||
case 'at': // add attributes
|
case 'at': // add attributes
|
||||||
if (this._state === 'cn') {
|
if ([
|
||||||
this.push (` [${instr.args.join (', ')}]`);
|
'cn',
|
||||||
|
'ce'
|
||||||
|
].includes (this._state[1])) {
|
||||||
|
this.push (` [${instr.args.join (', ')}]\n`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.push (`${this.level}${
|
this.push (`${this.level}${
|
||||||
@ -116,14 +130,16 @@ export class GraphStream extends Transform {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ce':
|
case 'ce':
|
||||||
|
this.finish_node ();
|
||||||
this.push (`${this.level}${
|
this.push (`${this.level}${
|
||||||
instr.args[0]
|
instr.args[0]
|
||||||
} -${this._directional ? '>' : '-'} ${instr.args[1]}\n`);
|
} -${this._directional ? '>' : '-'} ${instr.args[1]}`);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this._state = instr.type;
|
this._state.push (instr.type);
|
||||||
|
this._state.shift ();
|
||||||
callback ();
|
callback ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,8 +155,11 @@ export class GraphStream extends Transform {
|
|||||||
return `${this.path}_${node_name}`;
|
return `${this.path}_${node_name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated calling this method is not needed anymore
|
||||||
|
*/
|
||||||
public end_node (): void {
|
public end_node (): void {
|
||||||
this.write ({ type: 'en', args: [] });
|
// this.write ({ type: 'en', args: [] });
|
||||||
}
|
}
|
||||||
|
|
||||||
public create_graph (name: string, type: 'u'|'d'|'s' = 's'): void {
|
public create_graph (name: string, type: 'u'|'d'|'s' = 's'): void {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||||
* This file is part of graphviz-builder which is released under MIT.
|
* This file is part of graphviz-builder which is released under MIT.
|
||||||
* See file 'LICENSE' for full license details.
|
* See file 'LICENSE' for full license details.
|
||||||
* Created by Timo Hocker <timo@scode.ovh>, May 2020
|
* Created by Timo Hocker <timo@scode.ovh>, June 2020
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
@ -37,6 +37,7 @@ const complex = `digraph foo {
|
|||||||
foo_baz [label = "baz"]
|
foo_baz [label = "baz"]
|
||||||
foo_foo [label = "foo"]
|
foo_foo [label = "foo"]
|
||||||
foo_foo -> foo_baz
|
foo_foo -> foo_baz
|
||||||
|
foo_foo -> foo_baz_asd [label = "edge attr"]
|
||||||
}
|
}
|
||||||
|
|
||||||
`;
|
`;
|
||||||
@ -76,20 +77,19 @@ test ('complex stream graph', (t) => new Promise ((resolve) => {
|
|||||||
stream.attributes ({ color: Color.gray, style: 'dotted' });
|
stream.attributes ({ color: Color.gray, style: 'dotted' });
|
||||||
stream.end_graph ();
|
stream.end_graph ();
|
||||||
stream.end_graph ();
|
stream.end_graph ();
|
||||||
stream.create_node ('asd');
|
const asd = stream.create_node ('asd');
|
||||||
stream.attributes ({ label: 'asd' });
|
stream.attributes ({ label: 'asd' });
|
||||||
stream.end_node ();
|
stream.end_node ();
|
||||||
stream.create_node ('test');
|
stream.create_node ('test');
|
||||||
stream.attributes ({ style: 'bold', color: Color.gray });
|
stream.attributes ({ style: 'bold', color: Color.gray });
|
||||||
stream.end_node ();
|
|
||||||
stream.end_graph ();
|
stream.end_graph ();
|
||||||
stream.create_node ('baz');
|
const baz = stream.create_node ('baz');
|
||||||
stream.attributes ({ label: 'baz' });
|
stream.attributes ({ label: 'baz' });
|
||||||
stream.end_node ();
|
const foo = stream.create_node ('foo');
|
||||||
stream.create_node ('foo');
|
|
||||||
stream.attributes ({ label: 'foo' });
|
stream.attributes ({ label: 'foo' });
|
||||||
stream.end_node ();
|
stream.create_edge (foo, baz);
|
||||||
stream.create_edge (`${stream.path}_foo`, `${stream.path}_baz`);
|
stream.create_edge (foo, asd);
|
||||||
|
stream.attributes ({ label: 'edge attr' });
|
||||||
stream.end_graph ();
|
stream.end_graph ();
|
||||||
stream.end ();
|
stream.end ();
|
||||||
}));
|
}));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user