Skip to main content

Dot Serialization Example

The to_dot function as defined under graaf::io can be used to searialize graphs to the dot format. This can be handy for debugging purposes, as well as for post-processing of your graphs in another tool which supports the format.

Numeric primitive types

Default vertex and edge writers are provided such that you can serialize graphs with numeric primitive vertices and edges. For instance:

graaf::undirected_graph<int, float> my_graph{};

// ...

graaf::io::to_dot(my_graph, path):

User defined types

For user defined vertex and edge types, it is necessary to provide your own vertex and edge writers. These writers should take a vertex or edge as a parameter and serialize it to a string. This resulting string is used in the dot attribute list of the respective vertex or edge.

For example, consider the following user defined vertex and edge types:

struct my_vertex {
int number{};
std::string name{};
};

enum class edge_priority { LOW, HIGH };

struct my_edge {
edge_priority priority{edge_priority::LOW};
float weight{};
};

We define two lambdas to serialize these vertices and edges. Here we can use any of the graphviz attributes. In this example, we use fmtlib to format our strings.

Vertex writer

const auto vertex_writer{[](graaf::vertex_id_t vertex_id,
const my_vertex& vertex) -> std::string {
const auto color{vertex.number <= 25 ? "lightcyan" : "mediumspringgreen"};
return fmt::format("label=\"{}: {}\", fillcolor={}, style=filled", vertex_id, vertex.name, color);
}};

Edge writer

const auto edge_writer{[](const graaf::vertex_ids_t& /*edge_id*/,
const my_edge& edge) -> std::string {
const auto style{edge.priority == edge_priority::HIGH ? "solid" : "dashed"};
return fmt::format("label=\"{}\", style={}, color=gray, fontcolor=gray", edge.weight, style);
}};

Now let's create a directed graph and serialize it to dot:

graaf::directed_graph<my_vertex, my_edge> graph{};

const auto vertex_1{graph.add_vertex({10, "some data"})};
const auto vertex_2{graph.add_vertex({20, "some more data"})};
// ...

graph.add_edge(vertex_1, vertex_2, {edge_priority::HIGH, 3.3});
// ...

const std::filesystem::path dof_file_path{"./my_graph.dot"};
graaf::io::to_dot(my_graph, dof_file_path, vertex_writer, edge_writer);

The contents of my_graph.dot can be processed in any tool which supports dot format. For example, you can use the dot command line tool to generate png images:

dot -Tpng ./my_graph.dot -o my_graph.png

Alternatively, you can use graphviz online for easy visualization: