9

I see examples of this when using property maps, but not when using structs to handle the vertices and edges (I think this is called 'bundles').

I have vertices and edges defined as such, in an adjacency list graph.

struct Vertex
{
    string name;
    int some_int;
};

struct Edge
{
    double weight;
};

The graph is constructed as follows:

typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, Vertex, Edge> boost_graph;

I want to print my graph of these objects in Graphviz format, so I can view it as an image. However, I don't only want the nodes and edges. I also want the attribute name on vertices and weight on edges to appear in the image. How can I do this?

Jim
  • 4,509
  • 16
  • 50
  • 80
  • I think you should show a full sample. I can't see how you built a tree with Edge 'defined' as that. Perhaps, a mapped property for an edge? – sehe Feb 07 '12 at 19:58
  • @sehe Thanks. I've added the graph definition to the question. The edges and vertices are added by the functions boost::add_edge and boost::add_vertex – Jim Feb 07 '12 at 19:59
  • Are you looking for the dot format definition? http://www.graphviz.org/Gallery.php just click any of the examples and view the code it takes to make them :-) – Martin Kristiansen Feb 08 '12 at 12:33
  • @MartinKristiansen Thanks. Actually, Boost is supposed to have functionality to print to graphviz that I'd like to take advantage of – Jim Feb 08 '12 at 13:48

3 Answers3

31

I just stumbled upon this question. Although it has an accepted answer, I thought I'll add my version too.

You are using bundled property in your graph. The correct way to get property map from your bundled properties is to use boost::get. So you can do something like:

boost::write_graphviz(std::cout, your_graph,
    boost::make_label_writer(boost::get(&Vertex::name, your_graph)),
    boost::make_label_writer(boost::get(&Edge::weight, your_graph)),
    );

Where your_graph is the graph object you have created.

Vikas
  • 8,790
  • 4
  • 38
  • 48
  • 2
    I've the same issue, but, instead of public attribute, I've a method for my vertex class, say class Vertex{ public: int getID(); private: int m_iID;}; What should I do in this case to put the ID in graphviz file? – Jepessen Sep 24 '13 at 09:42
6

I gave bad info the first time. Here is the correct answer.

#include <boost/graph/graphviz.hpp>

using namespace boost;

// Graph type
typedef adjacency_list<vecS, vecS, directedS, VertexProperties, EdgeProperty> Graph;
Graph g;
std::vector<std::string> NameVec; // for dot file names


// write the dot file
std::ofstream dotfile (strDotFile.c_str ());
write_graphviz (dotfile, g, make_label_writer(&NameVec[0]));
Dan
  • 1,339
  • 3
  • 13
  • 19
  • Thanks but I don't see a method called WriteDOTFile.. Where is this? – Jim Feb 08 '12 at 19:46
  • @MartinKristiansen Yeah, but this doesn't explain where the .WriteDOTFile function is? I'm not sure what you are implying. – Jim Feb 08 '12 at 23:00
  • 1
    Thanks for the update. Does make_label_writer somehow pick out the string from the Vertex struct? – Jim Feb 09 '12 at 15:06
  • Yes, you load the vector with the string name for each of the nodes in the graph. – Dan Feb 09 '12 at 15:19
  • Here is the example I used a while back http://www.boost.org/doc/libs/1_48_0/libs/graph/doc/write-graphviz.html – Dan Feb 09 '12 at 15:20
0

Using boost::dynamic_properties (See here) and boost::write_graphviz_dp (See here), you can output the graph with properties defined in customized vertex and edge structs. To register the properties into a boost::dynamic_properties object, you must use reserved attributes, such as label, weight, etc.

One caveat is that the BOOST library (I am using 1.82.0) only supports "node_id" as the attribute name of node id, while the current GraphViz standard uses "id" instead.

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <fstream>

struct Vertex {
  int some_int;
  std::string name;
};

struct Edge {
  double weight;
};

using DirectedSimpleGraph =
    boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, Vertex,
                          Edge>;
using VertexSpec = boost::graph_traits<DirectedSimpleGraph>::vertex_descriptor;
using EdgeSpec = boost::graph_traits<DirectedSimpleGraph>::edge_descriptor;

int main() {
  DirectedSimpleGraph graph;
  boost::dynamic_properties dp;

  // "node_id", "label", and "weight" are reserved keywords
  // of the GraphViz DOT Format
  dp.property("node_id", boost::get(&Vertex::some_int, graph));
  dp.property("label", boost::get(&Vertex::name, graph));
  dp.property("weight", boost::get(&Edge::weight, graph));

  // Create vertices with id and label
  VertexSpec v0 = boost::add_vertex(Vertex{0, "Zero"}, graph);
  VertexSpec v1 = boost::add_vertex(Vertex{1, "One"}, graph);
  VertexSpec v2 = boost::add_vertex(Vertex{2, "Two"}, graph);
  VertexSpec v3 = boost::add_vertex(Vertex{3, "Three"}, graph);

  // Create edges with weight
  boost::add_edge(v0, v1, Edge{1.0}, graph);
  boost::add_edge(v0, v2, Edge{2.0}, graph);
  boost::add_edge(v2, v3, Edge{3.0}, graph);

  // Write to file
  std::ofstream graph_file_out("./out.gv");
  boost::write_graphviz_dp(graph_file_out, graph, dp);
}
wu1meng2
  • 71
  • 6