Boost Graph Library: Bundled Properties and Graphviz

Originally written: May 10th, 2022 Last edited: May 10th, 2022

These days, I've been working with the C++ Boost Graph Library.

However, I've had trouble finding succinct examples that explain how to add 1) bundled properties and 2) outputting to a dot file.

After a few hours of scouring, I've been able to construct a simple example that shows both. May this help any future lost soul, one of which is likely to be mine.

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

enum VertexType {
	Triangle,
	Square,
	Circle
};

struct VertexProps {
	std::string vertexName;
	VertexType vertexType;
};

struct EdgeProps {
	int weight;
};

template <class Name>
class VertexWriter {
public:
     VertexWriter(Name _name) : name(_name) {}
     template <class Vertex>
     void operator()(std::ostream& out, const Vertex& v) const {
		 	auto item = name[v];
			std::string shape;
			switch (item.vertexType) {
				case Triangle:
					shape = "triangle";
					break;
				case Square:
					shape = "square";
					break;
				case Circle:
					shape = "circle";
					break;
			}
			out << "[label=\"" << item.vertexName << "\" shape=\"" << shape << "\"]";
     }
private:
     Name name;
};


template <class Name>
class EdgeWriter {
public:
     EdgeWriter(Name _name) : name(_name) {}
     template <class Edge>
     void operator()(std::ostream& out, const Edge& e) const {
		 	auto item = name[e];
			std::string color;
			if (item.weight == 47) {
				color = "blue";
			} else {
				color = "red";
			}
			out << "[label=\"" << item.weight << "\" color=\"" << color << "\"]";
     }
private:
     Name name;
};

int main()
{

    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, VertexProps, EdgeProps> Graph;
    Graph g;

	VertexProps v1; v1.vertexName = std::string("foo"); v1.vertexType = Triangle; 
	VertexProps v2; v2.vertexName = std::string("bar"); v2.vertexType = Square;
	VertexProps v3; v3.vertexName = std::string("baz"); v3.vertexType = Circle;
	EdgeProps edge1; edge1.weight = 0x2f;
	EdgeProps edge2; edge2.weight = 0x47;

	auto vertexDescriptor = add_vertex(v1, g);
	auto vertex2 = add_vertex(v2, g);
	auto vertex3 = add_vertex(v3, g);
	add_edge(vertexDescriptor, vertex2, edge1, g);
	add_edge(vertexDescriptor, vertex3, edge2, g);

	VertexWriter<Graph> vertexWriter(g);
	EdgeWriter<Graph> edgeWriter(g);

    write_graphviz(std::cout, g, vertexWriter, edgeWriter);

}