# s3Dgraphy/utils/visual_layout.py
"""
Module for generating visual layouts for s3Dgraphy graphs using NetworkX.
This module provides functionality to generate hierarchical X, Y coordinates for nodes
within a graph using NetworkX.
"""
# Import NetworkX only if available
try:
import networkx as nx
except ImportError:
nx = None # Handle NetworkX unavailability gracefully
from ..graph import Graph, Node
[docs]
def generate_layout(graph: Graph):
"""
Generates X, Y coordinates for nodes in a graph based on a hierarchical layout.
:param graph: An instance of the Graph class containing nodes and edges.
:return: A dictionary with node IDs as keys and (x, y) tuples as values representing node coordinates.
:raises ImportError: If NetworkX is not installed.
"""
if nx is None:
raise ImportError("NetworkX library is required for layout generation but is not installed.")
# Initialize a NetworkX directed graph
G = nx.DiGraph()
# Add nodes to the NetworkX graph
for node in graph.nodes:
G.add_node(node.node_id)
# Add edges to the NetworkX graph
for edge in graph.edges:
G.add_edge(edge.edge_source, edge.edge_target)
# Generate layout using a spring layout or graphviz-based layout
pos = nx.spring_layout(G) # Alternative layout can be used based on requirements
# Create dictionary for node positions
node_positions = {node_id: (x, y) for node_id, (x, y) in pos.items()}
return node_positions
if __name__ == "__main__":
# Example usage
# Create a sample graph
example_graph = Graph("example")
example_graph.add_node(Node("1", "Node 1", "type1"))
example_graph.add_node(Node("2", "Node 2", "type2"))
example_graph.add_node(Node("3", "Node 3", "type3"))
example_graph.add_edge("e1", "1", "2", "is_connected_to")
example_graph.add_edge("e2", "2", "3", "is_connected_to")
# Generate layout
layout = generate_layout(example_graph)
# Print node positions
for node_id, coordinates in layout.items():
pass
# print(f"Node {node_id}: {coordinates}")