Skip to content

Commit c9aa085

Browse files
committed
fixes #18 and prepares release
1 parent fd6812f commit c9aa085

File tree

4 files changed

+59
-14
lines changed

4 files changed

+59
-14
lines changed

gremlin/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.6"
1+
__version__ = "0.0.7"

gremlin/draw.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

3134
class 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

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ readme = "README.md"
2020
license = { file="LICENSE" }
2121
dependencies = [
2222
# https://pypi.org/project/gremlinpython/
23-
'gremlinpython>=3.6.4',
23+
'gremlinpython>=3.7.0',
2424
# https://pypi.org/project/graphviz/
2525
'graphviz>=0.20.1',
2626
# https://pypi.org/project/PyYAML/

tests/test_draw.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class TestDraw(BaseGremlinTest):
1515

1616
def check_draw(self,gviz):
1717
"""
18+
check the drawing result
1819
"""
1920
debug=self.debug
2021
debug=True
@@ -41,12 +42,29 @@ def testDrawTraversal(self):
4142
gviz=GremlinDraw.show_graph_traversal(g, traversal, "software")
4243
self.check_draw(gviz)
4344

44-
def testGremlinDraw(self):
45-
g=self.g
46-
self.examples.load_by_name(g, "tinkerpop-modern")
47-
traversal=g.E().hasLabel("created").toList()
48-
gd=GremlinDraw()
45+
def testDrawLimited(self):
46+
"""
47+
test the limited drawing
48+
"""
49+
g=self.g
50+
self.examples.load_by_name(g, "air-routes-latest")
51+
# see https://www.kelvinlawrence.net/book/PracticalGremlin.html#continentdist
52+
traversal = (
53+
g.V()
54+
.has('continent', 'code', 'EU')
55+
.outE().as_('contains').inV()
56+
.outE().as_('route').inV()
57+
.has('country', 'US')
58+
.select('route')
59+
.toList()
60+
)
4961

62+
self.assertTrue(len(traversal)>=435)
63+
gd=GremlinDraw(g,title="EU - US Flights")
64+
gd.config.v_limit=5
65+
gd.config.vertex_properties=["country","code","city"] #[""]
66+
gd.draw(traversal)
67+
self.check_draw(gd.gviz)
5068

5169
if __name__ == "__main__":
5270
#import sys;sys.argv = ['', 'Test.testName']

0 commit comments

Comments
 (0)