rsdeps

Cargo.lock visualizer (mirror)
Log | Files | Refs | README | LICENSE

commit fbf864b32f697fe4f46caf44299522b64a399f17
parent 853c01f05eb699a038ebd4633ed23b0ca3c68c4d
Author: Andy Khramtsov <>
Date:   Sun, 31 May 2026 15:13:24 +0300

feat: add subtree toggle

Diffstat:
Msrc/rsdeps/pages/home.py | 38+++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/rsdeps/pages/home.py b/src/rsdeps/pages/home.py @@ -30,23 +30,28 @@ class ids: recalculate_button: str = "recalculate-button" generate_button: str = "generate-button" - dependency_graph: str = "dependency-graph" reset_highlight_button: str = "reset-highlight-button" + toggles: str = "toggles" + dependency_graph: str = "dependency-graph" selected_node_details: str = "selected-node-details" cache_store: str = "cache-store" selected_node_store: str = "selected-node-store" +class toggle_values: + subtree: str = "subtree" + + class colors: background: str = "#FAFAFA" outline: str = "#FFFFFF" - outline_highlight: str = "#808080" + outline_highlight: str = "#8080B0" node: str = "#B0D0F0" node_main: str = "#F080A0" node_faint: str = "#E0E0E0" line: str = "#B0B0B0" - line_highlight: str = "#808080" + line_highlight: str = "#8080B0" line_faint: str = "#E0E0E0" text: str = "#202020" text_faint: str = "#B0B0B0" @@ -239,6 +244,12 @@ def layout(): id=ids.reset_highlight_button, children="Deselect", ), + dcc.Checklist( + id=ids.toggles, + inline=True, + persistence=True, + options=[dict(label="Subtree", value=toggle_values.subtree)], + ), ], ), html.Div( @@ -439,6 +450,7 @@ def draw_graph_figure( positions: dict[str, tuple[float, float]], adjacency_list: dict[str, set[str]], selected_node=None, + subtree: bool = False, ) -> go.Figure: highlight_nodes = set() if selected_node and selected_node in adjacency_list: @@ -709,7 +721,7 @@ def display_cargo_lock_packages(inputs, state): ), prevent_initial_call=True, ) -def generate(inputs, state): +def graph_generate(inputs, state): if not state["cargo_lock"]: raise PreventUpdate try: @@ -754,6 +766,7 @@ def generate(inputs, state): ), dict( click_data=Input(ids.dependency_graph, "clickData"), + toggles=Input(ids.toggles, "value"), reset_highlight_button=Input(ids.reset_highlight_button, "n_clicks"), ), dict( @@ -763,7 +776,7 @@ def generate(inputs, state): ), prevent_initial_call=True, ) -def update(inputs, state): +def graph_update(inputs, state): if ( not state["cache"] or state["cache"].get("positions") is None @@ -775,13 +788,24 @@ def update(inputs, state): if ctx.triggered_id and ctx.triggered_id == ids.reset_highlight_button: selected = None - elif inputs["click_data"] and "points" in inputs["click_data"]: + elif ( + ctx.triggered_id + and ctx.triggered_id == ids.dependency_graph + and inputs["click_data"] + and "points" in inputs["click_data"] + ): point = inputs["click_data"]["points"][0] selected = point.get("customdata", None) else: selected = None + if state["selected_node_store"] and state["selected_node_store"].get("selected") == selected: selected = None + elif selected is None: + selected = state["selected_node_store"].get("selected") + + toggles = inputs["toggles"] or [] + subtree = toggle_values.subtree in toggles positions = state["cache"]["positions"] adjacency_list = unwrap_adjacency_list(state["cache"]["adjacency_list"]) @@ -803,7 +827,7 @@ def update(inputs, state): old_fig = state["figure"] uirevision = old_fig.get("layout", {}).get("uirevision", 0) - fig = draw_graph_figure(df_graph, positions, adjacency_list, selected) + fig = draw_graph_figure(df_graph, positions, adjacency_list, selected, subtree) fig.update_layout(uirevision=uirevision) return dict(