
Ok thanks Jeremiah. This compiles and produces subgraph clauses, but it seems from browsing the subgraph implementation in boost/graph/graphviz.hpp that I'm currently unable to... - use custom label writers with subgraphs - insert appropriate per-subgraph formatting detail required to get subgraphs rendering correctly via dot (eg as is shown in libs/graph/example/graphviz_test.dot). I think I'd better leave this for now unless the above is straightforward. Thanks for your time. I may look into it again at some stage, maybe even get around to submitting a patch if I find the time... Thanks, Chris On 3 August 2012 01:38, Jeremiah Willcock <jewillco@osl.iu.edu> wrote:
On Thu, 2 Aug 2012, Chris Cooper wrote:
With the dynamic property code I posted previously you should be able to just change that write_graphviz_dp call to write_graphviz(ofs, G0). Here's some code as per my original post. With boost trunk it's currently failing with...
include/boost/pending/property.hpp:126:5: error: no type named ‘type’ in ‘struct boost::lookup_one_property_internal<boost::no_property, boost::graph_graph_attribute_t>’
It looks like some of the property map defaults in write_graphviz got lost when I changed how property lookup works, and write_graphviz on subgraphs isn't using the default property writers like the normal version of write_graphviz does. The workaround is to change your property declarations to:
typedef std::map<std::string, std::string> smap; typedef property<vertex_color_t, int, property<vertex_attribute_t, smap> > vertex_p; typedef property<edge_index_t, int, property<edge_attribute_t, smap> > edge_p; typedef property<graph_name_t, std::string, property<graph_graph_attribute_t, smap, property<graph_vertex_attribute_t, smap, property<graph_edge_attribute_t, smap> > > > graph_p;
You don't need to initialize the new properties added here; the default-constructed empty versions are fine. If you want to save storage, you can create a dummy class that acts like an empty std::map<string, string> and use that instead of smap in the code.
-- Jeremiah Willcock
#include <boost/config.hpp> #include <iostream> #include <fstream> #include <boost/graph/subgraph.hpp> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graph_utility.hpp> #include <boost/graph/graphviz.hpp>
int main(int,char*[]) { using namespace boost; typedef adjacency_list_traits<vecS, vecS, directedS> Traits; typedef property<vertex_color_t, int> vertex_p; typedef property<edge_index_t, int> edge_p; typedef property<graph_name_t, std::string> graph_p; typedef subgraph< adjacency_list<vecS, vecS, directedS, vertex_p, edge_p, graph_p > > Graph;
const int N = 6; Graph G0(N); enum { A, B, C, D, E, F}; // for conveniently refering to vertices in G0
Graph& G1 = G0.create_subgraph(); Graph& G2 = G0.create_subgraph(); enum { A1, B1, C1 }; // for conveniently refering to vertices in G1 enum { A2, B2 }; // for conveniently refering to vertices in G2
add_vertex(C, G1); // global vertex C becomes local A1 for G1 add_vertex(E, G1); // global vertex E becomes local B1 for G1 add_vertex(F, G1); // global vertex F becomes local C1 for G1
add_vertex(A, G2); // global vertex A becomes local A1 for G2 add_vertex(B, G2); // global vertex B becomes local B1 for G2
add_edge(A, B, G0); add_edge(B, C, G0); add_edge(B, D, G0); add_edge(E, B, G0); add_edge(E, F, G0); add_edge(F, D, G0);
add_edge(A1, C1, G1); // (A1,C1) is subgraph G1 local indices for (C,F).
const char* names[] = { "A", "B", "C", "D", "E", "F" }; const char* enames[] = { "0", "1", "2", "3", "4", "5" }; const char* gnames[] = { "G0", "G1", "G2" };
std::ofstream ofs("out.dot");
#if 0 // works write_graphviz(ofs, G0.m_graph, make_label_writer(names)); #else write_graphviz(ofs, G0); //write_graphviz(ofs, G0, make_label_writer(names), make_label_writer(enames), make_label_writer(gnames)); #endif
return 0; }
On 2 August 2012 11:58, Jeremiah Willcock <jewillco@osl.iu.edu> wrote:
On Thu, 2 Aug 2012, Chris Cooper wrote:
Thanks Jeremiah,
I've now got something that compiles and runs, but still doesn't include 'subgraph' clauses in the dot output and corresponding rectangles when rendered. Interestingly if I now change back to write_graphviz(ofs, G0) I do get some subgraph clauses, but the names are messed up presumably since they're now being set up using dynamic properties. Also the subgraphs still don't render in this case.
It looks like you do need to use write_graphviz (without _dp) to get subgraphs in the output. Could you please try your original code with the Boost trunk and see what happens? That will allow your line numbers to match up with mine. Also, a full code example using write_graphviz would be helpful. Thank you.
-- Jeremiah Willcock _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users