Skip to content

Commit be6f329

Browse files
committed
Fixing big bug with vertex_index, and adding dot files for visualization
1 parent b64672d commit be6f329

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

docs/src/func_ref.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ getSubgraphAroundNode
5858
getSubgraph
5959
```
6060

61+
### Visualization
62+
```@docs
63+
toDot
64+
toDotFile
65+
```
66+
6167
### DataFrame Extension Functions
6268
```@docs
6369
getAdjacencyMatrixDataFrame

src/services/GraphsDFG.jl

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@ mutable struct GraphsNode
1515
end
1616
const FGType = Graphs.GenericIncidenceList{GraphsNode,Graphs.Edge{GraphsNode},Dict{Int,GraphsNode},Dict{Int,Array{Graphs.Edge{GraphsNode},1}}}
1717

18+
# For visualization
19+
import Graphs: attributes, vertex_index
20+
# Export attributes, these are enumerates as properties for the variables and factors
21+
# REF: http://www.graphviz.org/documentation/
22+
function attributes(v::GraphsNode, g::T)::AttributeDict where T <:GenericIncidenceList
23+
AttributeDict(
24+
"label" => v.dfgNode.label,
25+
"color" => typeof(v.dfgNode) == DFGVariable ? "red" : "blue",
26+
"shape" => typeof(v.dfgNode) == DFGVariable ? "box" : "ellipse",
27+
"fillcolor" => typeof(v.dfgNode) == DFGVariable ? "red" : "blue"
28+
)
29+
end
30+
31+
# This is insanely important - if we don't provide a valid index, the edges don't work correctly.
32+
vertex_index(v::GraphsNode) = v.index
33+
34+
# Exports
1835
export GraphsDFG
1936
export addVariable!
2037
export addFactor!
@@ -28,6 +45,7 @@ export getNeighbors
2845
export getSubgraphAroundNode
2946
export getSubgraph
3047
export isFullyConnected, hasOrphans
48+
export toDot, toDotFile
3149

3250
mutable struct GraphsDFG <: AbstractDFG
3351
g::FGType
@@ -80,7 +98,7 @@ function addFactor!(dfg::GraphsDFG, factor::DFGFactor, variables::Vector{DFGVari
8098
# Add the edges...
8199
for variable in variables
82100
v = dfg.g.vertices[variable._internalId]
83-
edge = Graphs.make_edge(dfg.g, f, v)
101+
edge = Graphs.make_edge(dfg.g, v, f)
84102
Graphs.add_edge!(dfg.g, edge)
85103
end
86104
return true
@@ -409,6 +427,30 @@ function getAdjacencyMatrix(dfg::GraphsDFG)::Matrix{Union{Nothing, Symbol}}
409427
return adjMat
410428
end
411429

430+
"""
431+
$(SIGNATURES)
432+
Produces a dot-format of the graph for visualization.
433+
"""
434+
function toDot(dfg::GraphsDFG)::String
435+
m = PipeBuffer()
436+
write(m,Graphs.to_dot(dfg.g))
437+
data = take!(m)
438+
close(m)
439+
return String(data)
440+
end
441+
442+
"""
443+
$(SIGNATURES)
444+
Produces a dot file of the graph for visualization.
445+
Download XDot to see the data
446+
"""
447+
function toDotFile(dfg::GraphsDFG, fileName::String)::Nothing
448+
open(fileName, "w") do fid
449+
write(fid,Graphs.to_dot(dfg.g))
450+
end
451+
return nothing
452+
end
453+
412454
function __init__()
413455
@require DataFrames="a93c6f00-e57d-5684-b7b6-d8193f3e46c0" begin
414456
if isdefined(Main, :DataFrames)

test/interfaceTests.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,9 @@ end
9797
dfgSubgraph = getSubgraphAroundNode(dfg, verts[1], 2, true, dfgSubgraph)
9898
@test setdiff([:x1, :x1x2f1, :x2], map(n -> n.label, [ls(dfgSubgraph)..., lsf(dfgSubgraph)...])) == []
9999
end
100+
101+
@testset "Producting Dot Files" begin
102+
@test toDot(dfg) == "graph graphname {\n18 [\"label\"=\"x8x9f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n2 [\"label\"=\"x2\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n2 -- 11\n2 -- 12\n16 [\"label\"=\"x6x7f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n11 [\"label\"=\"x1x2f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n7 [\"label\"=\"x7\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n7 -- 16\n7 -- 17\n9 [\"label\"=\"x9\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n9 -- 18\n9 -- 19\n10 [\"label\"=\"x10\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n10 -- 19\n19 [\"label\"=\"x9x10f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n17 [\"label\"=\"x7x8f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n8 [\"label\"=\"x8\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n8 -- 17\n8 -- 18\n6 [\"label\"=\"x6\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n6 -- 15\n6 -- 16\n4 [\"label\"=\"x4\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n4 -- 13\n4 -- 14\n3 [\"label\"=\"x3\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n3 -- 12\n3 -- 13\n5 [\"label\"=\"x5\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n5 -- 14\n5 -- 15\n13 [\"label\"=\"x3x4f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n14 [\"label\"=\"x4x5f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n15 [\"label\"=\"x5x6f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n12 [\"label\"=\"x2x3f1\",\"shape\"=\"ellipse\",\"fillcolor\"=\"blue\",\"color\"=\"blue\"]\n1 [\"label\"=\"x1\",\"shape\"=\"box\",\"fillcolor\"=\"red\",\"color\"=\"red\"]\n1 -- 11\n}\n"
103+
104+
@test toDotFile(dfg, "something.dot") == nothing
105+
end

0 commit comments

Comments
 (0)