DOT (Graphviz) format export for visualizing graphs.
This module exports graphs to the DOT language,
which is the native format for Graphviz - a powerful open-source
graph visualization tool. The exported files can be rendered to PNG, SVG, PDF, and other
formats using the dot, neato, circo, or other Graphviz layout engines.
Quick Start
# Export with default styling
dot_string = Yog.Render.DOT.to_dot(my_graph, Yog.Render.DOT.default_options())
# Write to file and render with Graphviz CLI
# $ dot -Tpng output.dot -o graph.pngCustomization
Use options/0 to customize:
- Node labels and shapes
- Edge labels and styles
- Per-node and per-edge attributes (custom colors, shapes, etc.)
- Subgraphs/clusters for visual grouping
- Highlight specific nodes or paths
- Graph direction (LR, TB, etc.)
Generic Data Types
The to_dot function works with any node and edge data types. Use
default_options_with_edge_formatter/1 when your edge data is not a String.
Per-Element Styling
Provide custom attribute functions for fine-grained control:
options = %{
Yog.Render.DOT.default_options() |
node_attributes: fn id, data ->
case id do
1 -> [{:fillcolor, "green"}, {:shape, "diamond"}]
_ -> []
end
end,
edge_attributes: fn from, to, weight ->
if weight > 10 do
[{:color, "red"}, {:penwidth, 2}]
else
[]
end
end
}Subgraphs and Clusters
Group nodes visually using subgraphs:
options = %{
Yog.Render.DOT.default_options() |
subgraphs: [
%{
name: "cluster_0",
label: "Cluster A",
node_ids: [1, 2, 3],
style: :filled,
fillcolor: "lightgrey",
color: nil
}
]
}Rendering Options
| Engine | Best For |
|---|---|
dot | Hierarchical layouts (DAGs, trees) |
neato | Spring-based layouts (undirected) |
circo | Circular layouts |
fdp | Force-directed layouts |
sfdp | Large graphs |
References
Summary
Types
Arrow head/tail style
Graphviz layout engine
Node shapes
Options for customizing DOT (Graphviz) diagram rendering
Overlap handling
Graph direction (rank direction)
Edge routing style
Visual style
A subgraph (cluster) for grouping nodes visually in the diagram.
Functions
Creates DOT options that color nodes by community assignment.
Creates DOT options that color the source and sink sides of a min-cut.
Creates default DOT options with simple labeling and sensible styling.
Creates default DOT options with custom label formatters for both nodes and edges.
Creates default DOT options with a custom edge formatter.
Creates DOT options that highlight matched edges from a matching result.
Creates DOT options that highlight an MST result.
Converts a shortest path result to highlighted DOT options.
Returns a pre-configured theme as DOT options.
Converts a graph to DOT (Graphviz) syntax.
Types
@type arrow_style() :: :normal | :dot | :diamond | :odiamond | :box | :crow | :vee | :inv | :tee | :none | {:custom, String.t()}
Arrow head/tail style
@type layout() :: :dot | :neato | :circo | :fdp | :sfdp | :twopi | :osage | {:custom, String.t()}
Graphviz layout engine
@type node_shape() :: :box | :box3d | :circle | :cloud | :component | :cylinder | :diamond | :doublecircle | :ellipse | :folder | :hexagon | :house | :invhouse | :invtriangle | :note | :octagon | :parallelogram | :pentagon | :plain | :plaintext | :point | :rect | :rectangle | :square | :tab | :trapezoid | :triangle | :underline | {:custom, String.t()}
Node shapes
@type options() :: %{ node_label: (Yog.node_id(), any() -> String.t()), edge_label: (any() -> String.t()), highlighted_nodes: [Yog.node_id()] | nil, highlighted_edges: [{Yog.node_id(), Yog.node_id()}] | nil, node_attributes: (Yog.node_id(), any() -> [{atom(), String.t()}]), edge_attributes: (Yog.node_id(), Yog.node_id(), any() -> [{atom(), String.t()}]), subgraphs: [subgraph()] | nil, ranks: [{:same | :min | :max | :source | :sink, [Yog.node_id()]}] | nil, graph_name: String.t(), layout: layout() | nil, rankdir: rank_dir() | nil, bgcolor: String.t() | nil, splines: splines() | nil, overlap: overlap() | nil, nodesep: float() | nil, ranksep: float() | nil, node_shape: node_shape(), node_color: String.t(), node_style: style(), node_fontname: String.t(), node_fontsize: integer(), node_fontcolor: String.t(), edge_color: String.t(), edge_style: style(), edge_fontname: String.t(), edge_fontsize: integer(), edge_penwidth: float(), arrowhead: arrow_style() | nil, arrowtail: arrow_style() | nil, highlight_color: String.t(), highlight_penwidth: float() }
Options for customizing DOT (Graphviz) diagram rendering
@type overlap() :: true | false | :scale | :scalexy | :prism | {:custom, String.t()}
Overlap handling
@type rank_dir() :: :tb | :lr | :bt | :rl
Graph direction (rank direction)
@type splines() :: :line | :polyline | :curved | :ortho | :spline | :none
Edge routing style
@type style() ::
:solid
| :dashed
| :dotted
| :bold
| :filled
| :rounded
| :diagonals
| :striped
| :wedged
Visual style
@type subgraph() :: %{ name: String.t(), label: String.t() | nil, node_ids: [Yog.node_id()] | nil, style: style() | nil, fillcolor: String.t() | nil, color: String.t() | nil, subgraphs: [subgraph()] | nil }
A subgraph (cluster) for grouping nodes visually in the diagram.
In Graphviz, subgraphs with names starting with "cluster_" are rendered as bounded rectangles around the contained nodes.
Subgraphs may be nested by providing the subgraphs key, which creates
a cluster hierarchy (e.g. VPC → AZ → nodes).
Functions
@spec community_to_options(Yog.Community.Result.t(), options()) :: options()
Creates DOT options that color nodes by community assignment.
Each community gets a distinct color from a generated palette. The palette cycles through visually distinct hues.
Example
result = Yog.Community.Louvain.detect(graph)
options = Yog.Render.DOT.community_to_options(result)
dot_string = Yog.Render.DOT.to_dot(graph, options)
@spec cut_to_options(Yog.Flow.MinCutResult.t(), options()) :: options()
Creates DOT options that color the source and sink sides of a min-cut.
Source-side nodes are colored with source_color (default: light blue),
sink-side nodes with sink_color (default: light coral).
Requires the MinCutResult to have source_side and sink_side populated
(use track_partitions: true or extract_min_cut/1).
Example
result = Yog.Flow.MinCut.global_min_cut(graph, track_partitions: true)
options = Yog.Render.DOT.cut_to_options(result)
dot_string = Yog.Render.DOT.to_dot(graph, options)
@spec default_options() :: options()
Creates default DOT options with simple labeling and sensible styling.
Default configuration:
- Layout: Auto-detected by Graphviz
- Direction: Top-to-bottom
- Node shape: Ellipse
- Colors: Light blue nodes, black edges
- Font: Helvetica 12pt
Examples
iex> opts = Yog.Render.DOT.default_options()
iex> opts.graph_name
"G"
iex> opts.node_shape
:ellipse
iex> opts.node_color
"lightblue"
@spec default_options_with( node_label: (Yog.node_id(), any() -> String.t()), edge_label: (any() -> String.t()) ) :: options()
Creates default DOT options with custom label formatters for both nodes and edges.
Example
options = Yog.Render.DOT.default_options_with(
node_label: fn id, data -> "#{data} (#{id})" end,
edge_label: fn weight -> "#{weight} ms" end
)
Creates default DOT options with a custom edge formatter.
Use this when your graph has non-String edge data (e.g., Int, Float, custom types).
Example
# For a graph with Int edge weights
options = Yog.Render.DOT.default_options_with_edge_formatter(fn weight ->
Integer.to_string(weight)
end)
@spec matching_to_options(%{required(Yog.node_id()) => Yog.node_id()}, options()) :: options()
Creates DOT options that highlight matched edges from a matching result.
Works with results from both Yog.Matching.hopcroft_karp/1 and
Yog.Matching.hungarian/2 (the matching map component).
Example
matching = Yog.Matching.hopcroft_karp(graph)
options = Yog.Render.DOT.matching_to_options(matching)
dot_string = Yog.Render.DOT.to_dot(graph, options)
@spec mst_to_options(Yog.MST.Result.t(), options()) :: options()
Creates DOT options that highlight an MST result.
MST edges are highlighted and non-MST edges use default styling.
Example
result = Yog.MST.kruskal(graph)
options = Yog.Render.DOT.mst_to_options(result)
dot_string = Yog.Render.DOT.to_dot(graph, options)
Converts a shortest path result to highlighted DOT options.
Creates a copy of the base options with the path's nodes and edges set to be highlighted. This is useful for visualizing algorithm results.
Example
case Yog.Pathfinding.Dijkstra.shortest_path(...) do
{:ok, path} ->
options = Yog.Render.DOT.path_to_options(path, Yog.Render.DOT.default_options())
dot_string = Yog.Render.DOT.to_dot(graph, options)
:error ->
""
end
Returns a pre-configured theme as DOT options.
Available themes:
:default— Light blue nodes, black edges (same asdefault_options/0):dark— Dark background with neon accent colors, ideal for dark UIs:minimal— Clean wireframe look with no fills and thin lines:presentation— Large fonts and bold colors for slides and demos
Examples
iex> opts = Yog.Render.DOT.theme(:dark)
iex> opts.bgcolor
"#1a1a2e"
iex> opts.node_color
"#16213e"
iex> opts = Yog.Render.DOT.theme(:minimal)
iex> opts.node_style
:solid
iex> opts = Yog.Render.DOT.theme(:presentation)
iex> opts.node_fontsize
18
Converts a graph to DOT (Graphviz) syntax.
Works with any node data type and edge data type. Use the options to customize labels, styling, and to define subgraphs.
Time Complexity: O(V + E + S) where S is the total number of nodes across all subgraphs.
Example
graph =
Yog.directed()
|> Yog.add_node(1, "Start")
|> Yog.add_node(2, "Process")
|> Yog.add_edge_ensure(from: 1, to: 2, with: "5")
diagram = Yog.Render.DOT.to_dot(graph, Yog.Render.DOT.default_options())