Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::graph subgraph + write_graphviz()
From: Chris Cooper (rallycoops_at_[hidden])
Date: 2012-08-02 20:28:58


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_at_[hidden]> 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_at_[hidden]> 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_at_[hidden]
>>> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>>
>> _______________________________________________
>> Boost-users mailing list
>> Boost-users_at_[hidden]
>> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net