TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/graph/GraphExporter.tcc
Go to the documentation of this file.
00001 #include <tuttle/host/graph/InternalGraph.hpp>
00002 #include <tuttle/host/graph/IVertex.hpp>
00003 #include <tuttle/host/graph/IEdge.hpp>
00004 
00005 #include <boost/graph/graphviz.hpp>
00006 #include <iostream>
00007 
00008 namespace tuttle {
00009 namespace host {
00010 namespace graph {
00011 
00012 namespace detail {
00013 template<class T>
00014 std::ostream& operator<<( std::ostream& os, const DotEntry<T>& d )
00015 {
00016 //      os << "[" << d._key << "=\"" << d._value << "\"]";
00017         os << d._key << "=\"" << d._value << "\"";
00018         return os;
00019 }
00020 template<class T>
00021 std::ostream& operator<<( std::ostream& os, const SubDotEntry<T>& d )
00022 {
00023         os << d._key << ":\'" << d._value << "\'\\n";
00024         return os;
00025 }
00026 }
00027 
00028 /**
00029  * @brief Use this function to force the correct syntax.
00030  *        os << dotEntry( "label", "fooNode");
00031  *        output: [label="fooNode"]
00032  */
00033 template<class T>
00034 detail::DotEntry<T> dotEntry( const std::string& key, const T& value )
00035 {
00036         return detail::DotEntry<T>( key, value );
00037 }
00038 template<class T>
00039 detail::SubDotEntry<T> subDotEntry( const std::string& key, const T& value )
00040 {
00041         return detail::SubDotEntry<T>( key, value );
00042 }
00043 
00044 namespace detail {
00045 template <class Name>
00046 class simple_node_writer
00047 {
00048 public:
00049         simple_node_writer( Name _name ) : name( _name ) {}
00050         template <class VertexOrEdge>
00051         void operator()( std::ostream& out, const VertexOrEdge& v ) const
00052         {
00053                 out << " [ " << get( name, v ) << " ]";
00054         }
00055 
00056 private:
00057         Name name;
00058 };
00059 }
00060 
00061 /**
00062  * @brief For simple export, don't use the real .dot syntax, just put the name.
00063  * like: [ fooNode ]
00064  * instead of: [label="fooNode"]
00065  */
00066 template <class Name>
00067 inline detail::simple_node_writer<Name> make_simple_node_writer( Name n )
00068 {
00069         return detail::simple_node_writer<Name>( n );
00070 }
00071 
00072 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList>
00073 inline void exportSimple( std::ostream& os, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g )
00074 {
00075         using namespace boost;
00076         boost::write_graphviz( os, g.getGraph(),
00077                                make_simple_node_writer( get( &Vertex::_name, g.getGraph() ) ),
00078                                make_simple_node_writer( get( &ProcessEdge::_name,   g.getGraph() ) ) );
00079 }
00080 
00081 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList>
00082 inline void exportAsDOT( std::ostream& os, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g )
00083 {
00084         std::map<std::string, std::string> graph_attr, vertex_attr, edge_attr;
00085         graph_attr["size"]       = "6,6";
00086         graph_attr["rankdir"]    = "LR";
00087         graph_attr["ratio"]      = "fill";
00088         graph_attr["label"]      = "TuttleOFX";
00089         vertex_attr["shape"]     = "circle";
00090         vertex_attr["color"]     = "dodgerblue4";
00091         vertex_attr["fontcolor"] = "dodgerblue4";
00092         edge_attr["style"]       = "dashed";
00093         edge_attr["minlen"]      = "1";
00094         edge_attr["color"]       = "darkslategray";
00095         edge_attr["fontcolor"]   = "darkslategray";
00096 
00097         using namespace boost;
00098         boost::write_graphviz( os,
00099                                g.getGraph(),
00100                                boost::make_label_writer( get( &IVertex::_name, g.getGraph() ) ),
00101                                boost::make_label_writer( get( &IEdge::_name, g.getGraph() ) ),
00102                                boost::make_graph_attributes_writer( graph_attr, vertex_attr, edge_attr ) );
00103 }
00104 
00105 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList>
00106 inline void exportAsDOT( const std::string& filename, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g )
00107 {
00108         std::ofstream ofs( filename.c_str() );
00109 
00110         exportAsDOT( ofs, g );
00111 }
00112 
00113 namespace detail {
00114 template <class Graph>
00115 struct debug_node_writer
00116 {
00117         debug_node_writer( const Graph& graph ) : _graph( graph ) {}
00118         template <class VertexOrEdge>
00119         void operator()( std::ostream& out, const VertexOrEdge& vd ) const
00120         {
00121                 _graph.instance(vd).exportDotDebug(out);
00122         }
00123         const Graph& _graph;
00124 };
00125 }
00126 
00127 template<class Graph>
00128 inline detail::debug_node_writer<Graph> make_debug_node_writer( const Graph g )
00129 {
00130         return detail::debug_node_writer<Graph>( g );
00131 }
00132 
00133 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList>
00134 inline void exportDebugAsDOT( std::ostream& os, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g )
00135 {
00136         std::map<std::string, std::string> graph_attr, vertex_attr, edge_attr;
00137         graph_attr["size"]       = "6,6";
00138         graph_attr["rankdir"]    = "LR";
00139         graph_attr["ratio"]      = "fill";
00140         graph_attr["label"]      = "TuttleOFX";
00141         vertex_attr["shape"]     = "circle";
00142         vertex_attr["color"]     = "dodgerblue4";
00143         vertex_attr["fontcolor"] = "dodgerblue4";
00144         edge_attr["style"]       = "dashed";
00145         edge_attr["minlen"]      = "1";
00146         edge_attr["color"]       = "darkslategray";
00147         edge_attr["fontcolor"]   = "darkslategray";
00148 
00149         using namespace boost;
00150         boost::write_graphviz( os,
00151                                g.getGraph(),
00152                                make_debug_node_writer(g),
00153                                make_debug_node_writer(g),
00154                                boost::make_graph_attributes_writer( graph_attr, vertex_attr, edge_attr ) );
00155 }
00156 
00157 template<typename Vertex, typename ProcessEdge, typename OutEdgeList, typename VertexList, typename EdgeList>
00158 inline void exportDebugAsDOT( const std::string& filename, const InternalGraph<Vertex, ProcessEdge, OutEdgeList, VertexList, EdgeList>& g )
00159 {
00160         std::ofstream ofs( filename.c_str() );
00161 
00162         exportDebugAsDOT( ofs, g );
00163 }
00164 
00165 }
00166 }
00167 }
00168