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
Migration Note: Enhanced in v0.53.0 with full Gleam parity: subgraphs, per-element attributes, layout engines, advanced styling options.
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 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.
Converts a shortest path result to highlighted 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 | :circle | :ellipse | :diamond | :hexagon | :pentagon | :octagon | :triangle | :rectangle | :square | :rect | :invtriangle | :house | :invhouse | :parallelogram | :trapezoid | {: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, 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()], style: style() | nil, fillcolor: String.t() | nil, color: String.t() | 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.
Functions
@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)
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
{:some, path} ->
options = Yog.Render.DOT.path_to_options(path, Yog.Render.DOT.default_options())
dot_string = Yog.Render.DOT.to_dot(graph, options)
:none ->
""
end
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!(from: 1, to: 2, with: "5")
diagram = Yog.Render.DOT.to_dot(graph, Yog.Render.DOT.default_options())