|
1 | 1 | import importlib.metadata
|
2 | 2 | from pathlib import Path
|
| 3 | +from typing import Any |
3 | 4 |
|
4 | 5 | import anywidget
|
| 6 | +import ipywidgets |
5 | 7 | import traitlets
|
6 | 8 |
|
7 | 9 | try:
|
@@ -33,3 +35,60 @@ class GraphvizWidget(anywidget.AnyWidget):
|
33 | 35 | selected_direction = traitlets.Unicode("bidirectional").tag(sync=True)
|
34 | 36 | search_type = traitlets.Unicode("included").tag(sync=True)
|
35 | 37 | case_sensitive = traitlets.Bool(False).tag(sync=True) # noqa: FBT003
|
| 38 | + |
| 39 | + |
| 40 | +def graph_widget( |
| 41 | + dot_string: str = "digraph { a -> b; b -> c; c -> a; }", |
| 42 | +) -> ipywidgets.VBox: |
| 43 | + widget = GraphvizWidget(dot_source=dot_string) |
| 44 | + reset_button = ipywidgets.Button(description="Reset Zoom") |
| 45 | + direction_selector = ipywidgets.Dropdown( |
| 46 | + options=["bidirectional", "downstream", "upstream", "single"], |
| 47 | + value="bidirectional", |
| 48 | + description="Direction:", |
| 49 | + ) |
| 50 | + search_input = ipywidgets.Text( |
| 51 | + placeholder="Search...", |
| 52 | + description="Search:", |
| 53 | + ) |
| 54 | + search_type_selector = ipywidgets.Dropdown( |
| 55 | + options=["exact", "included", "regex"], |
| 56 | + value="exact", |
| 57 | + description="Search Type:", |
| 58 | + ) |
| 59 | + case_toggle = ipywidgets.ToggleButton( |
| 60 | + value=False, |
| 61 | + description="Case Sensitive", |
| 62 | + icon="check", |
| 63 | + ) |
| 64 | + |
| 65 | + # Define button actions |
| 66 | + def reset_graph(_: Any) -> None: |
| 67 | + widget.send({"action": "reset_zoom"}) |
| 68 | + |
| 69 | + def update_direction(change: dict) -> None: |
| 70 | + widget.selected_direction = change["new"] |
| 71 | + |
| 72 | + def perform_search(change: dict) -> None: |
| 73 | + widget.send({"action": "search", "query": change["new"]}) |
| 74 | + |
| 75 | + def update_search_type(change: dict) -> None: |
| 76 | + widget.search_type = change["new"] |
| 77 | + |
| 78 | + def toggle_case_sensitive(change: dict) -> None: |
| 79 | + widget.case_sensitive = change["new"] |
| 80 | + |
| 81 | + reset_button.on_click(reset_graph) |
| 82 | + direction_selector.observe(update_direction, names="value") |
| 83 | + search_input.observe(perform_search, names="value") |
| 84 | + search_type_selector.observe(update_search_type, names="value") |
| 85 | + case_toggle.observe(toggle_case_sensitive, names="value") |
| 86 | + |
| 87 | + # Display ipywidgets |
| 88 | + return ipywidgets.VBox( |
| 89 | + [ |
| 90 | + ipywidgets.HBox([reset_button, direction_selector]), |
| 91 | + ipywidgets.HBox([search_input, search_type_selector, case_toggle]), |
| 92 | + widget, |
| 93 | + ], |
| 94 | + ) |
0 commit comments