Skip to content

Commit a918383

Browse files
authored
Merge pull request #275 from OskarDamkjaer/react-viz
Move the GraphVisualization wrapper
2 parents 8ea18a2 + 11bc330 commit a918383

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+111947
-1863
lines changed

.github/workflows/code-style.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
python-version: "3.11"
3434
enable-cache: true
3535
- run: uv venv
36-
- run: uv sync --group dev --extra pandas --extra gds --extra snowflake
36+
- run: uv sync --group dev --extra pandas --extra neo4j --extra gds --extra snowflake
3737

3838
- name: Check code style
3939
run: source .venv/bin/activate && cd ${GITHUB_WORKSPACE} && ./scripts/checkstyle.sh

.github/workflows/nvl-entrypoint-test.yml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,18 @@ name: Build JS Applet and check for changes
55
on:
66
# Triggers the workflow on push or pull request events but only for the "main" branch
77
push:
8-
branches: [ "main" ]
8+
branches: ["main"]
99
pull_request:
1010
paths:
11-
- "js-applet/src/nvl_entrypoint/**" # JS sources
12-
- "js-applet/webpack.config.js"
13-
- "js-applet/babel.config.js"
14-
- "js-applet/package.json"
15-
- "js-applet/tsconfig.json"
16-
branches: [ "main" ]
11+
- "js-applet/**"
12+
branches: ["main"]
1713

1814
# Allows you to run this workflow manually from the Actions tab
1915
workflow_dispatch:
2016

2117
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
2218
jobs:
23-
2419
tests:
25-
2620
# The type of runner that the job will run on
2721
runs-on: "ubuntu-latest"
2822

@@ -34,7 +28,7 @@ jobs:
3428
- uses: actions/checkout@v4
3529
- uses: actions/setup-node@v4
3630
with:
37-
node-version: '23.x'
31+
node-version: "24.x"
3832
- name: Setup
3933
run: yarn
4034
- name: Build

.github/workflows/snowflake-integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ jobs:
4343
SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
4444
SNOWFLAKE_ROLE: ACCOUNTADMIN
4545
SNOWFLAKE_WAREHOUSE: ${{ secrets.SNOWFLAKE_WAREHOUSE }}
46-
run: pytest tests/ --include-snowflake
46+
run: uv run pytest tests/ --include-snowflake

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ out/*
2727
.idea
2828

2929
.dmypy.json
30-
python-wrapper/uv.lock
30+
.virtual_documents
31+
# ignore top-level yarn files, the js-applet files are relevant
32+
yarn.lock

CONTRIBUTING.md

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ If you're not already a member, sign up!
99

1010
We love our community and wouldn't be where we are without you.
1111

12-
1312
## Need to raise an issue?
1413

1514
Where you raise an issue depends largely on the nature of the problem.
@@ -34,7 +33,6 @@ Include as much information as you can in any request you make:
3433
- What errors are you seeing?
3534
- What solutions have you tried already?
3635

37-
3836
## Want to contribute?
3937

4038
If you want to contribute a pull request, we have a little bit of process you'll need to follow:
@@ -50,102 +48,87 @@ We can't guarantee that we'll accept pull requests and may ask you to make some
5048
Occasionally, we might also have logistical, commercial, or legal reasons why we can't accept your work but we'll try to find an alternative way for you to contribute in that case.
5149
Remember that many community members have become regular contributors and some are now even Neo employees!
5250

53-
54-
## Building the project locally
55-
56-
To build the Python packages, run inside the `python-wrapper` folder:
51+
## Quick start
5752

5853
```sh
59-
pip install . # run with --editable for development mode
54+
just js-dev
6055
```
6156

62-
To rebuild the JavaScript applet, run inside the `js-applet` folder:
57+
This starts Vite watch builds and Jupyter Lab with hot module reloading. Changes to `js-applet/src/` will auto-reload in active widget cells.
58+
59+
If you want to modify the python code, run:
6360

6461
```sh
65-
yarn # Install JavaScript dependencies
66-
yarn build # Build JavaScript resources to be used by Python code
62+
just py-sync
6763
```
6864

69-
This will build the app and copy the relevant files to the python wrapper
65+
This will install all required dev dependencies and install the package in editable mode.
7066

7167

7268
## Specifically for this project
7369

7470
In this section, we will provide some more specific information about how to work with this particular project.
7571

76-
7772
### Python development environment
7873

79-
* Install Python 3.9+
80-
* [Install pip](https://pip.pypa.io/en/stable/installation/)
81-
* Install the project's Python dependencies:
82-
```bash
83-
pip install -e .
84-
pip install ".[dev]"
85-
```
74+
- Install Python 3.10+
75+
- We recommend installing [just](https://github.com/casey/just) for running commands
76+
77+
Install the project's Python dependencies:
78+
```bash
79+
just py-sync
80+
```
81+
82+
Apply and check python styling:
83+
```sh
84+
just py-style
85+
```
86+
8687

8788
### Testing
8889

8990
To run unit tests, execute:
9091

9192
```sh
92-
pytest python-wrapper/tests
93+
just py-test
9394
```
9495

9596
Additionally, there are integration tests that require an external data source.
9697
These require additional setup and configuration, such as environment variables specifying connection details.
9798

98-
99-
For a local Neo4j instance with GDS installed, execute:
99+
To test the Neo4j and GDS related tests, execute:
100100
```sh
101-
cd test-envs/neo4j-gds
102-
docker compose up -d
103-
```
104-
105-
To run tests requiring a Neo4j DB instance with GDS installed, execute:
106-
```sh
107-
export NEO4J_URI=localhost:7687 # or credentials for Aura API
108-
cd python-wrapper/
109-
pytest tests --include-neo4j-and-gds
101+
just py-test-gds
110102
```
103+
This will spinup a Neo4j container with the GDS plugin installed.
111104

112105
To run tests requiring a Snowflake connection, execute:
113-
114106
```sh
115107
cd python-wrapper/
116108
pytest tests/ --include-snowflake
117109
```
118110

119-
120111
### Project structure
121112

122113
The project contains of three parts:
123114

124-
- a JavaScript applet whith a basic NVL implementation under the `js-applect` folder
115+
- a JavaScript applet under the `js-applet` folder
125116
- a Python package which loads the applet and offers convenience functions to pass data to the applet
126-
- Jupyter notebooks to test the NVL Python wrapper
127-
117+
- Jupyter notebooks to test the Python wrapper
128118

129-
### JavaScipts configs
130-
131-
* `babel.config.js` - Config for the JavaScript compiler
132-
* `tsconfig.json` - Configuration for TypeScript code
133-
* `package.json` - For yarn, define dependencies and `build` target
134-
* `webpack.config.js` - Config for bundling JS parts
119+
### JavaScript configs
135120

121+
- `vite.config.ts` - Vite config for the lib build (widget.js + style.css for anywidget)
122+
- `vite.config.html.ts` - Vite config for the HTML singlefile build (self-contained index.html)
123+
- `tsconfig.json` - Configuration for TypeScript code
124+
- `package.json` - For yarn, define dependencies and `build` target
136125

137126
### Python
138127

139128
Everything is configured inside `pyproject.toml`
140129

141130
To keep a consistent code-style, we use `ruff` and `mypy`.
142-
For convenience there are a couple of scripts:
143-
144-
```sh
145-
./scripts/makestyle.sh # try to fix linting violations and format code
146-
./scripts/checkstyle.sh # check for linting, format or typing issues
147-
148-
```
131+
For convenience there are a couple of just targets under `justfile`:
149132

150133

151134
## Got an idea for a new project?
@@ -155,7 +138,6 @@ Chances are that someone has a similar idea or may have already started working
155138
The best software comes from getting like minds together to solve a problem.
156139
And we'll do our best to help you promote and co-ordinate your Neo4j ecosystem projects.
157140

158-
159141
## Further reading
160142

161143
If you want to find out more about how you can contribute, head over to our website for [more information](http://neo4j.com/developer/contributing-code/).

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
include examples/example_cora_graph.png
1+
include examples/example_graph.png

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010

1111
`neo4j-viz` is a Python package for creating interactive graph visualizations.
1212

13-
The output is of type `IPython.display.HTML` and can be viewed directly in a Jupyter Notebook or Streamlit application.
13+
The `render` method returns an `IPython.display.HTML` object that can be viewed directly in a Jupyter Notebook or Streamlit application.
14+
For an interactive widget experience, use `render_widget()` which returns an anywidget-based `GraphWidget` with two-way data sync.
1415
Alternatively, you can export the output to a file and view it in a web browser.
1516

1617
The package wraps the [Neo4j Visualization JavaScript library (NVL)](https://neo4j.com/docs/nvl/current/).
1718

18-
![Example Graph](examples/example_cora_graph.png)
19+
![Example Graph](examples/example_graph.png)
1920

2021
## Some notable features
2122

@@ -102,7 +103,8 @@ VG = VisualizationGraph(nodes=nodes, relationships=relationships)
102103
VG.render()
103104
```
104105

105-
This will return a `IPython.display.HTML` object that can be rendered in a Jupyter Notebook or streamlit application.
106+
This will return an `IPython.display.HTML` object that can be rendered in a Jupyter Notebook or Streamlit application.
107+
For an interactive Jupyter widget, use `VG.render_widget()` instead.
106108

107109
Please refer to the [documentation](https://neo4j.com/docs/nvl-python/preview/) for more details on the API and usage.
108110

changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@
22

33
## Breaking changes
44

5+
- Removed the `show_hover_tooltip` parameter from `render()`. The visualization now shows a detail side panel for selected nodes and relationships, replacing the previous hover tooltip.
6+
- Nodes are colored by default by their caption. Use `VG.color_nodes(field="caption", colors=[neo4j_viz.colors.NEO4J_COLORS_DISCRETE[0]])` to apply the previous coloring.
7+
58

69
## New features
710

11+
- Nodes are now automatically colored by their caption (label) in the JavaScript visualization. This works out of the box without needing to call `color_nodes()`, and applies regardless of how the graph was created. Explicit colors set via `color_nodes()` or directly on nodes take precedence. There is no longer a limit on the number of unique labels for auto-coloring.
12+
- New `Zoom to fit` button in the visualization.
13+
- New `render_widget()` method on `VisualizationGraph` returns a `GraphWidget` (anywidget) for interactive two-way data sync in Jupyter environments (JupyterLab, Notebook 7, VS Code, Colab).
14+
815
## Bug fixes
916

1017
## Improvements
1118

19+
- Migrated JavaScript visualization from `@neo4j-nvl/base` to `@neo4j-ndl/react-graph` React component.
20+
- Migrated build system from Webpack to Vite.
21+
- Added anywidget integration as the primary rendering path for Jupyter environments.
1222

1323
## Other changes

docs/antora/modules/ROOT/pages/customizing.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Nodes and relationships can be colored directly by providing them with a color f
5555
This can be done by passing a color as a string to the `color` parameter of the
5656
link:{api-docs-uri}/node[Node] or link:{api-docs-uri}/relationship[Relationship] object.
5757

58+
By default, the nodes will be colored based on their caption. The colors are the same as in other Neo4j tools, such as Neo4j Console and Neo4j Browser.
59+
5860
Alternatively, you can color nodes or relationships based on a field or property after a `VisualizationGraph` object has been
5961
created.
6062

@@ -258,4 +260,4 @@ for relationship in VG.relationships:
258260
relationship.caption_size = 15
259261
----
260262

261-
Any changes made to the nodes and relationships will be reflected in the next rendering of the graph.
263+
Any changes made to the nodes and relationships will be reflected in the next rendering of the graph.
216 KB
Loading

0 commit comments

Comments
 (0)