@@ -27,6 +27,9 @@ class GremlinDrawConfig:
2727 dash_width : int = 5 # number of dashes to apply
2828 v_limit :int = 10 # maximum number of vertices to show
2929 e_limit :int = 10 # maximum number of edges to show
30+ # optionally set the properties to be displayed
31+ vertex_properties : List [str ] = None # New filter for vertex properties
32+ edge_properties : List [str ] = None # New filter for edge properties
3033
3134class GremlinDraw :
3235 """
@@ -43,6 +46,9 @@ def __init__(self,g: GraphTraversalSource,title:str,config:GremlinDrawConfig=Non
4346 config = GremlinDrawConfig ()
4447 self .config = config
4548 self .gviz : graphviz .Digraph = graphviz .Digraph (title , format = config .output_format )
49+ # keep track of the vertices and edges drawn
50+ self .v_drawn = {}
51+ self .e_drawn = {}
4652
4753 def __as_label (self ,head ,body :str )-> str :
4854 """
@@ -58,6 +64,11 @@ def draw_vertex(self, vertex: Vertex):
5864 """
5965 draw a single given vertex
6066 """
67+ # avoid drawing to many vertices
68+ if len (self .v_drawn )>= self .config .v_limit :
69+ return
70+ if vertex .id in self .v_drawn :
71+ return
6172 # developer note: see https://github.com/apache/tinkerpop/blob/master/gremlin-python/src/main/python/gremlin_python/structure/graph.py#LL58C23-L58C23
6273 # when gremlin-python 3.7.0 is released, the following code can be improved (get the properties using vertex.properties)
6374 # then, g can also be removed as a parameter
@@ -67,7 +78,9 @@ def draw_vertex(self, vertex: Vertex):
6778 # non-property items are of type aenum
6879 properties = [item for item in kvp_list if not isinstance (item [0 ], Enum )]
6980 assert len (properties ) == len (kvp_list ) - 2 # ID and label are not properties
70-
81+ if self .config .vertex_properties is not None :
82+ properties = [item for item in properties if item [0 ] in self .config .vertex_properties ]
83+
7184 properties_label = "\n " .join (f"{ key } : { value } " for key , value in properties )
7285 head = f"{ str (vertex .id )} \n { vertex .label } "
7386 body = f"{ properties_label } "
@@ -80,22 +93,35 @@ def draw_vertex(self, vertex: Vertex):
8093 style = "filled" ,
8194 fontname = f"{ self .config .fontname } "
8295 )
96+ self .v_drawn [vertex .id ]= vertex
8397
84- def draw_edge (self , edge : Edge ):
98+ def draw_edge (self , edge : Edge , with_vertices : bool = True ):
8599 """
86100 draw a single given edge
87101 """
102+ # avoid drawing to many vertices
103+ if len (self .e_drawn )>= self .config .e_limit :
104+ return
105+ if edge .id in self .e_drawn :
106+ return
107+ if with_vertices :
108+ self .draw_vertex (edge .inV )
109+ self .draw_vertex (edge .outV )
110+ pass
88111 # developer note: see https://github.com/apache/tinkerpop/blob/master/gremlin-python/src/main/python/gremlin_python/structure/graph.py#L66
89- # when gremlin-python 3.7.0 is released, the following code can be improved (get the properties using edge.properties)
112+ # when gremlin-python 3.7.0 is released, the following code might be improved (get the properties using edge.properties)
113+ # e_props=edge.properties
114+ # 2023-08-21: WF tested - but properties are not set ...
90115 # then, g can also be removed as a parameter
91-
92116 # get the properties of the edge
93- # kvp_list = list(next(g.E(edge).element_map()).items())
117+ kvp_list = list (next (self . g .E (edge ).element_map ()).items ())
94118 # Workaround, because the above line does not work due to inconsistencies / bugs in the gremlin-python library
95- kvp_list = [edge_element_map for edge_element_map in self .g .E ().element_map ().to_list () if edge_element_map [T .id ] == edge .id ][0 ].items ()
96- # non-proerty items are of type aenum
119+ # kvp_list = [edge_element_map for edge_element_map in self.g.E().element_map().to_list() if edge_element_map[T.id] == edge.id][0].items()
120+ # non-property items are of type aenum
97121 properties = [item for item in kvp_list if not isinstance (item [0 ], Enum )]
98122 assert len (properties ) == len (kvp_list ) - 4 # ID, label, in, and out are not properties
123+ if self .config .edge_properties is not None :
124+ properties = [item for item in properties if item [0 ] in self .config .edge_properties ]
99125
100126 properties_label = "\n " .join (f"{ key } : { value } " for key , value in properties )
101127 head = f"{ str (edge .id )} \n { edge .label } "
@@ -113,6 +139,7 @@ def draw_edge(self, edge: Edge):
113139 style = f"setlinewidth({ self .config .edge_line_width } )" ,
114140 fontname = f"{ self .config .fontname } "
115141 )
142+ self .e_drawn [edge .id ]= edge
116143
117144 def draw_g (self ):
118145 # draw vertices
0 commit comments