5 #include <SimoxUtility/algorithm/string/string_tools.h>
9 #include <graphviz/cgraph.h>
20 return const_cast<char*
>(
c);
24 gv_str(std::string
const&
s)
26 return const_cast<char*
>(
s.c_str());
29 char GRAPHVIZ_ATTR_LABEL[] =
"label";
30 char GRAPHVIZ_ATTR_POS[] =
"pos";
31 char GRAPHVIZ_ATTR_WIDTH[] =
"width";
32 char GRAPHVIZ_ATTR_HEIGHT[] =
"height";
33 char GRAPHVIZ_ATTR_LABEL_POS[] =
"lp";
38 context = gvContext();
39 graph = agopen(gv_str(
"Graph"), Agdirected,
nullptr);
55 agattr(graph, AGRAPH, (
char*)
"overlap", (
char*)
"prism");
56 agattr(graph, AGRAPH, (
char*)
"splines", (
char*)
"true");
57 agattr(graph, AGRAPH, (
char*)
"pad", (
char*)
"0.2");
58 agattr(graph, AGRAPH, (
char*)
"nodesep", (
char*)
"0.4");
59 agattr(graph, AGRAPH, (
char*)
"sep", (
char*)
"1");
60 agattr(graph, AGRAPH, (
char*)
"overlap_shrink", (
char*)
"true");
61 agattr(graph, AGRAPH, (
char*)
"rankdir", (
char*)
"LR");
62 agattr(graph, AGRAPH, (
char*)
"ratio", (
char*)
"compress");
64 agattr(graph, AGNODE, (
char*)
"margin", (
char*)
"0,0");
65 agattr(graph, AGNODE, (
char*)
"fontsize", (
char*)
"28");
68 agattr(graph, AGEDGE,
const_cast<char*
>(
"label"),
const_cast<char*
>(
""));
69 agattr(graph, AGEDGE,
const_cast<char*
>(
"fontsize"),
const_cast<char*
>(
"28"));
81 gvFreeContext(context);
88 node_t* node = agnode(graph, gv_str(label), TRUE);
89 agset(node, GRAPHVIZ_ATTR_LABEL, gv_str(label));
90 id2node.emplace(
id, node);
96 node_t*
source = id2node.at(sourceID);
97 node_t*
target = id2node.at(targetID);
98 edge_t* edge = agedge(graph,
source,
target, gv_str(
"edge"), TRUE);
101 agset(edge, GRAPHVIZ_ATTR_LABEL, gv_str(label));
103 id2edge.emplace(std::make_pair(sourceID, targetID), edge);
109 gvLayout(context, graph,
"dot");
111 if (!savePNG.empty())
113 gvRenderFilename(context, graph,
"png", gv_str(savePNG));
115 gvFreeLayout(context, graph);
119 for (
auto& pair : id2node)
122 node_t* node = pair.second;
124 std::string labelString = agget(node, GRAPHVIZ_ATTR_LABEL);
125 std::string posString = agget(node, GRAPHVIZ_ATTR_POS);
126 std::string widthString = agget(node, GRAPHVIZ_ATTR_WIDTH);
127 std::string heightString = agget(node, GRAPHVIZ_ATTR_HEIGHT);
130 if (splitPos.size() != 2)
135 float posX = std::stof(splitPos[0]);
136 float posY = std::stof(splitPos[1]);
137 float width = std::stof(widthString);
138 float height = std::stof(heightString);
143 posX -= width / 2.0f;
144 posY -= height / 2.0f;
147 layoutedNode.
posX = posX;
148 layoutedNode.
posY = posY;
149 layoutedNode.
width = width;
150 layoutedNode.
height = height;
151 layoutedNode.
label = labelString;
153 layouted.
nodes.emplace(
id, layoutedNode);
156 for (
auto& pair : id2edge)
158 std::pair<int, int> sourceTarget = pair.first;
159 edge_t* edge = pair.second;
160 std::string posString = agget(edge, GRAPHVIZ_ATTR_POS);
161 std::string label = agget(edge, GRAPHVIZ_ATTR_LABEL);
162 std::string labelPos =
"";
163 if (
char* lp = agget(edge, GRAPHVIZ_ATTR_LABEL_POS))
180 if (label.size() > 0)
183 if (
split.size() == 2)
185 layoutedEdge.
label = label;
190 layouted.
edges.emplace(sourceTarget, layoutedEdge);