commit f10c4d5415831beb86a998bba5c37182500e656c
parent 05a2206867b1e62159e09e8aa9f083b8c1001ef5
Author: Andy Khramtsov <>
Date: Thu, 28 May 2026 01:32:13 +0300
feat: highlight edges
Diffstat:
1 file changed, 41 insertions(+), 17 deletions(-)
diff --git a/src/deps/pages/home.py b/src/deps/pages/home.py
@@ -195,6 +195,8 @@ def compute_positions(df_graph: dict[str, pl.DataFrame]) -> dict[str, tuple[floa
for row in df_graph["nodes"].iter_rows(named=True):
graph.add_node(pydot.Node(name=str(row["node_id"])))
for row in df_graph["arcs"].iter_rows(named=True):
+ if row["target"] is None:
+ continue
graph.add_edge(pydot.Edge(str(row["source"]), str(row["target"])))
dot_output = graph.create(prog="dot", format="dot")
@@ -223,26 +225,45 @@ def draw_graph_figure(
selected_node=None,
) -> go.Figure:
adjacency_list = {node: set() for node in df_graph["nodes"]["node_id"]}
- edge_x, edge_y = [], []
+
for row in df_graph["arcs"].iter_rows(named=True):
if not row["target"]:
continue
- src, tgt = str(row["source"]), str(row["target"])
- adjacency_list[src].add(tgt)
- adjacency_list[tgt].add(src)
-
- if src in positions and tgt in positions:
- x0, y0 = positions[src]
- x1, y1 = positions[tgt]
- edge_x.extend([x0, x1, None])
- edge_y.extend([y0, y1, None])
+ source, target = str(row["source"]), str(row["target"])
+ adjacency_list[source].add(target)
+ adjacency_list[target].add(source)
highlight_nodes = set()
if selected_node and selected_node in adjacency_list:
highlight_nodes.add(selected_node)
highlight_nodes.update(adjacency_list[selected_node])
- edge_trace = go.Scatter(x=edge_x, y=edge_y, line=dict(width=1.0, color="#A0AEC0"), hoverinfo="skip", mode="lines")
+ edge_x = []
+ edge_y = []
+ edge_x_highlight = []
+ edge_y_highlight = []
+ for row in df_graph["arcs"].iter_rows(named=True):
+ if not row["target"]:
+ continue
+ source, target = str(row["source"]), str(row["target"])
+ if source in positions and target in positions:
+ x0, y0 = positions[source]
+ x1, y1 = positions[target]
+ if (
+ source in highlight_nodes
+ and target in highlight_nodes
+ and (target == selected_node or source == selected_node)
+ ):
+ edge_x_highlight.extend([x0, x1, None])
+ edge_y_highlight.extend([y0, y1, None])
+ else:
+ edge_x.extend([x0, x1, None])
+ edge_y.extend([y0, y1, None])
+
+ edge_trace = go.Scatter(x=edge_x, y=edge_y, line=dict(width=1.0, color="#B0BEC0"), hoverinfo="skip", mode="lines")
+ edge_trace_highlight = go.Scatter(
+ x=edge_x_highlight, y=edge_y_highlight, line=dict(width=1.0, color="#707EF0"), hoverinfo="skip", mode="lines"
+ )
node_x = []
node_y = []
@@ -285,12 +306,16 @@ def draw_graph_figure(
hovertext=hover_details,
hoverinfo="text",
customdata=custom_data,
- marker=dict(showscale=False, color=colors, size=sizes, line=dict(width=2, color="white")),
+ marker=dict(showscale=False, color=colors, size=16, line=dict(width=2, color="white")),
textfont=dict(size=11, color=text_colors),
)
fig = go.Figure(
- data=[edge_trace, node_trace],
+ data=[
+ edge_trace,
+ edge_trace_highlight,
+ node_trace,
+ ],
layout=go.Layout(
title="Hierarchical Dependency Graph (Left-to-Right)",
showlegend=False,
@@ -411,11 +436,10 @@ def display_cargo_lock_packages(inputs, state):
),
)
def visualize(inputs, state):
- if ctx.triggered_id and ctx.triggered_id == ids.generate_button:
- print("clean")
- clean = True
if (
- not state["cache"]
+ ctx.triggered_id
+ and ctx.triggered_id == ids.generate_button
+ or not state["cache"]
or state["cache"].get("positions") is None
or state["cache"].get("df_graph_nodes") is None
or state["cache"].get("df_graph_arcs") is None