Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion js-applet/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NVL } from '@neo4j-nvl/base'
import { FreeLayoutType, NVL } from '@neo4j-nvl/base'
import type { Node, NvlOptions, Relationship } from '@neo4j-nvl/base'
import { DragNodeInteraction, PanInteraction, ZoomInteraction } from '@neo4j-nvl/interaction-handlers'

Expand All @@ -22,6 +22,10 @@ class PyNVL {
this.zoomInteraction = new ZoomInteraction(this.nvl)
this.panInteraction = new PanInteraction(this.nvl)
this.dragNodeInteraction = new DragNodeInteraction(this.nvl)

if (options.layout === FreeLayoutType) {
this.nvl.setNodePositions(nvlNodes, false)
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions python-wrapper/src/neo4j_viz/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class Node(BaseModel, extra="allow"):
size: Optional[RealNumber] = Field(None, ge=0, description="The size of the node as radius in pixel")
color: Optional[ColorType] = Field(None, description="The color of the node")
pinned: Optional[bool] = Field(None, description="Whether the node is pinned in the visualization")
x: Optional[RealNumber] = Field(None, description="The x-coordinate of the node")
y: Optional[RealNumber] = Field(None, description="The y-coordinate of the node")

@field_serializer("color")
def serialize_color(self, color: Color) -> str:
Expand Down
5 changes: 4 additions & 1 deletion python-wrapper/src/neo4j_viz/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ class Layout(str, Enum):
FORCE_DIRECTED = "forcedirected"
HIERARCHICAL = "hierarchical"
GRID = "grid"
# TODO expose free layout for X,Y based
COORDINATE = "free"
""""
The coordinate layout sets the position of each node based on the `x` and `y` properties of the node.
"""


class Renderer(str, Enum):
Expand Down

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions python-wrapper/tests/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def test_nodes_with_all_options() -> None:
color="#FF0000",
size=10,
pinned=True,
x=1,
y=10,
)

assert node.to_dict() == {
Expand All @@ -22,6 +24,8 @@ def test_nodes_with_all_options() -> None:
"color": "#ff0000",
"size": 10,
"pinned": True,
"x": 1,
"y": 10,
}


Expand Down Expand Up @@ -66,3 +70,8 @@ def test_id_aliases(alias: str) -> None:
assert node.to_dict() == {
"id": "1",
}


def test_node_validation() -> None:
with pytest.raises(ValueError, match="Input should be a valid integer, unable to parse string as an integer"):
Node(id="1", x="not a number")
15 changes: 8 additions & 7 deletions python-wrapper/tests/test_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@
"default": {},
"force layout": {"layout": Layout.FORCE_DIRECTED},
"grid layout": {"layout": Layout.GRID},
"coordinate layout": {"layout": Layout.COORDINATE},
}


@pytest.mark.parametrize("render_option", render_cases.values(), ids=render_cases.keys())
def test_basic_render(render_option: dict[str, Any], tmp_path: Path) -> None:
nodes = [
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:0", caption="Person"),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:6", caption="Product"),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:11", caption="Product", pinned=True),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:12", caption="Product"),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:1", caption="Person"),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:7", caption="Product"),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:8", caption="Product"),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:0", caption="Person", x=1, y=10),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:6", caption="Product", x=2, y=15),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:11", caption="Product", x=3, pinned=True),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:12", caption="Product", x=4),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:1", caption="Person", x=5),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:7", caption="Product", x=6),
Node(id="4:d09f48a4-5fca-421d-921d-a30a896c604d:8", caption="Product", x=7),
]
relationships = [
Relationship(
Expand Down
11 changes: 11 additions & 0 deletions scripts/build_js_applet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
GIT_ROOT=$(git rev-parse --show-toplevel)

set -o errexit
set -o nounset
set -o pipefail

(
cd "${GIT_ROOT}/js-applet"
yarn
yarn build
)
Loading