Skip to content

Commit 51b86ae

Browse files
committed
feat: Add support for laying out graphs horizontally
1 parent 8b0701d commit 51b86ae

3 files changed

Lines changed: 46 additions & 4 deletions

File tree

include/graaflib/io/dot.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const auto default_edge_writer{
4343
* edge_id_t and a graph::edge_t and serialize it to a string. Default
4444
* implementations are provided for primitive numeric types.
4545
* @param path Path to the output dot file.
46+
* @param horizontal If true, lays out the graph horizontally, otherwise lays it out vertically. Defaults to
47+
* false.
4648
*/
4749
template <typename V, typename E, graph_type T,
4850
typename VERTEX_WRITER_T = decltype(detail::default_vertex_writer<V>),
@@ -55,8 +57,8 @@ template <typename V, typename E, graph_type T,
5557
void to_dot(
5658
const graph<V, E, T>& graph, const std::filesystem::path& path,
5759
const VERTEX_WRITER_T& vertex_writer = detail::default_vertex_writer<V>,
58-
const EDGE_WRITER_T& edge_writer = detail::default_edge_writer);
60+
const EDGE_WRITER_T& edge_writer = detail::default_edge_writer, bool horizontal = false);
5961

6062
} // namespace graaf::io
6163

62-
#include "dot.tpp"
64+
#include "dot.tpp"

include/graaflib/io/dot.tpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ template <typename V, typename E, graph_type T, typename VERTEX_WRITER_T,
7272
const typename graph<V, E, T>::edge_t&>
7373
void to_dot(const graph<V, E, T>& graph, const std::filesystem::path& path,
7474
const VERTEX_WRITER_T& vertex_writer,
75-
const EDGE_WRITER_T& edge_writer) {
75+
const EDGE_WRITER_T& edge_writer, bool horizontal) {
7676
std::ofstream dot_file{path};
7777

7878
const auto append_line{
@@ -81,6 +81,10 @@ void to_dot(const graph<V, E, T>& graph, const std::filesystem::path& path,
8181
// TODO(bluppes): replace with std::format once Clang supports it
8282
append_line(std::string(detail::graph_type_to_string(T)) + " {");
8383

84+
if (horizontal) {
85+
append_line("rankdir=\"LR\";");
86+
}
87+
8488
for (const auto& [vertex_id, vertex] : graph.get_vertices()) {
8589
append_line("\t" + std::to_string(vertex_id) + " [" +
8690
vertex_writer(vertex_id, vertex) + "];");

test/graaflib/io/dot_test.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,40 @@ TEST(DotTest, DefaultWriters) {
256256
vertex_2)) != std::string::npos);
257257
}
258258

259-
} // namespace graaf::io
259+
TEST(DotTest, HorizontalGraph) {
260+
// GIVEN
261+
struct vertex_t {
262+
int numeric_data{};
263+
std::string string_data{};
264+
};
265+
266+
struct edge_t {
267+
int numeric_data{};
268+
std::string string_data{};
269+
};
270+
271+
const std::filesystem::path path{std::filesystem::temp_directory_path() /
272+
"DotTest_HorizontalGraph.dot"};
273+
directed_graph<vertex_t, edge_t> graph{};
274+
275+
const auto vertex_1{graph.add_vertex(vertex_t{10, "vertex 1"})};
276+
const auto vertex_2{graph.add_vertex(vertex_t{20, "vertex 2"})};
277+
graph.add_edge(vertex_1, vertex_2, edge_t{100, "edge 1"});
278+
279+
const auto vertex_writer{
280+
[](vertex_id_t /*vertex_id*/, const vertex_t& vertex) {
281+
return fmt::format("{}, {}", vertex.numeric_data, vertex.string_data);
282+
}};
283+
const auto edge_writer{[](const edge_id_t& /*edge_id*/, const auto& edge) {
284+
return fmt::format("{}, {}", edge.numeric_data, edge.string_data);
285+
}};
286+
287+
// WHEN
288+
to_dot(graph, path, vertex_writer, edge_writer, true);
289+
290+
// THEN
291+
const auto dot_content{read_to_string(path)};
292+
ASSERT_TRUE(dot_content.find("rankdir=\"LR\"") != std::string::npos);
293+
}
294+
295+
} // namespace graaf::io

0 commit comments

Comments
 (0)