10 #ifndef smtk_graph_arcs_Dump_h
11 #define smtk_graph_arcs_Dump_h
13 #include "smtk/graph/ArcImplementation.h"
14 #include "smtk/graph/ArcProperties.h"
15 #include "smtk/graph/Component.h"
17 #include "smtk/string/Token.h"
19 #include "smtk/common/Color.h"
21 #include "nlohmann/json.hpp"
35 using json = nlohmann::json;
41 struct SMTKCORE_EXPORT
Dump
44 : m_mimeType(
"text/vnd.graphviz")
49 : m_mimeType(mimeType)
54 : m_mimeType(mimeType)
55 , m_includeArcs(whitelist)
61 const std::set<smtk::string::Token>& whitelist,
62 const std::set<smtk::string::Token>& blacklist)
63 : m_mimeType(mimeType)
64 , m_includeArcs(whitelist)
65 , m_excludeArcs(blacklist)
71 m_arcColors[arcType] = color;
74 static void setBackground(
const std::array<double, 4>& bgcolor)
76 s_backgroundColor = std::unique_ptr<std::array<double, 4>>(
new std::array<double, 4>(bgcolor));
79 template<
typename ResourceType>
80 static void begin(
const ResourceType* resource, std::ostream& stream,
const Dump&
self)
86 std::function<void(
const std::shared_ptr<smtk::resource::Component>&)> mapNodes =
88 int nodeLabel =
self.m_nextNodeId++;
89 self.m_nodeMap[comp->id()] = nodeLabel;
91 if (
self.m_mimeType ==
"text/vnd.graphviz")
93 stream <<
"digraph \"" << resource->name() <<
"\" {\n\n";
94 if (s_backgroundColor)
96 stream <<
" bgcolor=\""
97 << smtk::common::Color::floatRGBAToString(s_backgroundColor->data()) <<
"\"\n";
99 if (
self.m_includeNodes)
101 std::function<void(
const std::shared_ptr<smtk::resource::Component>&)> dumpNodes =
103 int nodeLabel =
self.m_nextNodeId++;
104 self.m_nodeMap[comp->id()] = nodeLabel;
107 std::string nodeClass = comp->typeName();
108 std::replace(nodeClass.begin(), nodeClass.end(),
':',
'_');
109 stream <<
" " << nodeLabel <<
" [class=\"" << nodeClass <<
"\", label=\""
110 << comp->name() <<
"\"]\n";
112 resource->visit(dumpNodes);
117 resource->visit(mapNodes);
122 if (
self.m_includeNodes)
124 stream <<
"---\nNodes of " << resource->name() <<
"\n";
125 std::function<void(
const std::shared_ptr<smtk::resource::Component>&)> dumpNodes =
127 int nodeLabel =
self.m_nextNodeId++;
128 self.m_nodeMap[comp->id()] = nodeLabel;
129 stream <<
" " << nodeLabel <<
": " << comp.get() <<
" type " << comp->typeName()
130 <<
" name " << comp->name() <<
"\n";
132 resource->visit(dumpNodes);
134 stream <<
"---\nArcs of " << resource->name() <<
"\n";
139 template<
typename Impl,
typename ArcTraits =
typename Impl::Traits,
typename ResourceType>
142 const ResourceType* resource,
143 std::ostream& stream,
144 const Dump&
self)
const
146 std::string arcType = smtk::common::typeName<ArcTraits>();
149 !arcs || arcs->empty() ||
150 (
self.m_includeArcs.empty() &&
151 self.m_excludeArcs.find(arcToken) !=
self.m_excludeArcs.end()) ||
152 (!
self.m_includeArcs.empty() &&
153 self.m_includeArcs.find(arcToken) ==
self.m_includeArcs.end()))
158 if (
self.m_mimeType !=
"text/vnd.graphviz")
160 stream <<
" " << arcType <<
"\n";
166 std::string arcClass = arcType;
167 std::replace(arcClass.begin(), arcClass.end(),
':',
'_');
168 stream <<
" subgraph \"" << arcType <<
"\" {\n";
169 stream <<
" edge [class=\"" << arcClass <<
"\"";
170 if (!ArcTraits::Directed::value)
172 stream <<
" dir=\"none\"";
174 auto colorIt =
self.m_arcColors.find(arcType);
175 if (colorIt !=
self.m_arcColors.end())
177 stream <<
" color=\"" << smtk::common::Color::floatRGBAToString(colorIt->second.data())
182 arcs->visitAllOutgoingNodes(
183 resource, [&stream, &
self](
const typename ArcTraits::FromType* node) {
184 int fromLabel =
self.m_nodeMap[node->
id()];
185 std::size_t arcCount = 0;
186 std::ostringstream line;
187 if (
self.m_mimeType !=
"text/vnd.graphviz")
189 line <<
" " << node <<
": ";
191 node->template outgoing<ArcTraits>().visit(
192 [&fromLabel, &line, &arcCount, &stream, &
self](
const typename ArcTraits::ToType* other) {
194 int toLabel =
self.m_nodeMap[other->id()];
195 if (
self.m_mimeType ==
"text/vnd.graphviz")
197 stream <<
" " << fromLabel <<
" -> " << toLabel <<
"\n";
201 line <<
" " << toLabel;
204 if (arcCount > 0 &&
self.m_mimeType !=
"text/vnd.graphviz")
206 stream << line.str() <<
"\n";
209 if (
self.m_mimeType ==
"text/vnd.graphviz")
217 template<
typename ResourceType>
221 const ResourceType* resource,
222 std::ostream& stream,
223 const Dump&
self)
const
226 (
self.m_includeArcs.empty() &&
227 self.m_excludeArcs.find(arcTypeName) !=
self.m_excludeArcs.end()) ||
228 (!
self.m_includeArcs.empty() &&
229 self.m_includeArcs.find(arcTypeName) ==
self.m_includeArcs.end()))
234 if (
self.m_mimeType !=
"text/vnd.graphviz")
236 stream <<
" " << arcTypeName.
data() <<
"\n";
242 std::string arcClass = arcTypeName.
data();
243 std::replace(arcClass.begin(), arcClass.end(),
':',
'_');
244 stream <<
" subgraph \"" << arcTypeName.
data() <<
"\" {\n";
245 stream <<
" edge [class=\"" << arcClass <<
"\"";
246 if (arcs.directionality() == Directionality::IsUndirected)
248 stream <<
" dir=\"none\"";
250 auto colorIt =
self.m_arcColors.find(arcTypeName);
251 if (colorIt !=
self.m_arcColors.end())
253 stream <<
" color=\"" << smtk::common::Color::floatRGBAToString(colorIt->second.data())
260 int fromLabel =
self.m_nodeMap[node->
id()];
261 std::size_t arcCount = 0;
262 std::ostringstream line;
263 if (
self.m_mimeType !=
"text/vnd.graphviz")
265 line <<
" " << node <<
": ";
268 ->outgoing(arcTypeName)
269 .visit([&arcTypeName, &fromLabel, &line, &arcCount, &stream, &
self](
272 int toLabel =
self.m_nodeMap[other->
id()];
273 if (
self.m_mimeType ==
"text/vnd.graphviz")
275 stream <<
" " << fromLabel <<
" -> " << toLabel <<
"\n";
279 line <<
" " << toLabel;
283 if (arcCount > 0 &&
self.m_mimeType !=
"text/vnd.graphviz")
285 stream << line.str() <<
"\n";
289 if (
self.m_mimeType ==
"text/vnd.graphviz")
296 template<
typename ResourceType>
297 static void end(
const ResourceType* resource, std::ostream& stream,
const Dump&
self)
303 if (
self.m_mimeType ==
"text/vnd.graphviz")
314 std::set<smtk::string::Token> m_includeArcs;
315 std::set<smtk::string::Token> m_excludeArcs;
316 bool m_includeNodes =
true;
317 std::map<smtk::string::Token, std::array<double, 4>> m_arcColors;
318 mutable std::map<smtk::common::UUID, int> m_nodeMap;
319 mutable int m_nextNodeId = 1;
320 static std::unique_ptr<std::array<double, 4>> s_backgroundColor;
327 #endif // smtk_graph_arcs_Dump_h