yog_io/json
JSON format for graph data exchange.
This module provides comprehensive JSON I/O capabilities for graph data, supporting multiple formats used by popular visualization libraries.
Features
- Generic types for nodes and edges
- Reading and Writing support for Generic format
- Multiple JSON export formats (D3.js, Cytoscape.js, vis.js, etc.)
- File operations (read/write JSON files directly)
- Rich metadata support (graph properties, rendering hints)
- Format validation and error reporting
Quick Start
import yog_io/json
import yog/model
pub fn main() {
let graph =
model.new(model.Directed)
|> model.add_node(1, "Alice")
|> model.add_node(2, "Bob")
|> model.add_edge(from: 1, to: 2, with: "follows")
// Export to file (simple)
let assert Ok(_) = json.write("graph.json", graph)
// Or with custom options
let assert Ok(_) = json.to_json_file(
graph,
"graph.json",
json.default_export_options(),
)
}
Format Support
- Generic: Full metadata with type preservation
- D3Force: D3.js force-directed graphs
- Cytoscape: Cytoscape.js network visualization
- VisJs: vis.js network format
- NetworkX: Python NetworkX compatibility
References
Types
Errors that can occur during JSON operations
pub type JsonError {
FileNotFound(path: String)
InvalidJson(error: String)
WriteError(path: String, error: String)
ReadError(path: String, error: String)
UnsupportedFormat(format: String)
}
Constructors
-
FileNotFound(path: String)File not found
-
InvalidJson(error: String)Invalid JSON syntax
-
WriteError(path: String, error: String)File write error
-
ReadError(path: String, error: String)File read error
-
UnsupportedFormat(format: String)Unsupported format
Options for JSON export
pub type JsonExportOptions(n, e) {
JsonExportOptions(
format: JsonFormat,
include_metadata: Bool,
node_serializer: option.Option(fn(n) -> json.Json),
edge_serializer: option.Option(fn(e) -> json.Json),
pretty: Bool,
metadata: option.Option(dict.Dict(String, json.Json)),
)
}
Constructors
-
JsonExportOptions( format: JsonFormat, include_metadata: Bool, node_serializer: option.Option(fn(n) -> json.Json), edge_serializer: option.Option(fn(e) -> json.Json), pretty: Bool, metadata: option.Option(dict.Dict(String, json.Json)), )Arguments
- format
-
Output format (default: Generic)
- include_metadata
-
Include graph metadata (default: True)
- node_serializer
-
Custom node data serializer
- edge_serializer
-
Custom edge data serializer
- pretty
-
Pretty print output (default: True)
- metadata
-
Custom metadata fields
Format presets for popular graph visualization libraries
pub type JsonFormat {
Generic
D3Force
Cytoscape
VisJs
NetworkX
}
Constructors
-
GenericGeneric format with full metadata
-
D3ForceD3.js force-directed graph format
-
CytoscapeCytoscape.js elements format
-
VisJsvis.js network format
-
NetworkXNetworkX node-link format (Python compatibility)
Values
pub fn default_export_options() -> JsonExportOptions(
String,
String,
)
Creates default export options for String node and edge data.
Default Settings
- Format: Generic
- Include metadata: True
- Pretty print: True
- Node serializer: Converts strings to JSON strings
- Edge serializer: Converts strings to JSON strings
Example
let options = json.default_export_options()
json.to_json(graph, options)
pub fn error_to_string(error: JsonError) -> String
Converts a JsonError to a human-readable string.
Example
case json.to_json_file(graph, "output.json", options) {
Ok(_) -> "Success!"
Error(e) -> json.error_to_string(e)
}
pub fn export_options_with(
node_serializer: fn(n) -> json.Json,
edge_serializer: fn(e) -> json.Json,
) -> JsonExportOptions(n, e)
Creates export options with custom serializers for generic types.
Use this when your graph contains custom data types that need special conversion to JSON.
Example
pub type Person {
Person(name: String, age: Int)
}
let options = json.export_options_with(
node_serializer: fn(person) {
json.object([
#("name", json.string(person.name)),
#("age", json.int(person.age)),
])
},
edge_serializer: fn(weight) { json.int(weight) },
)
pub fn from_json(
json_string: String,
) -> Result(model.Graph(String, String), JsonError)
Parses a graph from a JSON string representation.
pub fn from_json_multi(
json_string: String,
) -> Result(model.MultiGraph(String, String), JsonError)
Parses a multigraph from a JSON string representation.
pub fn from_json_multi_with(
json_string: String,
node_data_decoder: decode.Decoder(n),
edge_data_decoder: decode.Decoder(e),
) -> Result(model.MultiGraph(n, e), JsonError)
Parses a multigraph from a JSON string with custom data decoders.
This function supports the standard yog-generic JSON format.
pub fn from_json_with(
json_string: String,
node_data_decoder: decode.Decoder(n),
edge_data_decoder: decode.Decoder(e),
) -> Result(model.Graph(n, e), JsonError)
Parses a graph from a JSON string with custom data decoders.
This function supports the standard yog-generic JSON format.
pub fn read(
path: String,
) -> Result(model.Graph(String, String), JsonError)
Reads a graph from a JSON file using default options.
This currently supports only the Generic format (yog-generic).
pub fn read_multi(
path: String,
) -> Result(model.MultiGraph(String, String), JsonError)
Reads a multigraph from a JSON file using default options.
pub fn read_multi_with(
path: String,
node_decoder: decode.Decoder(n),
edge_decoder: decode.Decoder(e),
) -> Result(model.MultiGraph(n, e), JsonError)
Reads a multigraph from a JSON file with custom data decoders.
pub fn read_with(
path: String,
node_decoder: decode.Decoder(n),
edge_decoder: decode.Decoder(e),
) -> Result(model.Graph(n, e), JsonError)
Reads a graph from a JSON file with custom data decoders.
pub fn to_cytoscape_json(
graph: model.Graph(n, e),
node_serializer: fn(n) -> json.Json,
edge_serializer: fn(e) -> json.Json,
) -> String
Quick export for Cytoscape.js with default settings.
pub fn to_d3_json(
graph: model.Graph(n, e),
node_serializer: fn(n) -> json.Json,
edge_serializer: fn(e) -> json.Json,
) -> String
Quick export for D3.js force-directed graphs with default settings.
This is a convenience function that exports graphs in D3.js format with sensible defaults.
Example
let d3_json = json.to_d3_json(graph, json.string, json.string)
pub fn to_json(
graph: model.Graph(n, e),
options: JsonExportOptions(n, e),
) -> String
Converts a graph to a JSON string.
This function serializes a graph to JSON format according to the specified options and format preset.
Time Complexity: O(V + E)
Example
import yog/model
import yog_io/json
pub fn main() {
let graph =
model.new(model.Directed)
|> model.add_node(1, "Alice")
|> model.add_node(2, "Bob")
|> model.add_edge(from: 1, to: 2, with: "follows")
let json_string = json.to_json(graph, json.default_export_options())
// Returns JSON string representation
}
pub fn to_json_file(
graph: model.Graph(n, e),
path: String,
options: JsonExportOptions(n, e),
) -> Result(Nil, JsonError)
Exports a graph to a JSON file.
This function writes the graph to a file in the specified JSON format. The file will be created if it doesn’t exist, or overwritten if it does.
Example
case json.to_json_file(graph, "output.json", json.default_export_options()) {
Ok(_) -> io.println("Graph saved successfully")
Error(json.WriteError(path, error)) -> {
io.println("Failed to write to " <> path <> ": " <> error)
}
Error(_) -> io.println("Unknown error")
}
pub fn to_json_file_multi(
graph: model.MultiGraph(n, e),
path: String,
options: JsonExportOptions(n, e),
) -> Result(Nil, JsonError)
Exports a multigraph to a JSON file.
This function writes the multigraph to a file in the specified JSON format. The file will be created if it doesn’t exist, or overwritten if it does.
Example
case json.to_json_file_multi(graph, "output.json", json.default_export_options()) {
Ok(_) -> io.println("Multigraph saved successfully")
Error(json.WriteError(path, error)) -> {
io.println("Failed to write to " <> path <> ": " <> error)
}
Error(_) -> io.println("Unknown error")
}
pub fn to_json_multi(
graph: model.MultiGraph(n, e),
options: JsonExportOptions(n, e),
) -> String
Converts a multigraph to a JSON string.
This function serializes a multigraph to JSON format with edge IDs to preserve parallel edges. All formats include unique edge identifiers.
Time Complexity: O(V + E)
Example
import yog/multi/model as multi
import yog_io/json
pub fn main() {
let graph =
multi.new(multi.Directed)
|> multi.add_node(1, "Alice")
|> multi.add_node(2, "Bob")
|> multi.add_edge(from: 1, to: 2, with: "follows")
|> multi.add_edge(from: 1, to: 2, with: "mentions")
let json_string = json.to_json_multi(graph, json.default_export_options())
// Returns JSON with edge IDs for parallel edges
}
pub fn to_visjs_json(
graph: model.Graph(n, e),
node_serializer: fn(n) -> json.Json,
edge_serializer: fn(e) -> json.Json,
) -> String
Quick export for vis.js networks with default settings.
pub fn write(
path: String,
graph: model.Graph(String, String),
) -> Result(Nil, JsonError)
Writes a graph to a JSON file using default export options.
This is a convenience function for String-based graphs that uses default
JSON export options. For more control over the output format, use
to_json_file() or write_with().
Example
import yog/model
import yog_io/json
let graph =
model.new(model.Directed)
|> model.add_node(1, "Alice")
|> model.add_node(2, "Bob")
|> model.add_edge(from: 1, to: 2, with: "follows")
let assert Ok(Nil) = json.write("graph.json", graph)
pub fn write_with(
path: String,
options: JsonExportOptions(n, e),
graph: model.Graph(n, e),
) -> Result(Nil, JsonError)
Writes a graph to a JSON file with custom export options.
This function provides full control over the JSON export format and serialization behavior.
Example
import gleam/json as gleam_json
import yog_io/json
pub type Person {
Person(name: String, age: Int)
}
let options = json.export_options_with(
node_serializer: fn(person) {
gleam_json.object([
#("name", gleam_json.string(person.name)),
#("age", gleam_json.int(person.age)),
])
},
edge_serializer: fn(weight) { gleam_json.int(weight) },
)
let assert Ok(Nil) = json.write_with("graph.json", options, graph)