prakharg24 commited on
Commit
ce9a7cc
·
verified ·
1 Parent(s): 2a198b1

Update my_pages/multiverse.py

Browse files
Files changed (1) hide show
  1. my_pages/multiverse.py +72 -32
my_pages/multiverse.py CHANGED
@@ -1,77 +1,115 @@
 
1
  import streamlit as st
2
  import plotly.graph_objects as go
3
  from utils import development_stages
4
 
5
- def build_tree_edges_and_path(selected_path):
6
- edges = []
 
 
 
 
7
  node_labels = ["Start"]
8
- node_positions = [(0, 0)]
9
  node_stage = [0]
10
- node_index_map = {(0, "Start"): 0} # (stage_idx, label) → index
11
 
12
- prev_nodes = [0] # start node
13
- stage_nodes_map = {} # stage_idx → [node indices]
14
 
15
- # Build all nodes and edges
16
  for stage_idx, stage in enumerate(development_stages, start=1):
17
  options = stage["questions"]
18
- stage_nodes_map[stage_idx] = []
 
 
19
  for parent_idx in prev_nodes:
20
  px, py = node_positions[parent_idx]
 
 
21
  for opt_idx, opt in enumerate(options):
22
- child_x = stage_idx
23
- child_y = py + (opt_idx - len(options) / 2) * (1.5 / (stage_idx))
 
 
24
  node_index = len(node_labels)
25
  node_labels.append(opt)
26
  node_positions.append((child_x, child_y))
27
  node_stage.append(stage_idx)
28
- node_index_map[(stage_idx, opt)] = node_index
29
  edges.append((parent_idx, node_index))
30
- stage_nodes_map[stage_idx].append(node_index)
31
- prev_nodes = stage_nodes_map[stage_idx]
32
 
33
- # Determine the exact path
 
 
 
34
  highlight_edges = set()
35
- highlight_nodes = set([0]) # start node always highlighted
36
  current_node = 0
37
- for stage_idx, choice in enumerate(selected_path, start=1):
38
- if (stage_idx, choice) in node_index_map:
39
- child_node = node_index_map[(stage_idx, choice)]
40
- highlight_edges.add((current_node, child_node))
41
- highlight_nodes.add(child_node)
42
- current_node = child_node
43
- else:
44
- break # choice not found — stop path
 
 
 
 
 
 
 
 
45
 
46
  return node_labels, node_positions, edges, highlight_edges, highlight_nodes
47
 
 
48
  def render():
49
- st.title("Multiverse of Developer Decisions - Tree View")
50
 
51
- # User selection for each stage
52
  selected_path = []
53
  for stage in development_stages:
54
- choice = st.selectbox(f"{stage['icon']} {stage['label']}", stage["questions"], key=stage["label"])
 
 
55
  selected_path.append(choice)
56
 
57
- labels, positions, edges, highlight_edges, highlight_nodes = build_tree_edges_and_path(selected_path)
 
58
 
 
59
  x_vals = [pos[0] for pos in positions]
60
  y_vals = [pos[1] for pos in positions]
61
- node_colors = ["green" if i in highlight_nodes else "skyblue" for i in range(len(labels))]
 
 
 
 
 
 
 
 
62
 
63
  node_trace = go.Scatter(
64
  x=x_vals, y=y_vals,
65
  mode='markers+text',
66
  text=labels,
67
  textposition="top center",
68
- marker=dict(size=20, color=node_colors, line=dict(width=2, color='black'))
 
69
  )
70
 
71
  edge_traces = []
72
  for src, dst in edges:
73
- color = 'green' if (src, dst) in highlight_edges else 'gray'
74
- width = 3 if (src, dst) in highlight_edges else 1.5
 
 
 
 
75
  edge_traces.append(go.Scatter(
76
  x=[positions[src][0], positions[dst][0]],
77
  y=[positions[src][1], positions[dst][1]],
@@ -80,13 +118,15 @@ def render():
80
  hoverinfo='none'
81
  ))
82
 
 
83
  fig = go.Figure(data=edge_traces + [node_trace])
84
  fig.update_layout(
85
  showlegend=False,
86
  xaxis=dict(visible=False),
87
  yaxis=dict(visible=False),
88
  plot_bgcolor='white',
89
- margin=dict(l=0, r=0, t=0, b=0)
 
90
  )
91
 
92
  st.plotly_chart(fig, use_container_width=True)
 
1
+ # pages/multiverse.py
2
  import streamlit as st
3
  import plotly.graph_objects as go
4
  from utils import development_stages
5
 
6
+ def build_tree_and_trace_path(selected_path):
7
+ """
8
+ Build tree nodes and edges. Then trace selected_path (one choice per stage)
9
+ by walking children of the current node to find the matching label at each stage.
10
+ Returns: node_labels, node_positions, edges, highlight_edges, highlight_nodes
11
+ """
12
  node_labels = ["Start"]
13
+ node_positions = [(0.0, 0.0)]
14
  node_stage = [0]
15
+ edges = []
16
 
17
+ prev_nodes = [0] # nodes at previous stage (start)
18
+ y_spacing_base = 1.0
19
 
20
+ # Build nodes and edges stage by stage
21
  for stage_idx, stage in enumerate(development_stages, start=1):
22
  options = stage["questions"]
23
+ next_nodes = []
24
+
25
+ # For layout niceness: compute a span for children under each parent
26
  for parent_idx in prev_nodes:
27
  px, py = node_positions[parent_idx]
28
+ # Spread children vertically around the parent's y
29
+ span = max(1, len(options))
30
  for opt_idx, opt in enumerate(options):
31
+ child_x = float(stage_idx)
32
+ # center children around px, offset by opt_idx
33
+ offset = (opt_idx - (len(options) - 1) / 2.0) * (y_spacing_base / (stage_idx))
34
+ child_y = py + offset
35
  node_index = len(node_labels)
36
  node_labels.append(opt)
37
  node_positions.append((child_x, child_y))
38
  node_stage.append(stage_idx)
 
39
  edges.append((parent_idx, node_index))
40
+ next_nodes.append(node_index)
 
41
 
42
+ # After all parents, the next stage's parents are all next_nodes
43
+ prev_nodes = next_nodes
44
+
45
+ # Trace the single chosen path by walking children
46
  highlight_edges = set()
47
+ highlight_nodes = set([0])
48
  current_node = 0
49
+
50
+ for stage_idx, chosen_label in enumerate(selected_path, start=1):
51
+ # children of current_node
52
+ children = [dst for (src, dst) in edges if src == current_node]
53
+ # find a child among these whose label equals chosen_label
54
+ found_child = None
55
+ for c in children:
56
+ if node_labels[c] == chosen_label:
57
+ found_child = c
58
+ break
59
+ if found_child is None:
60
+ # chosen label not found under this parent — stop tracing
61
+ break
62
+ highlight_edges.add((current_node, found_child))
63
+ highlight_nodes.add(found_child)
64
+ current_node = found_child
65
 
66
  return node_labels, node_positions, edges, highlight_edges, highlight_nodes
67
 
68
+
69
  def render():
70
+ st.title("Multiverse of Developer Decisions Tree View")
71
 
72
+ # --- User picks one choice per stage via dropdowns ---
73
  selected_path = []
74
  for stage in development_stages:
75
+ # use a stable key per stage to avoid conflicts
76
+ key = f"multiverse_choice_{stage['label']}"
77
+ choice = st.selectbox(f"{stage['icon']} {stage['label']}", stage["questions"], key=key)
78
  selected_path.append(choice)
79
 
80
+ # --- Build tree and compute which edges/nodes to highlight ---
81
+ labels, positions, edges, highlight_edges, highlight_nodes = build_tree_and_trace_path(selected_path)
82
 
83
+ # --- Prepare node and edge traces for Plotly ---
84
  x_vals = [pos[0] for pos in positions]
85
  y_vals = [pos[1] for pos in positions]
86
+
87
+ node_colors = []
88
+ for idx in range(len(labels)):
89
+ if idx in highlight_nodes:
90
+ node_colors.append("rgba(34,139,34,0.95)") # green for selected path nodes
91
+ elif idx == 0:
92
+ node_colors.append("rgba(30,144,255,0.9)") # start node distinct
93
+ else:
94
+ node_colors.append("rgba(135,206,250,0.6)") # default skyblue
95
 
96
  node_trace = go.Scatter(
97
  x=x_vals, y=y_vals,
98
  mode='markers+text',
99
  text=labels,
100
  textposition="top center",
101
+ marker=dict(size=18, color=node_colors, line=dict(width=1, color='black')),
102
+ hoverinfo="text"
103
  )
104
 
105
  edge_traces = []
106
  for src, dst in edges:
107
+ if (src, dst) in highlight_edges:
108
+ color = "rgba(0,128,0,0.9)" # bright green
109
+ width = 4
110
+ else:
111
+ color = "rgba(120,120,120,0.4)"
112
+ width = 1.5
113
  edge_traces.append(go.Scatter(
114
  x=[positions[src][0], positions[dst][0]],
115
  y=[positions[src][1], positions[dst][1]],
 
118
  hoverinfo='none'
119
  ))
120
 
121
+ # --- Render figure ---
122
  fig = go.Figure(data=edge_traces + [node_trace])
123
  fig.update_layout(
124
  showlegend=False,
125
  xaxis=dict(visible=False),
126
  yaxis=dict(visible=False),
127
  plot_bgcolor='white',
128
+ margin=dict(l=10, r=10, t=10, b=10),
129
+ hovermode="closest"
130
  )
131
 
132
  st.plotly_chart(fig, use_container_width=True)