Skip to content

Commit 6db4c3d

Browse files
authored
Merge pull request #23 from abhinavmehndiratta/write_dot
Added functionality to save graphs in DOT format
2 parents 257a8c3 + 1165562 commit 6db4c3d

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

src/DOT/Dot.jl

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,42 @@ using GraphIO.ParserCombinator.Parsers
44
using LightGraphs
55
using LightGraphs: AbstractGraphFormat
66

7-
import LightGraphs: loadgraph, loadgraphs
7+
import LightGraphs: loadgraph, loadgraphs, savegraph
88

99
export DOTFormat
1010

1111
struct DOTFormat <: AbstractGraphFormat end
12-
# TODO: implement save
12+
13+
function savedot(io::IO, g::LightGraphs.AbstractGraph, gname::String = "")
14+
isdir = LightGraphs.is_directed(g)
15+
println(io,(isdir ? "digraph " : "graph ") * gname * " {")
16+
for i in LightGraphs.vertices(g)
17+
println(io,"\t" * string(i))
18+
end
19+
if isdir
20+
for u in LightGraphs.vertices(g)
21+
out_nbrs = LightGraphs.outneighbors(g, u)
22+
length(out_nbrs) == 0 && continue
23+
println(io, "\t" * string(u) * " -> {" * join(out_nbrs,',') * "}")
24+
end
25+
else
26+
for e in LightGraphs.edges(g)
27+
source = string(LightGraphs.src(e))
28+
dest = string(LightGraphs.dst(e))
29+
println(io, "\t" * source * " -- " * dest)
30+
end
31+
end
32+
println(io,"}")
33+
return 1
34+
end
35+
36+
function savedot_mult(io::IO, graphs::Dict)
37+
ng = 0
38+
for (gname, g) in graphs
39+
ng += savedot(io, g, gname)
40+
end
41+
return ng
42+
end
1343

1444
function _dot_read_one_graph(pg::Parsers.DOT.Graph)
1545
isdir = pg.directed
@@ -55,5 +85,7 @@ end
5585

5686
loadgraph(io::IO, gname::String, ::DOTFormat) = loaddot(io, gname)
5787
loadgraphs(io::IO, ::DOTFormat) = loaddot_mult(io)
88+
savegraph(io::IO, g::AbstractGraph, gname::String, ::DOTFormat) = savedot(io, g, gname)
89+
savegraph(io::IO, d::Dict, ::DOTFormat) = savedot_mult(io, d)
5890

5991
end #module

test/DOT/runtests.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Test
22
using ParserCombinator
33
using GraphIO.DOT
4+
using LightGraphs.Experimental
45

56
@testset "DOT" begin
67
g = CompleteGraph(6)
@@ -12,4 +13,35 @@ using GraphIO.DOT
1213
read_test(DOTFormat(), g, "g1", fname, testfail=true)
1314
read_test(DOTFormat(), dg, "g2", fname)
1415
read_test_mult(DOTFormat(), Dict{String,AbstractGraph}("g1"=>g, "g2"=>dg), fname)
16+
17+
#tests for multiple graphs
18+
19+
fname = joinpath(testdir, "testdata", "saved3graphs.dot")
20+
#connected graph
21+
g1 = SimpleGraph(5,10)
22+
#disconnected graph
23+
g2 = SimpleGraph(5,2)
24+
#directed graph
25+
dg = SimpleDiGraph(5,8)
26+
GraphDict = Dict("g1" => g1, "g2" => g2, "dg" => dg)
27+
write_test(DOTFormat(), GraphDict, fname, remove = false, silent = true)
28+
29+
#adding this test because currently the Parser returns unordered vertices
30+
@test has_isomorph(loadgraph(fname, "g1", DOTFormat()), g1)
31+
@test has_isomorph(loadgraph(fname, "g2", DOTFormat()), g2)
32+
@test has_isomorph(loadgraph(fname, "dg", DOTFormat()), dg)
33+
34+
rm(fname)
35+
36+
#tests for single graph
37+
38+
fname1 = joinpath(testdir, "testdata", "saved1graph.dot")
39+
write_test(DOTFormat(), g1, "g1", fname1, remove = false, silent = true)
40+
@test has_isomorph(loadgraph(fname1, "g1", DOTFormat()), g1)
41+
fname2 = joinpath(testdir, "testdata", "saved1digraph.dot")
42+
write_test(DOTFormat(), dg, "dg", fname2, remove = false, silent = true)
43+
@test has_isomorph(loadgraph(fname2, "dg", DOTFormat()), dg)
44+
45+
rm(fname1)
46+
rm(fname2)
1547
end

0 commit comments

Comments
 (0)