Merging graphs in Graphviz
up vote
1
down vote
favorite
I have a collection of digraphs encoded in DOT language, and i want to merge them into a single digraph where nodes with the same name in different input graphs are merged together.
For example given the following files:
1.dot
:
digraph
A -> B
A -> C
2.dot
:
digraph
D -> E
E -> F
3.dot
:
digraph
D -> G
G -> A
I would like to obtain the following result.dot
:
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
I tried to use gvpack
but it renames duplicate nodes.
> gvpack -u 1.dot 2.dot 3.dot
Warning: node D in graph[2] %15 already defined
Some nodes will be renamed.
digraph root
node [label="N"];
node [label="N"];
A -> B;
A -> C;
node [label="N"];
D -> E;
E -> F;
node [label="N"];
D_gv1 -> G;
G -> A_gv1;
I found a similar question on SO that suggest using sed
to rename the renamed nodes, but that doesn't seem very clean.
Is there a way to merge the graphs the way i would like them?
graphviz dot
add a comment |
up vote
1
down vote
favorite
I have a collection of digraphs encoded in DOT language, and i want to merge them into a single digraph where nodes with the same name in different input graphs are merged together.
For example given the following files:
1.dot
:
digraph
A -> B
A -> C
2.dot
:
digraph
D -> E
E -> F
3.dot
:
digraph
D -> G
G -> A
I would like to obtain the following result.dot
:
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
I tried to use gvpack
but it renames duplicate nodes.
> gvpack -u 1.dot 2.dot 3.dot
Warning: node D in graph[2] %15 already defined
Some nodes will be renamed.
digraph root
node [label="N"];
node [label="N"];
A -> B;
A -> C;
node [label="N"];
D -> E;
E -> F;
node [label="N"];
D_gv1 -> G;
G -> A_gv1;
I found a similar question on SO that suggest using sed
to rename the renamed nodes, but that doesn't seem very clean.
Is there a way to merge the graphs the way i would like them?
graphviz dot
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have a collection of digraphs encoded in DOT language, and i want to merge them into a single digraph where nodes with the same name in different input graphs are merged together.
For example given the following files:
1.dot
:
digraph
A -> B
A -> C
2.dot
:
digraph
D -> E
E -> F
3.dot
:
digraph
D -> G
G -> A
I would like to obtain the following result.dot
:
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
I tried to use gvpack
but it renames duplicate nodes.
> gvpack -u 1.dot 2.dot 3.dot
Warning: node D in graph[2] %15 already defined
Some nodes will be renamed.
digraph root
node [label="N"];
node [label="N"];
A -> B;
A -> C;
node [label="N"];
D -> E;
E -> F;
node [label="N"];
D_gv1 -> G;
G -> A_gv1;
I found a similar question on SO that suggest using sed
to rename the renamed nodes, but that doesn't seem very clean.
Is there a way to merge the graphs the way i would like them?
graphviz dot
I have a collection of digraphs encoded in DOT language, and i want to merge them into a single digraph where nodes with the same name in different input graphs are merged together.
For example given the following files:
1.dot
:
digraph
A -> B
A -> C
2.dot
:
digraph
D -> E
E -> F
3.dot
:
digraph
D -> G
G -> A
I would like to obtain the following result.dot
:
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
I tried to use gvpack
but it renames duplicate nodes.
> gvpack -u 1.dot 2.dot 3.dot
Warning: node D in graph[2] %15 already defined
Some nodes will be renamed.
digraph root
node [label="N"];
node [label="N"];
A -> B;
A -> C;
node [label="N"];
D -> E;
E -> F;
node [label="N"];
D_gv1 -> G;
G -> A_gv1;
I found a similar question on SO that suggest using sed
to rename the renamed nodes, but that doesn't seem very clean.
Is there a way to merge the graphs the way i would like them?
graphviz dot
graphviz dot
asked Nov 8 at 6:32
Gauthier
2,3071822
2,3071822
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
2
down vote
For exactly the situation you are describing, using the sample files you provide, there is a very simple answer using m4 - a standard GNU Linux tool that should be installed by default in most distributions.
Create a file merge123.m4
with this content:
digraph 123
define(`digraph',`subgraph')
include(1.dot)
include(2.dot)
include(3.dot)
and execute it with the command
m4 merge123.m4 > 123.dot
and the resulting 123.dot
file will be
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
If you don't like the empty lines, close each line in the script with dnl
(the builtin dnl
stands for “Discard to Next Line”:), for example
include(1.dot)dnl
m4
is extremely useful as it adds features to graphviz
that are really helpful for more involved projects; see also this SO question.
EDITED to answer the question in the comment:
If you need to include files and don't know their number and names, you have (at least) two options:
1) If the number of files is rather small and you know all names that they could possibly have, you can sinclude()
them all:
digraph 123
define(`digraph',`subgraph')
sinclude(1.dot)
sinclude(2.dot)
sinclude(3.dot)
sinclude(4.dot)
sinclude(5.dot)
m4
will only include the files that actually exist, and not complain about the missing ones (the s
means "silent").
2) If you produce a larger number of.dot
files with unpredictable names, you will need to do some pre-processing. Create a shell script include.sh
similar to this one
#!/bin/sh
# get *.dot files (or any pattern you like) into one place
ls *.dot > files.txt
# bring them into a format m4 likes
awk 'print "include(" $1 ")" "dnl"' files.txt > includes.txt
#done
includes.txt
now provides m4
with the necessary information:
include(1.dot)dnl
include(2.dot)dnl
include(3.dot)dnl
Now modify your merge.m4
file, enabling it to make use of the file list provided (I'm adding dnl
here to avoid lots of empty space in the resulting merged file):
### merge dot files
digraph 123
define(`digraph',`subgraph')dnl
syscmd(`./include.sh')dnl
include(`includes.txt')dnl
In order to keep the resulting file separate from the input files, better use a different extension when merging:
m4 merge.m4 > merged.gv
which now looks like
### merge dot files
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
Thanks, that's interesting. Is there a way to usem4
if the number of input files as well as their names is variable?
– Gauthier
Nov 9 at 3:00
1
see edits in my original answer
– vaettchen
Nov 10 at 3:35
add a comment |
up vote
0
down vote
If it's really just a minor edit of the input files joined, then perl is a natural fit:
use strict;
sub main
local $/ = undef;
print "digraph n";
for my $f (@ARGV)
open(F, $f) or die $!;
my $text = <F>;
close(F);
$text =~ s/digraph/subgraph/;
$text =~s/^/ /mg;
print $text;
print "n";
main;
Then
$ perl merge.pl 1.dot 2.dot 3.dot
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
add a comment |
up vote
0
down vote
accepted
I ended up using a Java library to perform the merge, and much more!
With the library i could easily tap into the data structure, change nodes if need be, and add attributes to the graph.
A quick example in Kotlin:
// prepare root graph and set direction
val wamap = mutGraph("wamap")
.setDirected(true)
wamap.graphAttrs().add(RankDir.LEFT_TO_RIGHT)
// add subgraphs from the content of .gv files from disk
Files.walk(Paths.get("D:\src\work\Wamap"), 1)
.filter Files.isRegularFile(it)
.filter it.fileName.toString().endsWith(".gv")
.map Parser.read(it.toFile())
.forEach it.addTo(wamap)
// normalize node names to lowercase, to ensure nodes with same name are the same node
wamap.graphs()
.flatMap it.nodes()
.forEach it.setName(it.name().toString().toLowerCase())
// output as file, but also render the image directly with all the possible Graphviz layout engines
File("out/wamap.gv").writeText(wamap.toString())
Engine.values()
.forEach engine ->
Graphviz.fromGraph(wamap).engine(engine).render(Format.PNG).toFile(File("out/wamap-$engine.png"))
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
For exactly the situation you are describing, using the sample files you provide, there is a very simple answer using m4 - a standard GNU Linux tool that should be installed by default in most distributions.
Create a file merge123.m4
with this content:
digraph 123
define(`digraph',`subgraph')
include(1.dot)
include(2.dot)
include(3.dot)
and execute it with the command
m4 merge123.m4 > 123.dot
and the resulting 123.dot
file will be
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
If you don't like the empty lines, close each line in the script with dnl
(the builtin dnl
stands for “Discard to Next Line”:), for example
include(1.dot)dnl
m4
is extremely useful as it adds features to graphviz
that are really helpful for more involved projects; see also this SO question.
EDITED to answer the question in the comment:
If you need to include files and don't know their number and names, you have (at least) two options:
1) If the number of files is rather small and you know all names that they could possibly have, you can sinclude()
them all:
digraph 123
define(`digraph',`subgraph')
sinclude(1.dot)
sinclude(2.dot)
sinclude(3.dot)
sinclude(4.dot)
sinclude(5.dot)
m4
will only include the files that actually exist, and not complain about the missing ones (the s
means "silent").
2) If you produce a larger number of.dot
files with unpredictable names, you will need to do some pre-processing. Create a shell script include.sh
similar to this one
#!/bin/sh
# get *.dot files (or any pattern you like) into one place
ls *.dot > files.txt
# bring them into a format m4 likes
awk 'print "include(" $1 ")" "dnl"' files.txt > includes.txt
#done
includes.txt
now provides m4
with the necessary information:
include(1.dot)dnl
include(2.dot)dnl
include(3.dot)dnl
Now modify your merge.m4
file, enabling it to make use of the file list provided (I'm adding dnl
here to avoid lots of empty space in the resulting merged file):
### merge dot files
digraph 123
define(`digraph',`subgraph')dnl
syscmd(`./include.sh')dnl
include(`includes.txt')dnl
In order to keep the resulting file separate from the input files, better use a different extension when merging:
m4 merge.m4 > merged.gv
which now looks like
### merge dot files
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
Thanks, that's interesting. Is there a way to usem4
if the number of input files as well as their names is variable?
– Gauthier
Nov 9 at 3:00
1
see edits in my original answer
– vaettchen
Nov 10 at 3:35
add a comment |
up vote
2
down vote
For exactly the situation you are describing, using the sample files you provide, there is a very simple answer using m4 - a standard GNU Linux tool that should be installed by default in most distributions.
Create a file merge123.m4
with this content:
digraph 123
define(`digraph',`subgraph')
include(1.dot)
include(2.dot)
include(3.dot)
and execute it with the command
m4 merge123.m4 > 123.dot
and the resulting 123.dot
file will be
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
If you don't like the empty lines, close each line in the script with dnl
(the builtin dnl
stands for “Discard to Next Line”:), for example
include(1.dot)dnl
m4
is extremely useful as it adds features to graphviz
that are really helpful for more involved projects; see also this SO question.
EDITED to answer the question in the comment:
If you need to include files and don't know their number and names, you have (at least) two options:
1) If the number of files is rather small and you know all names that they could possibly have, you can sinclude()
them all:
digraph 123
define(`digraph',`subgraph')
sinclude(1.dot)
sinclude(2.dot)
sinclude(3.dot)
sinclude(4.dot)
sinclude(5.dot)
m4
will only include the files that actually exist, and not complain about the missing ones (the s
means "silent").
2) If you produce a larger number of.dot
files with unpredictable names, you will need to do some pre-processing. Create a shell script include.sh
similar to this one
#!/bin/sh
# get *.dot files (or any pattern you like) into one place
ls *.dot > files.txt
# bring them into a format m4 likes
awk 'print "include(" $1 ")" "dnl"' files.txt > includes.txt
#done
includes.txt
now provides m4
with the necessary information:
include(1.dot)dnl
include(2.dot)dnl
include(3.dot)dnl
Now modify your merge.m4
file, enabling it to make use of the file list provided (I'm adding dnl
here to avoid lots of empty space in the resulting merged file):
### merge dot files
digraph 123
define(`digraph',`subgraph')dnl
syscmd(`./include.sh')dnl
include(`includes.txt')dnl
In order to keep the resulting file separate from the input files, better use a different extension when merging:
m4 merge.m4 > merged.gv
which now looks like
### merge dot files
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
Thanks, that's interesting. Is there a way to usem4
if the number of input files as well as their names is variable?
– Gauthier
Nov 9 at 3:00
1
see edits in my original answer
– vaettchen
Nov 10 at 3:35
add a comment |
up vote
2
down vote
up vote
2
down vote
For exactly the situation you are describing, using the sample files you provide, there is a very simple answer using m4 - a standard GNU Linux tool that should be installed by default in most distributions.
Create a file merge123.m4
with this content:
digraph 123
define(`digraph',`subgraph')
include(1.dot)
include(2.dot)
include(3.dot)
and execute it with the command
m4 merge123.m4 > 123.dot
and the resulting 123.dot
file will be
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
If you don't like the empty lines, close each line in the script with dnl
(the builtin dnl
stands for “Discard to Next Line”:), for example
include(1.dot)dnl
m4
is extremely useful as it adds features to graphviz
that are really helpful for more involved projects; see also this SO question.
EDITED to answer the question in the comment:
If you need to include files and don't know their number and names, you have (at least) two options:
1) If the number of files is rather small and you know all names that they could possibly have, you can sinclude()
them all:
digraph 123
define(`digraph',`subgraph')
sinclude(1.dot)
sinclude(2.dot)
sinclude(3.dot)
sinclude(4.dot)
sinclude(5.dot)
m4
will only include the files that actually exist, and not complain about the missing ones (the s
means "silent").
2) If you produce a larger number of.dot
files with unpredictable names, you will need to do some pre-processing. Create a shell script include.sh
similar to this one
#!/bin/sh
# get *.dot files (or any pattern you like) into one place
ls *.dot > files.txt
# bring them into a format m4 likes
awk 'print "include(" $1 ")" "dnl"' files.txt > includes.txt
#done
includes.txt
now provides m4
with the necessary information:
include(1.dot)dnl
include(2.dot)dnl
include(3.dot)dnl
Now modify your merge.m4
file, enabling it to make use of the file list provided (I'm adding dnl
here to avoid lots of empty space in the resulting merged file):
### merge dot files
digraph 123
define(`digraph',`subgraph')dnl
syscmd(`./include.sh')dnl
include(`includes.txt')dnl
In order to keep the resulting file separate from the input files, better use a different extension when merging:
m4 merge.m4 > merged.gv
which now looks like
### merge dot files
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
For exactly the situation you are describing, using the sample files you provide, there is a very simple answer using m4 - a standard GNU Linux tool that should be installed by default in most distributions.
Create a file merge123.m4
with this content:
digraph 123
define(`digraph',`subgraph')
include(1.dot)
include(2.dot)
include(3.dot)
and execute it with the command
m4 merge123.m4 > 123.dot
and the resulting 123.dot
file will be
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
If you don't like the empty lines, close each line in the script with dnl
(the builtin dnl
stands for “Discard to Next Line”:), for example
include(1.dot)dnl
m4
is extremely useful as it adds features to graphviz
that are really helpful for more involved projects; see also this SO question.
EDITED to answer the question in the comment:
If you need to include files and don't know their number and names, you have (at least) two options:
1) If the number of files is rather small and you know all names that they could possibly have, you can sinclude()
them all:
digraph 123
define(`digraph',`subgraph')
sinclude(1.dot)
sinclude(2.dot)
sinclude(3.dot)
sinclude(4.dot)
sinclude(5.dot)
m4
will only include the files that actually exist, and not complain about the missing ones (the s
means "silent").
2) If you produce a larger number of.dot
files with unpredictable names, you will need to do some pre-processing. Create a shell script include.sh
similar to this one
#!/bin/sh
# get *.dot files (or any pattern you like) into one place
ls *.dot > files.txt
# bring them into a format m4 likes
awk 'print "include(" $1 ")" "dnl"' files.txt > includes.txt
#done
includes.txt
now provides m4
with the necessary information:
include(1.dot)dnl
include(2.dot)dnl
include(3.dot)dnl
Now modify your merge.m4
file, enabling it to make use of the file list provided (I'm adding dnl
here to avoid lots of empty space in the resulting merged file):
### merge dot files
digraph 123
define(`digraph',`subgraph')dnl
syscmd(`./include.sh')dnl
include(`includes.txt')dnl
In order to keep the resulting file separate from the input files, better use a different extension when merging:
m4 merge.m4 > merged.gv
which now looks like
### merge dot files
digraph 123
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
edited Nov 10 at 5:18
answered Nov 8 at 8:50
vaettchen
4,9751332
4,9751332
Thanks, that's interesting. Is there a way to usem4
if the number of input files as well as their names is variable?
– Gauthier
Nov 9 at 3:00
1
see edits in my original answer
– vaettchen
Nov 10 at 3:35
add a comment |
Thanks, that's interesting. Is there a way to usem4
if the number of input files as well as their names is variable?
– Gauthier
Nov 9 at 3:00
1
see edits in my original answer
– vaettchen
Nov 10 at 3:35
Thanks, that's interesting. Is there a way to use
m4
if the number of input files as well as their names is variable?– Gauthier
Nov 9 at 3:00
Thanks, that's interesting. Is there a way to use
m4
if the number of input files as well as their names is variable?– Gauthier
Nov 9 at 3:00
1
1
see edits in my original answer
– vaettchen
Nov 10 at 3:35
see edits in my original answer
– vaettchen
Nov 10 at 3:35
add a comment |
up vote
0
down vote
If it's really just a minor edit of the input files joined, then perl is a natural fit:
use strict;
sub main
local $/ = undef;
print "digraph n";
for my $f (@ARGV)
open(F, $f) or die $!;
my $text = <F>;
close(F);
$text =~ s/digraph/subgraph/;
$text =~s/^/ /mg;
print $text;
print "n";
main;
Then
$ perl merge.pl 1.dot 2.dot 3.dot
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
add a comment |
up vote
0
down vote
If it's really just a minor edit of the input files joined, then perl is a natural fit:
use strict;
sub main
local $/ = undef;
print "digraph n";
for my $f (@ARGV)
open(F, $f) or die $!;
my $text = <F>;
close(F);
$text =~ s/digraph/subgraph/;
$text =~s/^/ /mg;
print $text;
print "n";
main;
Then
$ perl merge.pl 1.dot 2.dot 3.dot
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
add a comment |
up vote
0
down vote
up vote
0
down vote
If it's really just a minor edit of the input files joined, then perl is a natural fit:
use strict;
sub main
local $/ = undef;
print "digraph n";
for my $f (@ARGV)
open(F, $f) or die $!;
my $text = <F>;
close(F);
$text =~ s/digraph/subgraph/;
$text =~s/^/ /mg;
print $text;
print "n";
main;
Then
$ perl merge.pl 1.dot 2.dot 3.dot
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
If it's really just a minor edit of the input files joined, then perl is a natural fit:
use strict;
sub main
local $/ = undef;
print "digraph n";
for my $f (@ARGV)
open(F, $f) or die $!;
my $text = <F>;
close(F);
$text =~ s/digraph/subgraph/;
$text =~s/^/ /mg;
print $text;
print "n";
main;
Then
$ perl merge.pl 1.dot 2.dot 3.dot
digraph
subgraph
A -> B
A -> C
subgraph
D -> E
E -> F
subgraph
D -> G
G -> A
answered Nov 8 at 6:47
Gene
37.4k44273
37.4k44273
add a comment |
add a comment |
up vote
0
down vote
accepted
I ended up using a Java library to perform the merge, and much more!
With the library i could easily tap into the data structure, change nodes if need be, and add attributes to the graph.
A quick example in Kotlin:
// prepare root graph and set direction
val wamap = mutGraph("wamap")
.setDirected(true)
wamap.graphAttrs().add(RankDir.LEFT_TO_RIGHT)
// add subgraphs from the content of .gv files from disk
Files.walk(Paths.get("D:\src\work\Wamap"), 1)
.filter Files.isRegularFile(it)
.filter it.fileName.toString().endsWith(".gv")
.map Parser.read(it.toFile())
.forEach it.addTo(wamap)
// normalize node names to lowercase, to ensure nodes with same name are the same node
wamap.graphs()
.flatMap it.nodes()
.forEach it.setName(it.name().toString().toLowerCase())
// output as file, but also render the image directly with all the possible Graphviz layout engines
File("out/wamap.gv").writeText(wamap.toString())
Engine.values()
.forEach engine ->
Graphviz.fromGraph(wamap).engine(engine).render(Format.PNG).toFile(File("out/wamap-$engine.png"))
add a comment |
up vote
0
down vote
accepted
I ended up using a Java library to perform the merge, and much more!
With the library i could easily tap into the data structure, change nodes if need be, and add attributes to the graph.
A quick example in Kotlin:
// prepare root graph and set direction
val wamap = mutGraph("wamap")
.setDirected(true)
wamap.graphAttrs().add(RankDir.LEFT_TO_RIGHT)
// add subgraphs from the content of .gv files from disk
Files.walk(Paths.get("D:\src\work\Wamap"), 1)
.filter Files.isRegularFile(it)
.filter it.fileName.toString().endsWith(".gv")
.map Parser.read(it.toFile())
.forEach it.addTo(wamap)
// normalize node names to lowercase, to ensure nodes with same name are the same node
wamap.graphs()
.flatMap it.nodes()
.forEach it.setName(it.name().toString().toLowerCase())
// output as file, but also render the image directly with all the possible Graphviz layout engines
File("out/wamap.gv").writeText(wamap.toString())
Engine.values()
.forEach engine ->
Graphviz.fromGraph(wamap).engine(engine).render(Format.PNG).toFile(File("out/wamap-$engine.png"))
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
I ended up using a Java library to perform the merge, and much more!
With the library i could easily tap into the data structure, change nodes if need be, and add attributes to the graph.
A quick example in Kotlin:
// prepare root graph and set direction
val wamap = mutGraph("wamap")
.setDirected(true)
wamap.graphAttrs().add(RankDir.LEFT_TO_RIGHT)
// add subgraphs from the content of .gv files from disk
Files.walk(Paths.get("D:\src\work\Wamap"), 1)
.filter Files.isRegularFile(it)
.filter it.fileName.toString().endsWith(".gv")
.map Parser.read(it.toFile())
.forEach it.addTo(wamap)
// normalize node names to lowercase, to ensure nodes with same name are the same node
wamap.graphs()
.flatMap it.nodes()
.forEach it.setName(it.name().toString().toLowerCase())
// output as file, but also render the image directly with all the possible Graphviz layout engines
File("out/wamap.gv").writeText(wamap.toString())
Engine.values()
.forEach engine ->
Graphviz.fromGraph(wamap).engine(engine).render(Format.PNG).toFile(File("out/wamap-$engine.png"))
I ended up using a Java library to perform the merge, and much more!
With the library i could easily tap into the data structure, change nodes if need be, and add attributes to the graph.
A quick example in Kotlin:
// prepare root graph and set direction
val wamap = mutGraph("wamap")
.setDirected(true)
wamap.graphAttrs().add(RankDir.LEFT_TO_RIGHT)
// add subgraphs from the content of .gv files from disk
Files.walk(Paths.get("D:\src\work\Wamap"), 1)
.filter Files.isRegularFile(it)
.filter it.fileName.toString().endsWith(".gv")
.map Parser.read(it.toFile())
.forEach it.addTo(wamap)
// normalize node names to lowercase, to ensure nodes with same name are the same node
wamap.graphs()
.flatMap it.nodes()
.forEach it.setName(it.name().toString().toLowerCase())
// output as file, but also render the image directly with all the possible Graphviz layout engines
File("out/wamap.gv").writeText(wamap.toString())
Engine.values()
.forEach engine ->
Graphviz.fromGraph(wamap).engine(engine).render(Format.PNG).toFile(File("out/wamap-$engine.png"))
answered Nov 14 at 6:56
Gauthier
2,3071822
2,3071822
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53202550%2fmerging-graphs-in-graphviz%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown