neo4j-viz 0.5.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- neo4j_viz/gds.py +46 -47
- neo4j_viz/gql_create.py +32 -79
- neo4j_viz/neo4j.py +29 -92
- neo4j_viz/node.py +4 -5
- neo4j_viz/options.py +3 -0
- neo4j_viz/pandas.py +24 -41
- neo4j_viz/relationship.py +4 -5
- neo4j_viz/resources/__init__.py +0 -0
- neo4j_viz/resources/icons/__init__.py +0 -0
- neo4j_viz/resources/nvl_entrypoint/__init__.py +0 -0
- neo4j_viz/resources/nvl_entrypoint/base.js +1 -1
- neo4j_viz/snowflake.py +30 -22
- neo4j_viz/visualization_graph.py +104 -21
- {neo4j_viz-0.5.0.dist-info → neo4j_viz-0.6.0.dist-info}/METADATA +10 -9
- neo4j_viz-0.6.0.dist-info/RECORD +27 -0
- neo4j_viz-0.6.0.dist-info/licenses/LICENSE +695 -0
- neo4j_viz-0.5.0.dist-info/RECORD +0 -23
- {neo4j_viz-0.5.0.dist-info → neo4j_viz-0.6.0.dist-info}/WHEEL +0 -0
- {neo4j_viz-0.5.0.dist-info → neo4j_viz-0.6.0.dist-info}/top_level.txt +0 -0
neo4j_viz/pandas.py
CHANGED
|
@@ -29,8 +29,6 @@ def _parse_validation_error(e: ValidationError, entity_type: type[BaseModel]) ->
|
|
|
29
29
|
def _from_dfs(
|
|
30
30
|
node_dfs: Optional[DFS_TYPE] = None,
|
|
31
31
|
rel_dfs: Optional[DFS_TYPE] = None,
|
|
32
|
-
node_radius_min_max: Optional[tuple[float, float]] = (3, 60),
|
|
33
|
-
rename_properties: Optional[dict[str, str]] = None,
|
|
34
32
|
dropna: bool = False,
|
|
35
33
|
) -> VisualizationGraph:
|
|
36
34
|
if node_dfs is None and rel_dfs is None:
|
|
@@ -39,29 +37,21 @@ def _from_dfs(
|
|
|
39
37
|
if rel_dfs is None:
|
|
40
38
|
relationships = []
|
|
41
39
|
else:
|
|
42
|
-
relationships = _parse_relationships(rel_dfs,
|
|
40
|
+
relationships = _parse_relationships(rel_dfs, dropna=dropna)
|
|
43
41
|
|
|
44
42
|
if node_dfs is None:
|
|
45
|
-
has_size = False
|
|
46
43
|
node_ids = set()
|
|
47
44
|
for rel in relationships:
|
|
48
45
|
node_ids.add(rel.source)
|
|
49
46
|
node_ids.add(rel.target)
|
|
50
47
|
nodes = [Node(id=id) for id in node_ids]
|
|
51
48
|
else:
|
|
52
|
-
nodes
|
|
49
|
+
nodes = _parse_nodes(node_dfs, dropna=dropna)
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
return VisualizationGraph(nodes=nodes, relationships=relationships)
|
|
55
52
|
|
|
56
|
-
if node_radius_min_max is not None and has_size:
|
|
57
|
-
VG.resize_nodes(node_radius_min_max=node_radius_min_max)
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def _parse_nodes(
|
|
63
|
-
node_dfs: DFS_TYPE, rename_properties: Optional[dict[str, str]], dropna: bool = False
|
|
64
|
-
) -> tuple[list[Node], bool]:
|
|
54
|
+
def _parse_nodes(node_dfs: DFS_TYPE, dropna: bool = False) -> list[Node]:
|
|
65
55
|
if isinstance(node_dfs, DataFrame):
|
|
66
56
|
node_dfs_iter: Iterable[DataFrame] = [node_dfs]
|
|
67
57
|
elif node_dfs is None:
|
|
@@ -69,37 +59,31 @@ def _parse_nodes(
|
|
|
69
59
|
else:
|
|
70
60
|
node_dfs_iter = node_dfs
|
|
71
61
|
|
|
72
|
-
|
|
62
|
+
basic_node_fields_aliases = Node.basic_fields_validation_aliases()
|
|
73
63
|
|
|
74
|
-
has_size = True
|
|
75
64
|
nodes = []
|
|
76
65
|
for node_df in node_dfs_iter:
|
|
77
|
-
has_size &= "size" in [c.lower() for c in node_df.columns]
|
|
78
66
|
for _, row in node_df.iterrows():
|
|
79
67
|
if dropna:
|
|
80
68
|
row = row.dropna(inplace=False)
|
|
81
|
-
|
|
69
|
+
mandatory_fields = {}
|
|
82
70
|
properties = {}
|
|
83
71
|
for key, value in row.to_dict().items():
|
|
84
|
-
if key in
|
|
85
|
-
|
|
72
|
+
if key in basic_node_fields_aliases:
|
|
73
|
+
mandatory_fields[key] = value
|
|
86
74
|
else:
|
|
87
|
-
if rename_properties and key in rename_properties:
|
|
88
|
-
key = rename_properties[key]
|
|
89
75
|
properties[key] = value
|
|
90
76
|
|
|
91
77
|
try:
|
|
92
|
-
nodes.append(Node(**
|
|
78
|
+
nodes.append(Node(**mandatory_fields, properties=properties))
|
|
93
79
|
except ValidationError as e:
|
|
94
80
|
_parse_validation_error(e, Node)
|
|
95
81
|
|
|
96
|
-
return nodes
|
|
82
|
+
return nodes
|
|
97
83
|
|
|
98
84
|
|
|
99
|
-
def _parse_relationships(
|
|
100
|
-
|
|
101
|
-
) -> list[Relationship]:
|
|
102
|
-
all_rel_field_aliases = Relationship.all_validation_aliases()
|
|
85
|
+
def _parse_relationships(rel_dfs: DFS_TYPE, dropna: bool = False) -> list[Relationship]:
|
|
86
|
+
basic_rel_field_aliases = Relationship.basic_fields_validation_aliases()
|
|
103
87
|
|
|
104
88
|
if isinstance(rel_dfs, DataFrame):
|
|
105
89
|
rel_dfs_iter: Iterable[DataFrame] = [rel_dfs]
|
|
@@ -111,18 +95,16 @@ def _parse_relationships(
|
|
|
111
95
|
for _, row in rel_df.iterrows():
|
|
112
96
|
if dropna:
|
|
113
97
|
row = row.dropna(inplace=False)
|
|
114
|
-
|
|
98
|
+
mandatory_fields = {}
|
|
115
99
|
properties = {}
|
|
116
100
|
for key, value in row.to_dict().items():
|
|
117
|
-
if key in
|
|
118
|
-
|
|
101
|
+
if key in basic_rel_field_aliases:
|
|
102
|
+
mandatory_fields[key] = value
|
|
119
103
|
else:
|
|
120
|
-
if rename_properties and key in rename_properties:
|
|
121
|
-
key = rename_properties[key]
|
|
122
104
|
properties[key] = value
|
|
123
105
|
|
|
124
106
|
try:
|
|
125
|
-
relationships.append(Relationship(**
|
|
107
|
+
relationships.append(Relationship(**mandatory_fields, properties=properties))
|
|
126
108
|
except ValidationError as e:
|
|
127
109
|
_parse_validation_error(e, Relationship)
|
|
128
110
|
|
|
@@ -132,14 +114,17 @@ def _parse_relationships(
|
|
|
132
114
|
def from_dfs(
|
|
133
115
|
node_dfs: Optional[DFS_TYPE] = None,
|
|
134
116
|
rel_dfs: Optional[DFS_TYPE] = None,
|
|
135
|
-
node_radius_min_max: Optional[tuple[float, float]] = (3, 60),
|
|
136
117
|
) -> VisualizationGraph:
|
|
137
118
|
"""
|
|
138
119
|
Create a VisualizationGraph from pandas DataFrames representing a graph.
|
|
139
120
|
|
|
140
121
|
All columns will be included in the visualization graph.
|
|
141
|
-
|
|
142
|
-
|
|
122
|
+
The following columns will be treated as fields:
|
|
123
|
+
|
|
124
|
+
* `id` for the node_dfs
|
|
125
|
+
* `id`, `source`, `target` for the rel_dfs
|
|
126
|
+
|
|
127
|
+
Other columns will be included in the `properties` dictionary on the respective node or relationship objects.
|
|
143
128
|
|
|
144
129
|
Parameters
|
|
145
130
|
----------
|
|
@@ -149,9 +134,7 @@ def from_dfs(
|
|
|
149
134
|
rel_dfs: Optional[Union[DataFrame, Iterable[DataFrame]]], optional
|
|
150
135
|
DataFrame or iterable of DataFrames containing relationship data.
|
|
151
136
|
If None, no relationships will be created.
|
|
152
|
-
|
|
153
|
-
Minimum and maximum node radius.
|
|
154
|
-
To avoid tiny or huge nodes in the visualization, the node sizes are scaled to fit in the given range.
|
|
137
|
+
|
|
155
138
|
"""
|
|
156
139
|
|
|
157
|
-
return _from_dfs(node_dfs, rel_dfs,
|
|
140
|
+
return _from_dfs(node_dfs, rel_dfs, dropna=False)
|
neo4j_viz/relationship.py
CHANGED
|
@@ -30,6 +30,7 @@ class Relationship(
|
|
|
30
30
|
validation_alias=create_aliases,
|
|
31
31
|
serialization_alias=lambda field_name: to_camel(field_name),
|
|
32
32
|
),
|
|
33
|
+
validate_assignment=True,
|
|
33
34
|
):
|
|
34
35
|
"""
|
|
35
36
|
A relationship in a graph to visualize.
|
|
@@ -97,14 +98,12 @@ class Relationship(
|
|
|
97
98
|
return self.model_dump(exclude_none=True, by_alias=True)
|
|
98
99
|
|
|
99
100
|
@staticmethod
|
|
100
|
-
def
|
|
101
|
-
|
|
102
|
-
exempted_fields = []
|
|
103
|
-
|
|
101
|
+
def basic_fields_validation_aliases() -> set[str]:
|
|
102
|
+
basic_fields = ["id", "source", "target"]
|
|
104
103
|
by_field = [
|
|
105
104
|
v.validation_alias.choices # type: ignore
|
|
106
105
|
for k, v in Relationship.model_fields.items()
|
|
107
|
-
if k
|
|
106
|
+
if k in basic_fields
|
|
108
107
|
]
|
|
109
108
|
|
|
110
109
|
return {str(alias) for aliases in by_field for alias in aliases}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|