Skip to main content

livebooks/how_to/import_export.livemd

# How-To: Importing & Exporting Graphs

```elixir
Mix.install([
  {:yog_ex, path: "/home/mafinar/repos/elixir/yog_ex"},
  {:jason, "~> 1.4"} # Needed for JSON
])
```

## Introduction

`Yog` is designed to be a "good citizen" in the data ecosystem. It supports several industry-standard formats for importing and exporting graphs, ensuring that you can easily integrate `Yog` with other tools like Gephi, Cytoscape, or NetworkX.

## 📁 GraphML (The Standard)

GraphML is an XML-based format that is the de-facto standard for graph interchange.

```elixir
g = Yog.Generator.Classic.petersen()

# 1. Export to GraphML string
{:ok, xml} = Yog.IO.GraphML.serialize(g)
IO.puts String.slice(xml, 0, 200) <> "..."

# 2. Import from GraphML string
{:ok, imported_g} = Yog.IO.GraphML.deserialize(xml)
IO.puts("Imported graph has #{Yog.node_count(imported_g)} nodes and #{Yog.edge_count(imported_g)} edges")
```

## 📄 JSON (For Web & Data)

JSON is perfect for passing graph data to frontend libraries like Cytoscape.js or D3.js.

```elixir
g = Yog.undirected()
  |> Yog.add_node(1, %{name: "Alice"})
  |> Yog.add_node(2, %{name: "Bob"})
  |> Yog.add_edge!(1, 2, %{type: "friend"})

# 1. Export to JSON (uses Jason internally)
{:ok, json} = Yog.IO.JSON.serialize(g)
IO.puts json

# 2. Import from JSON
{:ok, imported_g} = Yog.IO.JSON.deserialize(json)
IO.puts("Imported: #{Yog.node_count(imported_g)} nodes")
```

## 🗃️ GDF (GUESS Format)

GDF is a simple CSV-like format used by the GUESS visualization tool and Gephi.

```elixir
g = Yog.Generator.Classic.cycle(5)

# Export to GDF
gdf = Yog.IO.GDF.serialize(g)
IO.puts gdf

# Import from GDF
{:ok, imported} = Yog.IO.GDF.deserialize(gdf)
IO.puts("Imported: #{Yog.node_count(imported)} nodes, #{Yog.edge_count(imported)} edges")
```

## 🔢 Graph6 (Compact Encoding)

Graph6 is a compact text format for encoding small graphs. It's popular in mathematics and competitions.

```elixir
g = Yog.Generator.Classic.petersen()

# Export to graph6
{:ok, g6} = Yog.IO.Graph6.serialize(g)
IO.puts("Graph6: #{g6}")

# Import from graph6
{:ok, imported} = Yog.IO.Graph6.deserialize(g6)
IO.puts("Imported: #{Yog.node_count(imported)} nodes, #{Yog.edge_count(imported)} edges")

# Cycle graph C5
c5_g6 = Yog.IO.Graph6.encode_graph6(Yog.Generator.Classic.cycle(5))
IO.puts("C5 in graph6: #{c5_g6}")
```

## 🛠️ Interoperability with `libgraph`

If you are migrating from `libgraph` or need to use an algorithm only available there, `Yog` makes the transition seamless.

```elixir
# Create a libgraph graph
lg = Graph.new() |> Graph.add_edge(1, 2)

# Convert to Yog
yg = Yog.IO.Libgraph.from_libgraph(lg)
IO.puts("Yog graph: #{Yog.node_count(yg)} nodes")

# Convert back to libgraph
lg_back = Yog.IO.Libgraph.to_libgraph(yg)
IO.puts("Back to libgraph: #{length(Graph.vertices(lg_back))} vertices")
```

## 🖼️ DOT (For Visualization)

While DOT is primarily for visualization, it is also a valid interchange format.

```elixir
g = Yog.Generator.Classic.cycle(5)

dot = Yog.Render.DOT.to_dot(g)
IO.puts dot
```

## Summary

`Yog`'s I/O suite allows you to:
1.  **Collaborate**: Use **GraphML** to share data with researchers using other languages.
2.  **Build**: Use **JSON** to power interactive web visualizations.
3.  **Archive**: Use **Graph6** for compact, lossless graph encoding.
4.  **Migrate**: Use the **libgraph** bridge to leverage existing Elixir codebases.
5.  **Publish**: Use **DOT** to generate high-quality diagrams.

Next, explore the **Gallery** to see more exotic graph structures!