### SugiyamaLayout Initialization (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Shows the basic setup for SugiyamaLayout, a hierarchical placement algorithm for directed acyclic graphs. It requires a graph_core object where vertices have a '.view' interface. ```python # Assuming 'graph_core_object' is a valid graph_core instance # and vertices have a '.view' attribute with width and height. sug = SugiyamaLayout(graph_core_object) ``` -------------------------------- ### Python: Applying Sugiyama Layout with Grandalf Source: https://github.com/bdcht/grandalf/blob/master/doc/quickstart.rst This example demonstrates how to apply the Sugiyama layout algorithm to a Grandalf graph. It involves defining a view for vertices and then initializing and drawing the layout. ```python from grandalf.layouts import SugiyamaLayout class defaultview(object): w,h = 10,10 for v in V: v.view = defaultview() sug = SugiyamaLayout(g.C[0]) sug.init_all(roots=[V[0]],inverted_edges=[V[4].e_to(V[0])]) sug.draw() for v in g.C[0].sV: print("%s: (%d,%d)"%(v.data,v.view.xy[0],v.view.xy[1])) ``` -------------------------------- ### Running masr-graph with SugiyamaLayout and Constraints (Bash) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Runs the masr-graph tool with SugiyamaLayout, applying the '-ce' option to constrain inverted edges to start from the bottom of their initial vertex and end on the top of their terminal vertex. ```bash $ ./masr-graph tests/samples/manhattan1.dot -ce ``` -------------------------------- ### Python Set Operations with Poset Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates basic set operations like checking membership, getting size, adding, and removing elements using the Poset class. It also shows union, intersection, and difference operations between two Poset objects. ```python from grandalf.graphs import Poset p = Poset(['a', 'b', 'c', 'd']) print('b' in p) # True print(len(p)) # 4 p.add('e') p.remove('b') print(list(p)) # ['a', 'c', 'd', 'e'] p1 = Poset([1, 2, 3]) p2 = Poset([2, 3, 4]) union = p1 | p2 # {1, 2, 3, 4} intersection = p1 & p2 # {2, 3} difference = p1 - p2 # {1} print(f"Union: {list(union)}") print(f"Intersection: {list(intersection)}") print(f"Difference: {list(difference)}") ``` -------------------------------- ### DigcoLayout Initialization (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Illustrates the initialization of DigcoLayout, an alternative hierarchical placement algorithm based on optimization theory. It also requires a graph_core object with vertex views. ```python # Assuming 'graph_core_object' is a valid graph_core instance # and vertices have a '.view' attribute with width and height. digco = DigcoLayout(graph_core_object) ``` -------------------------------- ### Create and Manage Graph Components Source: https://github.com/bdcht/grandalf/blob/master/README.rst Demonstrates how to initialize a graph, create vertices and edges, and manage their inclusion in the graph structure. It highlights that vertices and edges must belong to only one graph at a time. ```python from grandalf.graphs import Graph, Vertex, Edge # Create an empty graph g = Graph() # Create vertices v1 = Vertex('a') v2 = Vertex('b') v3 = Vertex() v3.data = 'c' # Add vertices and edges to the graph g.add_vertex(v1) e1 = Edge(v1, v2) e2 = Edge(v1, v3, w=2) g.add_edge(e1) g.add_edge(e2) # Removing a vertex also removes associated edges g.remove_vertex(v1) ``` -------------------------------- ### Graph Initialization and Updates (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Demonstrates the initialization of the main Graph class, which handles potentially disconnected graphs by managing components as Disjoint Sets. It also shows methods for updating the graph. ```python >>> v4,v5 = Vertex(4),Vertex(5) >>> g = Graph([v1,v2,v3,v4],[e1,e2]) ``` -------------------------------- ### Create and Manage Graph Vertices Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates how to instantiate Vertex objects with arbitrary data and add them to a Graph. It shows how to access vertex properties like degree and component references. ```python from grandalf.graphs import Vertex, Edge, Graph # Create vertices with associated data v1 = Vertex('node_a') v2 = Vertex('node_b') v3 = Vertex({'id': 3, 'label': 'node_c'}) # Access vertex properties print(v1.data) print(v1.deg()) print(v1.c) # Create vertices and add to graph V = [Vertex(i) for i in range(5)] E = [Edge(V[0], V[1]), Edge(V[1], V[2]), Edge(V[2], V[3]), Edge(V[3], V[4])] g = Graph(V, E) # Now vertices have component reference print(V[0].c) print(V[0].deg()) print(V[1].deg()) ``` -------------------------------- ### Visualizing DigcoLayout Convergence Steps (Bash) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Runs masr-graph with DigcoLayout to visualize each step of the convergence process. Setting '-N 1' allows for step-by-step iteration, where pressing SPACE in the interactive viewer advances to the next iteration. ```bash $ masr-graph -digco -N 1 tests/samples/circle.dot ``` -------------------------------- ### DigcoLayout Initialization and Drawing (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Initializes and draws a graph using the DigcoLayout algorithm, which is a stress minimization approach with hierarchical constraints. The 'draw' method uses a conjugate-gradient method for convergence, with an optional 'limit' for maximum iterations. ```python >>> dco = DigcoLayout(gr) >>> dco.init_all() >>> dco.draw(limit=100) ``` -------------------------------- ### Manage Graph Structure and Components Source: https://context7.com/bdcht/grandalf/llms.txt Illustrates how to build a graph dynamically, check connectivity, and perform basic graph traversals or pathfinding using the Graph class. ```python from grandalf.graphs import Vertex, Edge, Graph # Create an empty graph g = Graph() # Add vertices and edges v1 = g.add_vertex(Vertex('A')) v2 = g.add_vertex(Vertex('B')) v3 = g.add_vertex(Vertex('C')) g.add_edge(Edge(v1, v2)) g.add_edge(Edge(v2, v3)) # Check graph properties print(g.order()) print(g.norm()) print(len(g.C)) print(g.connected()) # Find path between vertices V = [Vertex(i) for i in range(6)] E = [Edge(V[0], V[1]), Edge(V[1], V[2]), Edge(V[2], V[3]), Edge(V[1], V[4]), Edge(V[4], V[5]), Edge(V[5], V[3])] g = Graph(V, E) path = g.path(V[0], V[3]) print([v.data for v in path]) ``` -------------------------------- ### Configure Graph Layout and Edge Routing Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates how to initialize a graph, assign viewers to vertices and edges, and apply different routing strategies like line, spline, and rounded corner algorithms using the Sugiyama layout. ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout, VertexViewer from grandalf.routing import EdgeViewer, route_with_lines, route_with_splines, route_with_rounded_corners # Example setup for line routing V = [Vertex(i) for i in range(4)] E = [Edge(V[0], V[1]), Edge(V[0], V[2]), Edge(V[1], V[3]), Edge(V[2], V[3])] g = Graph(V, E) for v in V: v.view = VertexViewer(w=50, h=30) for e in E: e.view = EdgeViewer() sug = SugiyamaLayout(g.C[0]) sug.route_edge = route_with_lines sug.init_all() sug.draw() ``` -------------------------------- ### Vertex Initialization and Data Access (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Demonstrates the creation of a Vertex object and accessing its data attribute. A Vertex represents a node in the graph and holds associated data. ```python >>> v1 = Vertex('a') >>> v2 = Vertex('b') >>> v3 = Vertex('c') >>> v1.data 'a' ``` -------------------------------- ### Graph Core Initialization (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Illustrates the creation of a graph_core object, which is designed for connected graphs only. It takes lists of vertices and edges as input. ```python >>> g = graph_core([v1,v2,v3],[e1,e2]) ``` -------------------------------- ### Edge Creation with Optional Weights (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Shows how to create Edge objects, which connect two Vertex objects. Edges can optionally have a weight and associated data, with defaults provided. ```python >>> e1 = Edge(v1,v2) >>> e2 = Edge(v1,v3,w=2) ``` -------------------------------- ### Route with Lines Function (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Demonstrates how to assign the route_with_lines function to a layout instance to draw edges as polylines, adjusting waypoints and node boundary positions. ```python # Assuming 'sug' is a layout instance (e.g., SugiyamaLayout) sug.route_edge = route_with_lines ``` -------------------------------- ### Manage Partially Ordered Sets Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates the use of the Poset utility class to maintain insertion order while handling partially ordered set operations. ```python from grandalf.utils import Poset p = Poset(['a', 'b', 'c', 'd']) print(p[0]) # Access by index ``` -------------------------------- ### Route with Lines Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates creating a graph and applying Sugiyama layout with line routing for edges. ```APIDOC ## Route with Lines Routes edges using straight lines. ### Method ```python route_with_lines ``` ### Parameters This function does not take explicit parameters but operates on graph elements and their views. ### Request Example ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout, VertexViewer from grandalf.routing import EdgeViewer, route_with_lines V = [Vertex(i) for i in range(4)] E = [Edge(V[0], V[1]), Edge(V[0], V[2]), Edge(V[1], V[3]), Edge(V[2], V[3])] g = Graph(V, E) for v in V: v.view = VertexViewer(w=50, h=30) for e in E: e.view = EdgeViewer() sug = SugiyamaLayout(g.C[0]) sug.route_edge = route_with_lines # Set routing function sug.init_all() sug.draw() # Access edge paths for e in E: print(f"Edge {e.v[0].data}->{e.v[1].data}:") print(f" Path: {e.view._pts}") print(f" Head angle: {e.view.head_angle:.2f} radians") ``` ### Response Edge paths and head angles are printed to the console. ``` -------------------------------- ### Python Graph Layout with Grandalf SugiyamaLayout Source: https://context7.com/bdcht/grandalf/llms.txt Illustrates creating a control flow graph, configuring visual properties for nodes and edges, computing a hierarchical layout using SugiyamaLayout, and extracting node positions and edge paths. ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout, VertexViewer from grandalf.routing import EdgeViewer, route_with_splines # Define a control flow graph nodes = ['entry', 'cond', 'if_true', 'if_false', 'merge', 'exit'] edges_def = [ ('entry', 'cond'), ('cond', 'if_true'), ('cond', 'if_false'), ('if_true', 'merge'), ('if_false', 'merge'), ('merge', 'exit'), ] # Create grandalf structures V = {name: Vertex(name) for name in nodes} E = [Edge(V[src], V[dst]) for src, dst in edges_def] g = Graph(list(V.values()), E) # Configure views node_sizes = { 'entry': (60, 30), 'cond': (80, 40), 'if_true': (70, 35), 'if_false': (70, 35), 'merge': (60, 30), 'exit': (60, 30) } for name, v in V.items(): w, h = node_sizes.get(name, (50, 30)) v.view = VertexViewer(w=w, h=h) for e in E: e.view = EdgeViewer() # Layout configuration sug = SugiyamaLayout(g.C[0]) sug.xspace = 40 # Horizontal spacing sug.yspace = 50 # Vertical spacing sug.route_edge = route_with_splines # Compute layout sug.init_all(roots=[V['entry']]) sug.draw(N=4) # 4 iterations for crossing reduction # Extract results print("Node positions:") for name, v in V.items(): x, y = v.view.xy print(f" {name}: ({x:.1f}, {y:.1f})") print("\nEdge paths:") for e in E: src, dst = e.v[0].data, e.v[1].data points = e.view._pts print(f" {src} -> {dst}: {len(points)} points") if hasattr(e.view, 'splines'): print(f" Splines: {len(e.view.splines)} segments") print(f"\nLayout info:") print(f" Layers: {len(sug.layers)}") print(f" Layer sizes: {[len(l) for l in sug.layers]}") ``` -------------------------------- ### Drawing Edges with Routing (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Demonstrates how to draw graph edges using predefined routing functions from 'routing.py'. This involves defining a 'setpath' method or using utilities like 'route_with_lines' or 'route_with_splines' to determine edge paths. ```python # Example usage with setpath or routing functions would go here ``` -------------------------------- ### SugiyamaLayout Initialization and Drawing (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Initializes and performs one round of the SugiyamaLayout algorithm for graph drawing. This involves computing node positions layer by layer. It can also perform multiple drawing passes by specifying a number. ```python >>> sug = SugiyamaLayout(gr) >>> sug.init_all() >>> sug.draw() ``` ```python >>> sug.draw(3) ``` -------------------------------- ### Compute Strongly Connected Sets and Feedback Edges Source: https://github.com/bdcht/grandalf/blob/master/README.rst Demonstrates how to identify root nodes and compute the strongly connected sets with feedback edges for a graph component using the Tarjan algorithm implementation in Grandalf. ```python r = filter(lambda x: len(x.e_in())==0, gr.sV) if len(r)==0: r = [my_guessed_root_node] L = gr.get_scs_with_feedback(r) inverted_edges = filter(lambda x: x.feedback, gr.sE) ``` -------------------------------- ### Parse Graphviz DOT Files Source: https://context7.com/bdcht/grandalf/llms.txt Shows how to parse DOT format strings or files into an AST and convert them into Grandalf graph structures. Requires the PLY library. ```python from grandalf.utils import Dot from grandalf.graphs import Vertex, Edge, Graph dot_content = "digraph example { A -> B; A -> C; B -> D; C -> D; D -> E; }" parser = Dot() ast = parser.parse(dot_content.encode()) vertices = {name: Vertex(name) for name in ast[0].nodes} edges = [Edge(vertices[e.n1.name], vertices[e.n2.name]) for e in ast[0].edges] g = Graph(list(vertices.values()), edges) ``` -------------------------------- ### Route with Splines Function (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Shows how to use route_with_splines for drawing edges with rounded corners using Bezier curves, offering a smoother visual appearance compared to straight lines. ```python # Assuming 'sug' is a layout instance (e.g., SugiyamaLayout) sug.route_edge = route_with_splines ``` -------------------------------- ### Python: Graph Creation and Manipulation with Grandalf Source: https://github.com/bdcht/grandalf/blob/master/doc/quickstart.rst This snippet shows how to create a graph, add vertices and edges, find paths, and remove elements. It utilizes the core classes from the grandalf.graphs module. ```python from grandalf.graphs import Vertex, Edge, Graph V = [Vertex(data) for data in range(10)] X = [(0,1),(0,2),(1,3),(2,3),(4,0),(1,4),(4,5),(5,6),(3,6),(3,7),(6,8),(7,8),(8,9),(5,9)] E = [Edge(V[v],V[w]) for (v,w) in X] g = Graph(V,E) print([v.data for v in g.path(V[1],V[9])]) g.add_edge(Edge(V[9],Vertex(10))) g.remove_edge(V[5].e_to(V[9])) print([v.data for v in g.path(V[1],V[9])]) g.remove_vertex(V[8]) for e in g.C[1].E(): print("%s->%s"%(e.v[0].data,e.v[1].data)) ``` -------------------------------- ### Running masr-graph with SugiyamaLayout (Bash) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Executes the masr-graph command-line tool to draw a graph using the SugiyamaLayout algorithm. This is a convenient way to process graph files like DOT format from the terminal. ```bash $ cd /path/to/grandalf $ ./masr-graph tests/samples/brandes.dot ``` -------------------------------- ### Running masr-graph with DigcoLayout (Bash) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Executes the masr-graph tool with the DigcoLayout algorithm. The '-digco' flag specifies the layout, '-N' sets the number of iterations, and a DOT file is provided as input. ```bash $ masr-graph -digco -N 25 tests/samples/circle.dot ``` -------------------------------- ### SugiyamaLayout Step-by-Step Drawing (Python) Source: https://github.com/bdcht/grandalf/blob/master/README.rst Provides an iterator for drawing the graph step-by-step with SugiyamaLayout. This allows visualization of the algorithm's progress at each layer during forward and backward passes, useful for understanding edge crossing reduction. ```python >>> sug.draw_step() ``` -------------------------------- ### Define and Query Graph Edges Source: https://context7.com/bdcht/grandalf/llms.txt Shows how to create directed edges between vertices, optionally including weights and metadata. It also demonstrates how to query incoming and outgoing edges from specific vertices. ```python from grandalf.graphs import Vertex, Edge, Graph # Create vertices v1 = Vertex('A') v2 = Vertex('B') v3 = Vertex('C') # Create edges - direction is v[0] -> v[1] e1 = Edge(v1, v2) e2 = Edge(v2, v3, w=5) e3 = Edge(v1, v3, w=2, data={'label': 'shortcut'}) # Access edge properties print(e1.v) print(e2.w) print(e3.data) # Build graph and query edges g = Graph([v1, v2, v3], [e1, e2, e3]) # Find edges from a vertex print(v1.e_out()) print(v2.e_in()) # Find edge between specific vertices edge = v1.e_to(v2) print(edge) ``` -------------------------------- ### DigcoLayout Class Source: https://github.com/bdcht/grandalf/blob/master/README.rst Performs 2D hierarchical placement using optimization theory for energy minimization. ```APIDOC ## DigcoLayout Class ### Description This class implements a 2D hierarchical layout algorithm based on optimization theory. It minimizes an energy function to determine node coordinates, allowing for flexible placement constraints. It requires a graph where vertices have a '.view' interface. ### Initialization To create a layout, provide: - A `graph_core` object with vertices equipped with a '.view' interface (width, height). ### Usage ```python >>> from your_module import DigcoLayout >>> # Assuming 'g' is a graph_core with nodes having '.view' >>> digco = DigcoLayout(g) >>> digco.init_all() >>> digco.draw() ``` ``` -------------------------------- ### Sugiyama Layout Calculation in Python Source: https://github.com/bdcht/grandalf/blob/master/README.rst Illustrates the use of the SugiyamaLayout class from Grandalf to compute node positions for a graph. It involves initializing the layout with the graph, setting up view objects for nodes, and then drawing the layout to obtain coordinates for nodes and edges. ```python from grandalf.layouts import SugiyamaLayout class defaultview(object): w,h = 10,10 for v in V: v.view = defaultview() sug = SugiyamaLayout(g.C[0]) sug.init_all(roots=[V[0]],inverted_edges=[V[4].e_to(V[0])]) sug.draw() for v in g.C[0].sV: print("%s: (%d,%d)"%(v.data,v.view.xy[0],v.view.xy[1])) for l in sug.layers: for n in l: print(n.view.xy,end='') print('') for e,d in sug.ctrls.items(): print('long edge %s --> %s points:'%(e.v[0].data,e.v[1].data)) for r,v in d.items(): print("%s %s %s"%(v.view.xy,'at rank',r)) ``` -------------------------------- ### Analyze Connected Components with graph_core Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates accessing the graph_core object to perform deeper analysis on a specific connected component of a graph. ```python from grandalf.graphs import Vertex, Edge, Graph, graph_core # Create vertices and edges for a connected graph V = [Vertex(i) for i in range(5)] E = [Edge(V[0], V[1], w=1), Edge(V[1], V[2], w=2), Edge(V[0], V[3], w=4), Edge(V[3], V[4], w=1), Edge(V[4], V[2], w=1)] g = Graph(V, E) # Access the connected component core = g.C[0] ``` -------------------------------- ### SugiyamaLayout Class Source: https://github.com/bdcht/grandalf/blob/master/README.rst Performs 2D hierarchical placement for directed acyclic graphs (DAGs). ```APIDOC ## SugiyamaLayout Class ### Description This class implements a 2D hierarchical layout algorithm suitable for directed acyclic graphs (DAGs). It requires a graph where vertices have a '.view' interface providing dimensions. The algorithm aims to minimize edge crossings through node reordering. ### Initialization To create a layout, provide: - A `graph_core` object with vertices equipped with a '.view' interface (width, height). Optional parameters for `init_all`: - `root_nodes`: List of starting nodes. - `feedback_acyclic_edges`: Edges to ensure acyclicity. - `constraint`: Parameter for routing inverted edges. ### Usage ```python >>> from your_module import SugiyamaLayout >>> # Assuming 'g' is a graph_core with nodes having '.view' >>> sug = SugiyamaLayout(g) >>> sug.init_all() >>> # To improve layout, increase N for more reordering rounds >>> sug.draw(N=10) >>> # For step-by-step visualization >>> sug.draw_step() ``` ### Configuration - `route_edge`: Can be set to `route_with_lines` or `route_with_splines` for edge routing. ``` -------------------------------- ### Route with Rounded Corners Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates an alternative routing method that generates smooth paths by progressively rounding corners. ```APIDOC ## route_with_rounded_corners - Custom Rounded Routing An alternative routing method that generates smooth paths by progressively rounding corners. ### Method ```python route_with_rounded_corners ``` ### Parameters This function does not take explicit parameters but operates on graph elements and their views. ### Request Example ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout, VertexViewer from grandalf.routing import EdgeViewer, route_with_rounded_corners V = [Vertex(i) for i in range(4)] E = [Edge(V[0], V[1]), Edge(V[1], V[2]), Edge(V[2], V[3]), Edge(V[0], V[3])] g = Graph(V, E) for v in V: v.view = VertexViewer(w=40, h=30) for e in E: e.view = EdgeViewer() sug = SugiyamaLayout(g.C[0]) sug.route_edge = route_with_rounded_corners sug.init_all() sug.draw() # Edges now have smoothed paths for e in E: print(f"Edge {e.v[0].data}->{e.v[1].data}: {len(e.view._pts)} points") ``` ### Response Prints the number of points in the smoothed path for each edge. ``` -------------------------------- ### Route Edges with Straight Lines Source: https://context7.com/bdcht/grandalf/llms.txt Demonstrates routing edges as straight polylines between vertices. This method adjusts edge endpoints to align with the boundaries of the connected vertices. ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout, VertexViewer from grandalf.routing import EdgeViewer, route_with_lines ``` -------------------------------- ### Route with Splines Source: https://context7.com/bdcht/grandalf/llms.txt Illustrates using Sugiyama layout with spline routing for curved edge visualization, suitable for graphs with long edges. ```APIDOC ## Route with Splines - Curved Edge Routing Routes edges with rounded corners using Bezier curves for smoother visualization. ### Method ```python route_with_splines ``` ### Parameters This function does not take explicit parameters but operates on graph elements and their views. ### Request Example ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout, VertexViewer from grandalf.routing import EdgeViewer, route_with_splines # Create a graph with long edges (spanning multiple layers) V = [Vertex(i) for i in range(5)] E = [Edge(V[0], V[1]), Edge(V[1], V[2]), Edge(V[2], V[3]), Edge(V[3], V[4]), Edge(V[0], V[4])] # Long edge from 0 to 4 g = Graph(V, E) for v in V: v.view = VertexViewer(w=40, h=25) for e in E: e.view = EdgeViewer() # Layout with spline routing sug = SugiyamaLayout(g.C[0]) sug.route_edge = route_with_splines sug.init_all() sug.draw() # Access spline data for e in E: if hasattr(e.view, 'splines'): print(f"Edge {e.v[0].data}->{e.v[1].data} splines:") for spline in e.view.splines: if len(spline) == 2: print(f" Line: {spline}") else: print(f" Bezier: {spline}") # 4 control points ``` ### Response Spline data (lines or Bezier curves) for each edge is printed to the console. ``` -------------------------------- ### DigcoLayout Force-Directed Layout Source: https://context7.com/bdcht/grandalf/llms.txt Implements a force-directed layout using stress majorization, suitable for general graph visualization. This algorithm requires the numpy library for matrix operations and vertices need view objects. ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import DigcoLayout # Create a graph V = [Vertex(i) for i in range(6)] E = [ Edge(V[0], V[1]), Edge(V[0], V[2]), Edge(V[1], V[3]), Edge(V[2], V[3]), Edge(V[3], V[4]), Edge(V[4], V[5]), Edge(V[2], V[5]), ] g = Graph(V, E) # Add views to vertices class NodeView: def __init__(self, w=30, h=30): self.w = w self.h = h self.xy = (0, 0) for v in V: v.view = NodeView() # Create and run the force-directed layout # Requires numpy for matrix operations try: dco = DigcoLayout(g.C[0]) dco.init_all() # Initialize positions dco.draw(N=100) # Run optimization for 100 iterations # Get computed coordinates for v in g.C[0].sV: print(f"Node {v.data}: ({v.view.xy[0]:.1f}, {v.view.xy[1]:.1f})") except ImportError: print("DigcoLayout requires numpy") ``` -------------------------------- ### Graph Metrics Calculation Source: https://context7.com/bdcht/grandalf/llms.txt Calculates and prints various graph metrics such as vertex count, edge count, minimum, maximum, and average degrees. It also demonstrates finding root and leaf vertices and performing Dijkstra's shortest path algorithm. ```python print(core.order()) # 5 - vertex count print(core.norm()) # 5 - edge count print(core.deg_min()) # 1 - minimum degree print(core.deg_max()) # 3 - maximum degree print(core.deg_avg()) # 2.0 - average degree # Find roots and leaves print([v.data for v in core.roots()]) # [0] - vertices with no incoming edges print([v.data for v in core.leaves()]) # [2] - vertices with no outgoing edges # Dijkstra's shortest weighted paths from V[0] distances = core.dijkstra(V[0]) for v in core.sV: print(f"Distance to {v.data}: {distances[v]}") # Distance to 0: 0.0 # Distance to 1: 1.0 # Distance to 2: 3.0 # Distance to 3: 4.0 # Distance to 4: 5.0 ``` -------------------------------- ### Integrate with NetworkX Source: https://context7.com/bdcht/grandalf/llms.txt Provides utility functions to convert graphs between Grandalf and NetworkX formats, facilitating interoperability between the two libraries. ```python import networkx as nx from grandalf.utils import convert_grandalf_graph_to_networkx_graph, convert_nextworkx_graph_to_grandalf # Grandalf to NetworkX nx_graph = convert_grandalf_graph_to_networkx_graph(grandalf_graph) # NetworkX to Grandalf nx_g = nx.DiGraph() nx_g.add_edges_from([('X', 'Y'), ('Y', 'Z')]) grandalf_g = convert_nextworkx_graph_to_grandalf(nx_g) ``` -------------------------------- ### DigcoLayout API Source: https://context7.com/bdcht/grandalf/llms.txt Force-directed layout algorithm using stress majorization for general graph visualization. ```APIDOC ## POST /layout/digco ### Description Applies a force-directed layout to a graph component using stress majorization. ### Method POST ### Endpoint /layout/digco ### Request Body - **graph** (object) - The graph structure - **iterations** (int) - Optimization iterations ### Response #### Success Response (200) - **coordinates** (list) - Optimized (x, y) positions for all vertices ``` -------------------------------- ### Identify Root Nodes for SugiyamaLayout Source: https://github.com/bdcht/grandalf/blob/master/README.rst Shows the standard approach to identifying root nodes in a graph component, defined as vertices with no incoming edges. ```python gr = g.C[0] r = filter(lambda x: len(x.e_in())==0, gr.sV) ``` -------------------------------- ### Sugiyama Layout API Source: https://github.com/bdcht/grandalf/blob/master/doc/quickstart.rst API for applying Sugiyama layout algorithms to graph components for visualization. ```APIDOC ## POST /layout/sugiyama ### Description Initializes and executes a Sugiyama layout calculation on a graph component. ### Method POST ### Endpoint /layout/sugiyama ### Parameters #### Request Body - **component** (graph_core) - Required - The graph component to layout. - **roots** (list) - Optional - List of root vertices. - **inverted_edges** (list) - Optional - List of edges to invert during layout. ### Response #### Success Response (200) - **status** (string) - Confirmation of layout execution. ``` -------------------------------- ### Poset - Ordered Set Collection Source: https://context7.com/bdcht/grandalf/llms.txt A utility class representing a partially ordered set that maintains insertion order while supporting set operations. ```APIDOC ## Poset - Ordered Set Collection A partially ordered set that maintains insertion order while providing set operations. ### Method ```python Poset(items) ``` ### Parameters - `items` (list): An iterable of items to initialize the Poset with. ### Request Example ```python from grandalf.utils import Poset # Create a Poset items = ['a', 'b', 'c', 'd'] p = Poset(items) # Access by index (preserves order) print(p[0]) # 'a' print(p[2]) # 'c' ``` ### Response Allows access to elements by their insertion order index. ``` -------------------------------- ### Dot Parser Source: https://context7.com/bdcht/grandalf/llms.txt Utility to parse graphviz dot format files into grandalf graph objects. ```APIDOC ## Dot Parser - Import Graphviz Files Parse graphviz dot format files to create grandalf graphs. ### Method ```python Dot().parse() ``` ### Parameters - `dot_content` (str): A string containing the graph definition in dot format. ### Request Example ```python from grandalf.utils import Dot from grandalf.graphs import Vertex, Edge, Graph # Parse a dot file dot_content = """ digraph example { A -> B; A -> C; B -> D; C -> D; D -> E; } """ # Parse the dot string parser = Dot() # Note: requires PLY library (pip install ply) try: ast = parser.parse(dot_content.encode()) if ast: graph_ast = ast[0] print(f"Graph name: {graph_ast.name}") print(f"Nodes: {list(graph_ast.nodes.keys())}") print(f"Edges: {[(e.n1.name, e.n2.name) for e in graph_ast.edges]}") # Convert to grandalf Graph vertices = {name: Vertex(name) for name in graph_ast.nodes} edges = [Edge(vertices[e.n1.name], vertices[e.n2.name]) for e in graph_ast.edges] g = Graph(list(vertices.values()), edges) print(f"Created graph with {g.order()} vertices and {g.norm()} edges") except Exception as e: print(f"Parsing requires PLY library: {e}") # Parse from file # graphs = parser.read('graph.dot') ``` ### Response Prints the parsed graph's name, nodes, edges, and the created grandalf graph's vertex and edge counts. An error message is printed if the PLY library is not installed. ``` -------------------------------- ### VertexViewer Default View Implementation Source: https://context7.com/bdcht/grandalf/llms.txt Provides a default implementation for vertex views, including attributes for width, height, and position. This class can be used to assign basic view properties to graph vertices. ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout, VertexViewer # Create graph V = [Vertex(f"node_{i}") for i in range(4)] E = [Edge(V[0], V[1]), Edge(V[0], V[2]), Edge(V[1], V[3]), Edge(V[2], V[3])] g = Graph(V, E) # Use VertexViewer for all vertices for v in V: v.view = VertexViewer(w=60, h=40) # Custom width and height # Run layout sug = SugiyamaLayout(g.C[0]) sug.init_all() sug.draw() # Access positions through view for v in V: print(f"{v.data}: {v.view}") # Shows xy, w, h ``` -------------------------------- ### SugiyamaLayout API Source: https://context7.com/bdcht/grandalf/llms.txt Hierarchical graph layout algorithm that organizes vertices into layers to minimize edge crossings. ```APIDOC ## POST /layout/sugiyama ### Description Applies the Sugiyama hierarchical layout algorithm to a graph component. ### Method POST ### Endpoint /layout/sugiyama ### Request Body - **graph** (object) - The graph structure - **iterations** (int) - Number of iterations for edge crossing reduction ### Response #### Success Response (200) - **coordinates** (list) - List of (x, y) coordinates for each vertex - **layers** (list) - Layer assignments for vertices ``` -------------------------------- ### NetworkX Integration Source: https://context7.com/bdcht/grandalf/llms.txt Provides functions to convert graphs between Grandalf and NetworkX formats. ```APIDOC ## NetworkX Integration Convert between grandalf and NetworkX graph formats. ### Methods - `convert_grandalf_graph_to_networkx_graph(grandalf_graph)` - `convert_nextworkx_graph_to_grandalf(networkx_graph)` ### Parameters - `grandalf_graph`: A Grandalf Graph object. - `networkx_graph`: A NetworkX graph object. ### Request Example ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.utils import ( convert_grandalf_graph_to_networkx_graph, convert_nextworkx_graph_to_grandalf ) # Create a grandalf graph V = [Vertex('A'), Vertex('B'), Vertex('C'), Vertex('D')] E = [Edge(V[0], V[1]), Edge(V[1], V[2]), Edge(V[2], V[3]), Edge(V[0], V[3])] grandalf_graph = Graph(V, E) # Convert to NetworkX (requires networkx library) try: import networkx as nx # Grandalf -> NetworkX nx_graph = convert_grandalf_graph_to_networkx_graph(grandalf_graph) print(f"NetworkX nodes: {list(nx_graph.nodes())}") print(f"NetworkX edges: {list(nx_graph.edges())}") # NetworkX -> Grandalf nx_g = nx.DiGraph() nx_g.add_edges_from([('X', 'Y'), ('Y', 'Z'), ('X', 'Z')]) grandalf_g = convert_nextworkx_graph_to_grandalf(nx_g) print(f"Grandalf vertices: {[v.data for v in grandalf_g.V()]}") except ImportError: print("NetworkX integration requires: pip install networkx") ``` ### Response Prints the nodes and edges of the converted NetworkX graph, and the data of vertices in the converted Grandalf graph. An error message is printed if the NetworkX library is not installed. ``` -------------------------------- ### Strongly Connected Components (SCC) Detection Source: https://context7.com/bdcht/grandalf/llms.txt Finds strongly connected components in a directed graph and identifies feedback edges that would need to be removed to make the graph acyclic. This is useful for cycle detection and analysis. ```python V = [Vertex(i) for i in range(4)] E = [Edge(V[0], V[1]), Edge(V[1], V[2]), Edge(V[2], V[0]), Edge(V[2], V[3])] g = Graph(V, E) scs = g.C[0].get_scs_with_feedback() print(f"Strongly connected components: {len(scs)}") # 2 # Feedback edges (edges to remove for acyclic graph) feedback = [e for e in g.C[0].sE if e.feedback] print(f"Feedback edges: {[(e.v[0].data, e.v[1].data) for e in feedback]}") ``` -------------------------------- ### Sugiyama Hierarchical Layout Algorithm Source: https://context7.com/bdcht/grandalf/llms.txt Implements the Sugiyama hierarchical layout algorithm for organizing vertices in layers to minimize edge crossings. It requires vertices to have a view object with width and height attributes. ```python from grandalf.graphs import Vertex, Edge, Graph from grandalf.layouts import SugiyamaLayout # Create a directed graph V = [Vertex(data) for data in ['start', 'A', 'B', 'C', 'D', 'end']] E = [ Edge(V[0], V[1]), # start -> A Edge(V[0], V[2]), # start -> B Edge(V[1], V[3]), # A -> C Edge(V[2], V[3]), # B -> C Edge(V[3], V[4]), # C -> D Edge(V[4], V[5]), # D -> end Edge(V[1], V[5]), # A -> end (long edge) ] g = Graph(V, E) # Each vertex needs a view with width and height class NodeView: def __init__(self, w=50, h=30): self.w = w self.h = h self.xy = (0, 0) for v in V: v.view = NodeView() # Create and run the layout sug = SugiyamaLayout(g.C[0]) sug.init_all() # Computes ranks and creates layers sug.draw(N=3) # Run 3 iterations for edge crossing reduction # Get computed coordinates for v in g.C[0].sV: print(f"{v.data}: x={v.view.xy[0]:.1f}, y={v.view.xy[1]:.1f}") # Access layer information print(f"Number of layers: {len(sug.layers)}") for i, layer in enumerate(sug.layers): nodes = [v.data for v in layer if hasattr(v, 'data')] print(f"Layer {i}: {nodes}") # Long edges have control points (dummy vertices) for e, ctrl in sug.ctrls.items(): print(f"Edge {e.v[0].data}->{e.v[1].data} has {len(ctrl)} control points") ``` -------------------------------- ### EdgeViewer Class Source: https://github.com/bdcht/grandalf/blob/master/README.rst Provides a default view for edges, required by layout algorithms. ```APIDOC ## EdgeViewer Class ### Description This class provides a default visual representation for edges. Edges without a view might be ignored by layout drawing methods. A provided view must have a `setpath` method to receive waypoints. ### Usage ```python >>> from your_module import Edge, EdgeViewer >>> # Assuming 'e' is an Edge object >>> edge_view = EdgeViewer(e) >>> # The layout algorithm will interact with edge_view.setpath() ``` ``` -------------------------------- ### graph_core Class Source: https://github.com/bdcht/grandalf/blob/master/README.rst Represents a connected component of a graph. Raises an exception if connectivity is lost upon modification. ```APIDOC ## graph_core Class ### Description A graph_core is designed to hold only connected graphs. If an operation would result in a disconnected graph, an exception is raised. This class is preferable when graph connectivity is a strict requirement. ### Usage ```python >>> from your_module import Vertex, Edge, graph_core >>> v1 = Vertex('a') >>> v2 = Vertex('b') >>> v3 = Vertex('c') >>> e1 = Edge(v1, v2) >>> e2 = Edge(v1, v3) >>> g = graph_core([v1, v2, v3], [e1, e2]) ``` ### Methods - `add_edge(e)`: Adds an edge to the graph. May add a new vertex if it's not already present. - `remove_edge(e)`: Removes an edge from the graph. - `remove_vertex(v)`: Removes a vertex and its associated edges from the graph. ``` -------------------------------- ### Graph Class Source: https://github.com/bdcht/grandalf/blob/master/README.rst The main class for managing graphs, internally using Disjoint Sets to handle potentially multiple connected components. ```APIDOC ## Graph Class ### Description The primary class for graph manipulation. It manages a collection of graph_core components, representing potentially disconnected graphs. Operations can merge or split these components. ### Usage ```python >>> from your_module import Vertex, Edge, Graph >>> v1, v2, v3, v4, v5 = Vertex(1), Vertex(2), Vertex(3), Vertex(4), Vertex(5) >>> e1 = Edge(v1, v2) >>> g = Graph([v1, v2, v3, v4], [e1]) ``` ### Methods - `add_vertex(v)`: Adds a vertex to the graph. - `add_edge(e)`: Adds an edge to the graph. - `remove_vertex(v)`: Removes a vertex from the graph. - `remove_edge(e)`: Removes an edge from the graph. ``` -------------------------------- ### Graph Metrics and Analysis Source: https://context7.com/bdcht/grandalf/llms.txt Endpoints for calculating graph properties such as order, norm, degree statistics, and identifying graph structure components. ```APIDOC ## GET /graph/metrics ### Description Calculates various metrics for a given graph instance, including vertex count, edge count, and degree statistics. ### Method GET ### Endpoint /graph/metrics ### Response #### Success Response (200) - **order** (int) - Total number of vertices - **norm** (int) - Total number of edges - **deg_min** (int) - Minimum vertex degree - **deg_max** (int) - Maximum vertex degree - **deg_avg** (float) - Average vertex degree ``` -------------------------------- ### route_with_splines Function Source: https://github.com/bdcht/grandalf/blob/master/README.rst Routes edges using a combination of lines and Bezier curves for rounded corners. ```APIDOC ## route_with_splines Function ### Description This function draws edges using a mix of straight lines and Bezier curves. It rounds the corners of polyline edges, providing a smoother visual appearance compared to sharp corners. ### Usage To use this routing method, assign it to the `route_edge` attribute of a layout instance: ```python >>> from your_module import SugiyamaLayout, route_with_splines >>> # Assuming 'sug' is a SugiyamaLayout instance >>> sug.route_edge = route_with_splines ``` ``` -------------------------------- ### route_with_lines Function Source: https://github.com/bdcht/grandalf/blob/master/README.rst Routes edges as polylines, adjusting endpoints and head angles. ```APIDOC ## route_with_lines Function ### Description This function adjusts edge waypoints to draw them as polylines. It ensures that the start and end points of the edge lie on the boundary of their respective nodes and precomputes the head angle. ### Usage To use this routing method, assign it to the `route_edge` attribute of a layout instance: ```python >>> from your_module import SugiyamaLayout, route_with_lines >>> # Assuming 'sug' is a SugiyamaLayout instance >>> sug.route_edge = route_with_lines ``` ```