diff --git a/changelog.md b/changelog.md index e529dd8..097f1d8 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ ## New features * Added the ability to set the selection mode (gesture) of the `GraphWidget` from Python, via the `selection_mode` render option or the `GraphWidget.set_selection_mode` method. +* Added the `GraphWidget.selected` trait to read back the IDs of the nodes and relationships selected in the widget UI. Use the `GraphWidget.on_selection_change` method (or `widget.observe`) to react to selection changes. ## Bug fixes diff --git a/docs/antora/modules/ROOT/pages/customizing.adoc b/docs/antora/modules/ROOT/pages/customizing.adoc index af7737d..e4e6502 100644 --- a/docs/antora/modules/ROOT/pages/customizing.adoc +++ b/docs/antora/modules/ROOT/pages/customizing.adoc @@ -233,6 +233,38 @@ In the following example, we pin the node with ID 1337 and unpin the node with I VG.toggle_nodes_pinned(1337: True, 42: False)}) ---- +== Reading the selection + +When a graph is rendered as an interactive widget via +link:{api-docs-uri}/visualization-graph/#neo4j_viz.VisualizationGraph.render_widget[`neo4j_viz.VisualizationGraph.render_widget()`], +you can read back which nodes and relationships the user has selected in the UI (using single, box, or lasso selection). + +The widget exposes the `selected` attribute, a typed link:{api-docs-uri}/widget[`GraphSelection`] with `nodeIds` and +`relationshipIds` fields holding the IDs of the currently selected nodes and relationships. +Note that the IDs are strings, so match them against `str(node.id)` / `str(relationship.id)` to recover the +link:{api-docs-uri}/node[Node] and link:{api-docs-uri}/relationship[Relationship] objects. + +To react to selection changes interactively, register a callback with `widget.on_selection_change(...)`. This is a +convenience wrapper around `widget.observe(..., names=["selected"])`: the callback runs every time the user selects +nodes or relationships in the widget, and receives the new `GraphSelection` directly. + +[source, python] +---- +# VG is a VisualizationGraph object +widget = VG.render_widget() + + +def on_selection_change(selection): + selected_nodes = [node for node in widget.nodes if str(node.id) in set(selection.nodeIds)] + # ... act on the selected nodes, e.g. add data or update other widgets + + +widget.on_selection_change(on_selection_change) +---- + +`on_selection_change` returns the registered handler, which you can pass to `widget.unobserve(handler, names=["selected"])` +to stop reacting. You can also read `widget.selected` directly at any point for the current selection. + == Direct modification of nodes and relationships Nodes and relationships can also be modified directly by accessing the `nodes` and `relationships` fields of an diff --git a/docs/source/api-reference/widget.rst b/docs/source/api-reference/widget.rst index 8ec6510..2c2fb22 100644 --- a/docs/source/api-reference/widget.rst +++ b/docs/source/api-reference/widget.rst @@ -1,2 +1,6 @@ .. autoclass:: neo4j_viz.GraphWidget :members: + +.. autoclass:: neo4j_viz.GraphSelection + :members: + :exclude-members: model_config diff --git a/examples/getting-started.ipynb b/examples/getting-started.ipynb index 7a012a5..6a7a506 100644 --- a/examples/getting-started.ipynb +++ b/examples/getting-started.ipynb @@ -20,13 +20,13 @@ "The only mandatory fields for a node are the \"id\", and \"source\" and \"target\" for a relationship.\n", "But the other fields can optionally be used to customize the appearance of the nodes and relationships in the visualization.\n", "\n", - "Lastly we create a `VisualizationGraph` object with the nodes and relationships we created, and call its `render` method to display the graph.\n" + "Lastly we create a `VisualizationGraph` object with the nodes and relationships we created, and call its `render_widget` method to display the graph as an interactive widget." ] }, { "cell_type": "code", "execution_count": 1, - "id": "801d0bed", + "id": "2ec305c1", "metadata": { "tags": [ "preserve-output" @@ -35,1615 +35,13 @@ "outputs": [ { "data": { - "text/html": [ - "\n", - "\n", - "
\n", - " \n", - " \n", - "