Skip to content

Commit 4d38019

Browse files
committed
idk
1 parent 0583d06 commit 4d38019

File tree

1 file changed

+62
-15
lines changed

1 file changed

+62
-15
lines changed

PathPlanning/TimeBasedPathPlanning/constraint_tree_viz.py

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ def visualize_cbs_tree(
3030
node_colors.append("lightblue")
3131
node_sizes.append(initial_size)
3232

33-
# Add edge from parent
34-
# if node.parent_idx is not None:
33+
# Add edge from parent only if parent exists in expanded_nodes
3534
if node.parent_idx is not None and node.parent_idx in expanded_nodes:
3635
G.add_edge(node.parent_idx, idx)
37-
# G.add_edge(0, 5)
3836
print(f"adding edge btwn {node.parent_idx} and {idx}")
3937

4038
# Add unexpanded nodes
@@ -52,44 +50,86 @@ def visualize_cbs_tree(
5250
# if node.parent_idx is not None and node.parent_idx >= 0:
5351
# G.add_edge(node.parent_idx, idx)
5452

53+
# Debug: print all edges in the graph
54+
print(f"\nAll edges in graph: {list(G.edges())}")
55+
print(f"All nodes in graph: {list(G.nodes())}")
56+
57+
5558
# Use hierarchical layout with fixed horizontal spacing
56-
pos = _hierarchy_pos(G, root=next(iter(G.nodes()), None), vert_gap=0.3, horiz_gap=1.5)
59+
# Handle disconnected components
60+
pos = {}
61+
x_offset = 0
62+
for component in nx.weakly_connected_components(G):
63+
subgraph = G.subgraph(component)
64+
root = next(iter(subgraph.nodes()))
65+
component_pos = _hierarchy_pos(subgraph, root=root, vert_gap=0.3, horiz_gap=3.0)
66+
67+
# Offset each component horizontally to avoid overlap
68+
for node, (x, y) in component_pos.items():
69+
pos[node] = (x + x_offset, y)
70+
71+
# Increment x_offset for next component
72+
if len(component_pos) > 0:
73+
x_offset += max(x for x, y in component_pos.values()) + 3
5774

58-
# Extract edge coordinates
75+
print(f"Positions: {pos}")
76+
77+
# Extract edge coordinates with hover text
5978
edge_x = []
6079
edge_y = []
80+
edge_text = []
6181
for edge in G.edges():
6282
print(f"Drawing edge: {edge}")
6383
if edge[0] in pos and edge[1] in pos:
6484
x0, y0 = pos[edge[0]]
6585
x1, y1 = pos[edge[1]]
86+
print(f" From ({x0}, {y0}) to ({x1}, {y1})")
6687
edge_x.extend([x0, x1, None])
6788
edge_y.extend([y0, y1, None])
89+
edge_text.extend([f"Node {edge[0]} → Node {edge[1]}", f"Node {edge[0]} → Node {edge[1]}", None])
6890
else:
91+
print(f" Edge position not found")
6992
edge_x.extend([1, 1, None])
7093
edge_y.extend([5, 5, None])
71-
94+
edge_text.extend([f"Node {edge[0]} → Node {edge[1]}", f"Node {edge[0]} → Node {edge[1]}", None])
95+
7296
# Extract node coordinates
7397
node_x = []
7498
node_y = []
75-
for node in G.nodes():
99+
node_list = list(G.nodes())
100+
for node in node_list:
76101
x, y = 1, 1
77102
if node in pos:
78103
x, y = pos[node]
104+
else:
105+
print(f"WARNING: Node {node} not in positions!")
79106
node_x.append(x)
80107
node_y.append(y)
81108

109+
print(f"Node coordinates: {list(zip(node_list, node_x, node_y))}")
110+
82111
# Create figure
83112
fig = go.Figure()
84113

85-
# Add edges
114+
# Add edges (visible lines)
86115
fig.add_trace(go.Scatter(
87116
x=edge_x, y=edge_y,
88117
mode='lines',
89118
line=dict(width=2, color='#888'),
90119
hoverinfo='none',
91120
showlegend=False
92121
))
122+
123+
# Add invisible thick edges for hover detection
124+
fig.add_trace(go.Scatter(
125+
x=edge_x, y=edge_y,
126+
mode='lines',
127+
line=dict(width=20, color='rgba(0,0,0,0)'),
128+
text=edge_text,
129+
hoverinfo='text',
130+
showlegend=False
131+
))
132+
93133
# Add nodes
94134
fig.add_trace(go.Scatter(
95135
x=node_x, y=node_y,
@@ -99,10 +139,10 @@ def visualize_cbs_tree(
99139
color=node_colors,
100140
line=dict(width=2, color='darkblue')
101141
),
102-
text=[node_labels[node] for node in G.nodes() if node in node_labels],
142+
text=[node_labels.get(node, f"Node {node}") for node in node_list],
103143
hoverinfo='text',
104144
showlegend=False,
105-
customdata=list(G.nodes())
145+
customdata=node_list
106146
))
107147

108148
fig.update_layout(
@@ -157,26 +197,33 @@ def visualize_cbs_tree(
157197
def _hierarchy_pos(G, root=None, vert_gap=0.2, horiz_gap=1.0, xcenter=0.5):
158198
"""
159199
Create hierarchical layout for tree visualization with fixed horizontal spacing.
200+
Spreads nodes wide at each level to avoid overlaps.
160201
"""
161202
if not nx.is_tree(G):
162203
G = nx.DiGraph(G)
163204

164-
def _hierarchy_pos_recursive(G, root, vert_gap=0.2, horiz_gap=1.0, xcenter=0.5, pos=None, parent=None, child_index=0):
205+
def _hierarchy_pos_recursive(G, root, vert_gap=0.2, horiz_gap=1.0, xcenter=0.5, pos=None, parent=None, child_index=0, level_nodes=None):
165206
if pos is None:
166207
pos = {root: (xcenter, 0)}
208+
level_nodes = {0: [root]}
167209
else:
210+
level = pos[parent][1] / (-vert_gap)
168211
pos[root] = (xcenter, pos[parent][1] - vert_gap)
212+
if int(level) + 1 not in level_nodes:
213+
level_nodes[int(level) + 1] = []
214+
level_nodes[int(level) + 1].append(root)
169215

170216
neighbors = list(G.neighbors(root))
171217

172218
if len(neighbors) != 0:
173219
num_children = len(neighbors)
174-
# Spread children horizontally with fixed gap
175-
start_x = xcenter - (num_children - 1) * horiz_gap / 2
220+
# Spread children very wide to avoid any overlap
221+
spread = num_children * horiz_gap * 2
222+
start_x = xcenter - spread / 2
176223
for i, neighbor in enumerate(neighbors):
177-
nextx = start_x + i * horiz_gap
224+
nextx = start_x + i * (spread / max(num_children - 1, 1))
178225
_hierarchy_pos_recursive(G, neighbor, vert_gap=vert_gap, horiz_gap=horiz_gap,
179-
xcenter=nextx, pos=pos, parent=root, child_index=i)
226+
xcenter=nextx, pos=pos, parent=root, child_index=i, level_nodes=level_nodes)
180227

181228
return pos
182229

0 commit comments

Comments
 (0)