rsdeps

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

commit b4b7a5cad1f79dc195eeea47840f9f5548be77cf
parent 66c432e6d16a2f78e1fbd543b083b4031ba7aac5
Author: Andy Khramtsov <>
Date:   Sun, 31 May 2026 18:07:16 +0300

feat: visualize sugraph down or up

Diffstat:
Msrc/rsdeps/pages/home.py | 86++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 57 insertions(+), 29 deletions(-)

diff --git a/src/rsdeps/pages/home.py b/src/rsdeps/pages/home.py @@ -40,7 +40,8 @@ class ids: class toggle_values: - subtree: str = "subtree" + subgraph_down: str = "subgraph_down" + subgraph_up: str = "subgraph_up" class colors: @@ -248,7 +249,10 @@ def layout(): id=ids.toggles, inline=True, persistence=True, - options=[dict(label="Subtree", value=toggle_values.subtree)], + options=[ + dict(label="Subgraph down", value=toggle_values.subgraph_down), + dict(label="Subgraph up", value=toggle_values.subgraph_up), + ], ), ], ), @@ -450,35 +454,51 @@ def draw_graph_figure( positions: dict[str, tuple[float, float]], adjacency_list: dict[str, set[str]], selected_node=None, - subtree: bool = False, + subgraph_down: bool = False, + subgraph_up: bool = False, ) -> go.Figure: highlight_nodes = set() if selected_node and selected_node in adjacency_list: highlight_nodes.add(selected_node) highlight_nodes.update(adjacency_list[selected_node]) - subtree_nodes = set() - - def build_subtree(): - node_buffer = [] - if selected_node: - node_buffer.append(selected_node) - subtree_nodes.add(selected_node) - - graph = {str(node): set() for node in df_graph.nodes["node_id"]} - for arc in df_graph.arcs.iter_rows(named=True): - if arc["target"] is not None: - graph[str(arc["source"])].add(str(arc["target"])) - - while node_buffer: - source = node_buffer.pop() - for target in graph[source]: - if target not in subtree_nodes: - node_buffer.append(target) - subtree_nodes.add(target) - - if subtree: - build_subtree() + def build_subgraph(): + + def build_from_dict(graph: dict, subgraph: set): + node_buffer = [] + if selected_node: + node_buffer.append(selected_node) + subgraph.add(selected_node) + while node_buffer: + source = node_buffer.pop() + for target in graph[source]: + if target not in subgraph: + node_buffer.append(target) + subgraph.add(target) + + subgraph_up_nodes = set() + subgraph_down_nodes = set() + + if subgraph_down: + graph = {str(node): set() for node in df_graph.nodes["node_id"]} + for arc in df_graph.arcs.iter_rows(named=True): + if arc["target"] is not None: + graph[str(arc["source"])].add(str(arc["target"])) + build_from_dict(graph, subgraph_down_nodes) + + if subgraph_up: + graph = {str(node): set() for node in df_graph.nodes["node_id"]} + for arc in df_graph.arcs.iter_rows(named=True): + if arc["target"] is not None: + graph[str(arc["target"])].add(str(arc["source"])) + build_from_dict(graph, subgraph_down_nodes) + + return subgraph_down_nodes.union(subgraph_up_nodes) + + subgraph_nodes = set() + subgraph = selected_node and (subgraph_down or subgraph_up) + if subgraph: + subgraph_nodes = build_subgraph() edges = EdgeFigData( x=[], @@ -509,7 +529,7 @@ def draw_graph_figure( ): edges_highlight.x.extend([source_x, target_x, None]) edges_highlight.y.extend([source_y, target_y, None]) - elif selected_node and (not subtree or source not in subtree_nodes or target not in subtree_nodes): + elif selected_node and (not subgraph or source not in subgraph_nodes or target not in subgraph_nodes): edges_faint.x.extend([source_x, target_x, None]) edges_faint.y.extend([source_y, target_y, None]) else: @@ -550,7 +570,7 @@ def draw_graph_figure( if selected_node: if node_id in highlight_nodes: nodes_appending = nodes_highlight - elif subtree and node_id in subtree_nodes: + elif subgraph and node_id in subgraph_nodes: nodes_appending = nodes else: nodes_appending = nodes_faint @@ -842,7 +862,8 @@ def graph_update(inputs, state): selected = state["selected_node_store"].get("selected") toggles = inputs["toggles"] or [] - subtree = toggle_values.subtree in toggles + subgraph_down = toggle_values.subgraph_down in toggles + subgraph_up = toggle_values.subgraph_up in toggles positions = state["cache"]["positions"] adjacency_list = unwrap_adjacency_list(state["cache"]["adjacency_list"]) @@ -864,7 +885,14 @@ def graph_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, subtree) + fig = draw_graph_figure( + df_graph, + positions, + adjacency_list, + selected, + subgraph_down, + subgraph_up, + ) fig.update_layout(uirevision=uirevision) return dict(