Skip to content

Commit

Permalink
Merge pull request #3 from HEnquist/autocomplete
Browse files Browse the repository at this point in the history
Optional autocomplete of relationships
  • Loading branch information
fskpf authored May 22, 2024
2 parents 1e3226b + 8550d01 commit 1c2bd70
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ The main class `Neo4jGraphWidget` provides the following API:
- `**kwargs`: Additional parameters that should be passed to the cypher query (e.g., see
the [selection example](https://github.com/yWorks/yfiles-jupyter-graphs-for-neo4j/blob/main/examples/selection_example.ipynb)).

The default behavior is to only show the nodes and relationships returned by the cypher query.
This can be changed to autocomplete relationships like in neo4j browser:
- `set_autocomplete_relationships(autocomplete_relationships)`: Sets whether to autocomplete relationships in the graph or not.

The cypher queries are executed by the provided Neo4j driver. If you have not specified a driver when instantiating the
class, you can set
a driver afterward:
Expand Down
47 changes: 46 additions & 1 deletion src/yfiles_jupyter_graphs_for_neo4j/Yfiles_Neo4j_Graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ class Neo4jGraphWidget:
_widget = GraphWidget()

def __init__(self, driver=None, widget_layout=None,
overview_enabled=None, context_start_with='About', license=None):
overview_enabled=None, context_start_with='About', license=None,
autocomplete_relationships=False):
if driver is not None:
self._driver = driver
self._session = driver.session()
self._license = license
self._overview = overview_enabled
self._layout = widget_layout
self._context_start_with = context_start_with
self.set_autocomplete_relationships(autocomplete_relationships)

def set_driver(self, driver):
"""
Expand All @@ -44,13 +46,56 @@ def get_driver(self):
"""
return self._driver

def set_autocomplete_relationships(self, autocomplete_relationships):
"""
Sets the flag to enable or disable autocomplete for relationships.
When autocomplete is enabled, relationships are automatically completed in the graph,
similar to the behavior in Neo4j Browser.
This can be set to True/False to enable or disable for all relationships,
or a single relationship type or a list of relationship types to enable for specific relationships.
:param autocomplete_relationships: bool | str | list[str]
"""
if not isinstance(autocomplete_relationships, (bool, str, list)):
raise ValueError("autocomplete_relationships must be a bool, a string, or a list of strings")
if isinstance(autocomplete_relationships, str):
self._autocomplete_relationships = [autocomplete_relationships]
else:
self._autocomplete_relationships = autocomplete_relationships

def _is_autocomplete_enabled(self):
if isinstance(self._autocomplete_relationships, bool):
return self._autocomplete_relationships
return len(self._autocomplete_relationships) > 0

def _get_relationship_types_expression(self):
if isinstance(self._autocomplete_relationships, list) and len(self._autocomplete_relationships) > 0:
return "AND type(rel) IN $relationship_types"
return ""

def show_cypher(self, cypher, **kwargs):
"""
main function
:param cypher: str, Send a data query to the neo4j database
**kwargs: variable declarations usable in cypher
"""
if self._driver is not None:
if self._is_autocomplete_enabled():
nodes = self._session.run(cypher, **kwargs).graph().nodes
node_ids = [node.element_id for node in nodes]
reltypes_expr = self._get_relationship_types_expression()
cypher = f"""
MATCH (n) WHERE elementId(n) IN $node_ids
RETURN n as start, NULL as rel, NULL as end
UNION ALL
MATCH (n)-[rel]-(m)
WHERE elementId(n) IN $node_ids
AND elementId(m) IN $node_ids
{reltypes_expr}
RETURN n as start, rel, m as end
"""
kwargs = {"node_ids": node_ids}
if reltypes_expr:
kwargs["relationship_types"] = self._autocomplete_relationships
widget = GraphWidget(overview_enabled=self._overview, context_start_with=self._context_start_with,
widget_layout=self._layout, license=self._license,
graph=self._session.run(cypher, **kwargs).graph())
Expand Down

0 comments on commit 1c2bd70

Please sign in to comment.