ZahirJS commited on
Commit
e2d8c14
·
verified ·
1 Parent(s): 11561b8

Update process_flow_generator.py

Browse files
Files changed (1) hide show
  1. process_flow_generator.py +46 -53
process_flow_generator.py CHANGED
@@ -25,35 +25,39 @@ def generate_process_flow_diagram(json_input: str, base_color: str) -> str:
25
  "id": "step1",
26
  "label": "Gather Requirements",
27
  "type": "process",
28
- "relationship": "Next",
29
- "subnodes": [
30
- {"id": "step1_1", "label": "Define Scope", "type": "process", "relationship": "Then"}
31
- ]
32
  },
33
  {
34
  "id": "decision1",
35
  "label": "Is Data Available?",
36
  "type": "decision",
37
- "relationship": "Check",
38
- "subnodes": [
39
- {"id": "path_yes", "label": "Process Data", "type": "process", "relationship": "Yes"},
40
- {"id": "path_no", "label": "Collect More Data", "type": "process", "relationship": "No"}
41
- ]
 
 
 
 
 
 
 
 
42
  },
43
  {
44
  "id": "end_node",
45
  "label": "End Process",
46
- "type": "end",
47
- "relationship": "Concludes"
48
  }
49
  ],
50
  "connections": [
51
- {"from": "start_node", "to": "step1"},
52
- {"from": "step1", "to": "decision1"},
53
  {"from": "decision1", "to": "path_yes", "label": "Yes"},
54
  {"from": "decision1", "to": "path_no", "label": "No"},
55
- {"from": "path_yes", "to": "end_node"},
56
- {"from": "path_no", "to": "end_node"}
57
  ]
58
  }
59
  """
@@ -65,13 +69,13 @@ def generate_process_flow_diagram(json_input: str, base_color: str) -> str:
65
 
66
  # Determine specific node shapes for flowchart types
67
  node_shapes = {
68
- "process": "box",
69
- "decision": "diamond",
70
- "start": "Mrecord", # Rounded box for start/end
71
- "end": "Mrecord", # Rounded box for start/end
72
- "io": "parallelogram", # Input/Output
73
- "document": "note",
74
- "default": "box"
75
  }
76
 
77
  dot = graphviz.Digraph(
@@ -81,45 +85,41 @@ def generate_process_flow_diagram(json_input: str, base_color: str) -> str:
81
  'rankdir': 'TB', # Top-to-Bottom flow is common for flowcharts
82
  'splines': 'ortho', # Straight lines with 90-degree bends
83
  'bgcolor': 'white', # White background
84
- 'pad': '0.5' # Padding around the graph
85
- },
86
- node_attr={'style': 'filled,rounded', 'fontcolor': 'white', 'fontsize': '12'} # Default node style
 
87
  )
88
 
 
 
 
 
89
  # Add all nodes based on JSON structure
90
- all_nodes = {}
 
91
  if 'start_node' in data:
92
- all_nodes[data['start_node']] = {"label": data['start_node'], "type": "start"}
93
 
94
  for node_data in data.get('nodes', []):
95
- all_nodes[node_data['id']] = node_data
96
 
97
- # Add nodes with specific shapes and styles
98
- for node_id, node_info in all_nodes.items():
99
  node_type = node_info.get("type", "default")
100
  shape = node_shapes.get(node_type, "box") # Default to box if type is unknown
101
 
102
- # Calculate color for current node based on a simplified depth or fixed for process flow
103
- # For simplicity in process flow, let's keep the base color for all primary nodes for now,
104
- # or apply a subtle gradient if depth is truly defined in a meaningful way.
105
- # Here, we'll use the base_color for all nodes, making the color selection more direct.
106
-
107
- # Simple color lightening for sub-levels if 'subnodes' are used in a nested process
108
- # This logic mimics graph_generator_utils but is adapted for the specific flow structure
109
- # For a pure flowchart, often nodes are all the same color.
110
- # If you want gradient for subprocesses, the current_depth logic needs to be more robust for different node types.
111
-
112
- # Let's use base_color directly for all main nodes and only apply gradient for 'subnodes'
113
- # For now, we'll pass current_depth=0 to add_nodes_and_edges when called recursively
114
- # to ensure the main flow nodes are consistent.
115
 
116
  dot.node(
117
  node_id,
118
  node_info['label'],
119
  shape=shape,
120
- style='filled,rounded',
121
- fillcolor=base_color, # Use the selected base color
122
- fontcolor='white' if base_color == '#19191a' else 'black', # Adjust for readability
123
  fontsize='14'
124
  )
125
 
@@ -134,13 +134,6 @@ def generate_process_flow_diagram(json_input: str, base_color: str) -> str:
134
  fontsize='10'
135
  )
136
 
137
- # If there's a start_node, ensure it's visually marked
138
- if 'start_node' in data:
139
- dot.node(data['start_node'], data['start_node'], shape=node_shapes['start'], style='filled,rounded', fillcolor='#2196F3', fontcolor='white', fontsize='14')
140
- if 'end_node' in data and data['end_node'] in all_nodes:
141
- dot.node(data['end_node'], all_nodes[data['end_node']]['label'], shape=node_shapes['end'], style='filled,rounded', fillcolor='#F44336', fontcolor='white', fontsize='14')
142
-
143
-
144
  # Save to temporary file
145
  with NamedTemporaryFile(delete=False, suffix='.png') as tmp:
146
  dot.render(tmp.name, format='png', cleanup=True)
 
25
  "id": "step1",
26
  "label": "Gather Requirements",
27
  "type": "process",
28
+ "relationship": "Next"
 
 
 
29
  },
30
  {
31
  "id": "decision1",
32
  "label": "Is Data Available?",
33
  "type": "decision",
34
+ "relationship": "Check"
35
+ },
36
+ {
37
+ "id": "path_yes",
38
+ "label": "Process Data",
39
+ "type": "process",
40
+ "relationship": "Yes"
41
+ },
42
+ {
43
+ "id": "path_no",
44
+ "label": "Collect More Data",
45
+ "type": "process",
46
+ "relationship": "No"
47
  },
48
  {
49
  "id": "end_node",
50
  "label": "End Process",
51
+ "type": "end"
 
52
  }
53
  ],
54
  "connections": [
55
+ {"from": "start_node", "to": "step1", "label": "Start"},
56
+ {"from": "step1", "to": "decision1", "label": "Continue"},
57
  {"from": "decision1", "to": "path_yes", "label": "Yes"},
58
  {"from": "decision1", "to": "path_no", "label": "No"},
59
+ {"from": "path_yes", "to": "end_node", "label": "Done"},
60
+ {"from": "path_no", "to": "end_node", "label": "Done"}
61
  ]
62
  }
63
  """
 
69
 
70
  # Determine specific node shapes for flowchart types
71
  node_shapes = {
72
+ "process": "box", # Rectangle for processes
73
+ "decision": "diamond", # Diamond for decisions
74
+ "start": "oval", # Oval for start
75
+ "end": "oval", # Oval for end
76
+ "io": "parallelogram", # Input/Output
77
+ "document": "note", # Document symbol
78
+ "default": "box" # Fallback
79
  }
80
 
81
  dot = graphviz.Digraph(
 
85
  'rankdir': 'TB', # Top-to-Bottom flow is common for flowcharts
86
  'splines': 'ortho', # Straight lines with 90-degree bends
87
  'bgcolor': 'white', # White background
88
+ 'pad': '0.5', # Padding around the graph
89
+ 'nodesep': '0.6', # Spacing between nodes on same rank
90
+ 'ranksep': '0.8' # Spacing between ranks
91
+ }
92
  )
93
 
94
+ # Ensure base_color is valid, fallback if not
95
+ if not isinstance(base_color, str) or not base_color.startswith('#') or len(base_color) != 7:
96
+ base_color = '#19191a' # Fallback to default dark if invalid
97
+
98
  # Add all nodes based on JSON structure
99
+ all_nodes_data = {}
100
+ # Special handling for start_node if defined separately
101
  if 'start_node' in data:
102
+ all_nodes_data[data['start_node']] = {"label": data['start_node'], "type": "start"}
103
 
104
  for node_data in data.get('nodes', []):
105
+ all_nodes_data[node_data['id']] = node_data
106
 
107
+ for node_id, node_info in all_nodes_data.items():
 
108
  node_type = node_info.get("type", "default")
109
  shape = node_shapes.get(node_type, "box") # Default to box if type is unknown
110
 
111
+ # Use base_color for all nodes for consistent flowchart look
112
+ # You can adapt add_nodes_and_edges if you want color gradient per depth for flowcharts too
113
+ fill_color_for_node = base_color
114
+ font_color_for_node = 'white' if base_color == '#19191a' else 'black' # Keep text readable
 
 
 
 
 
 
 
 
 
115
 
116
  dot.node(
117
  node_id,
118
  node_info['label'],
119
  shape=shape,
120
+ style='filled,rounded', # Keep rounded corners
121
+ fillcolor=fill_color_for_node,
122
+ fontcolor=font_color_for_node,
123
  fontsize='14'
124
  )
125
 
 
134
  fontsize='10'
135
  )
136
 
 
 
 
 
 
 
 
137
  # Save to temporary file
138
  with NamedTemporaryFile(delete=False, suffix='.png') as tmp:
139
  dot.render(tmp.name, format='png', cleanup=True)