ZahirJS commited on
Commit
3a00e55
·
verified ·
1 Parent(s): 6637847

Update process_flow_generator.py

Browse files
Files changed (1) hide show
  1. process_flow_generator.py +87 -74
process_flow_generator.py CHANGED
@@ -2,9 +2,12 @@ import graphviz
2
  import json
3
  from tempfile import NamedTemporaryFile
4
  import os
5
- from graph_generator_utils import add_nodes_and_edges # Reusing common utility
6
 
7
- def generate_process_flow_diagram(json_input: str, base_color: str) -> str: # base_color is now correctly used
 
 
 
 
8
  """
9
  Generates a Process Flow Diagram (Flowchart) from JSON input.
10
 
@@ -19,45 +22,25 @@ def generate_process_flow_diagram(json_input: str, base_color: str) -> str: # ba
19
 
20
  Expected JSON Format Example:
21
  {
22
- "start_node": "Start Process",
23
  "nodes": [
24
- {
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": "Initiate"},
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
  """
@@ -67,8 +50,20 @@ def generate_process_flow_diagram(json_input: str, base_color: str) -> str: # ba
67
 
68
  data = json.loads(json_input)
69
 
70
- if 'central_node' not in data or 'nodes' not in data:
71
- raise ValueError("Missing required fields: central_node or nodes")
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
  dot = graphviz.Digraph(
74
  name='ProcessFlowDiagram',
@@ -83,48 +78,66 @@ def generate_process_flow_diagram(json_input: str, base_color: str) -> str: # ba
83
  }
84
  )
85
 
86
- # This line was REMOVED to ensure the passed base_color is used: base_color = '#19191a'
87
-
88
- # Determine specific node shapes for flowchart types
89
- node_shapes = {
90
- "process": "box", # Rectangle for processes
91
- "decision": "diamond", # Diamond for decisions
92
- "start": "oval", # Oval for start
93
- "end": "oval", # Oval for end
94
- "io": "parallelogram", # Input/Output
95
- "document": "note", # Document symbol
96
- "default": "box" # Fallback
97
- }
98
 
99
- # Add all nodes based on JSON structure
100
- all_nodes_data = {}
101
- # Special handling for start_node if defined separately
102
- if 'start_node' in data:
103
- all_nodes_data[data['start_node']] = {"label": data['start_node'], "type": "start"}
 
 
 
 
104
 
105
- for node_data in data.get('nodes', []):
106
- all_nodes_data[node_data['id']] = node_data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- for node_id, node_info in all_nodes_data.items():
109
  node_type = node_info.get("type", "default")
110
- shape = node_shapes.get(node_type, "box") # Default to box if type is unknown
111
 
112
- # Use base_color for all nodes for consistent flowchart look
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
 
126
  # Add connections (edges)
127
- for connection in data.get('connections', []):
128
  dot.edge(
129
  connection['from'],
130
  connection['to'],
 
2
  import json
3
  from tempfile import NamedTemporaryFile
4
  import os
 
5
 
6
+ # No longer importing add_nodes_and_edges from graph_generator_utils
7
+ # as process flow diagrams have a different structure and node addition logic.
8
+ # However, we'll re-implement the color gradient logic directly for consistency.
9
+
10
+ def generate_process_flow_diagram(json_input: str, base_color: str) -> str:
11
  """
12
  Generates a Process Flow Diagram (Flowchart) from JSON input.
13
 
 
22
 
23
  Expected JSON Format Example:
24
  {
25
+ "start_node": "Start Order Process",
26
  "nodes": [
27
+ {"id": "customer_order", "label": "Customer Places Order", "type": "process"},
28
+ {"id": "check_stock", "label": "Check Stock Availability", "type": "decision"},
29
+ {"id": "stock_available", "label": "Stock Available?", "type": "decision"},
30
+ {"id": "process_payment", "label": "Process Payment", "type": "process"},
31
+ {"id": "order_confirmed", "label": "Order Confirmed", "type": "process"},
32
+ {"id": "notify_customer_oos", "label": "Notify Customer (Out of Stock)", "type": "process"},
33
+ {"id": "end_order_process", "label": "End Order Process", "type": "end"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  ],
35
  "connections": [
36
+ {"from": "start_node", "to": "customer_order", "label": "Initiate"},
37
+ {"from": "customer_order", "to": "check_stock", "label": "Proceed"},
38
+ {"from": "check_stock", "to": "stock_available", "label": "Result"},
39
+ {"from": "stock_available", "to": "process_payment", "label": "Yes"},
40
+ {"from": "stock_available", "to": "notify_customer_oos", "label": "No"},
41
+ {"from": "process_payment", "to": "order_confirmed", "label": "Success"},
42
+ {"from": "order_confirmed", "to": "end_order_process", "label": "Complete"},
43
+ {"from": "notify_customer_oos", "to": "end_order_process", "label": "Finish"}
44
  ]
45
  }
46
  """
 
50
 
51
  data = json.loads(json_input)
52
 
53
+ # Validate required top-level keys for a flowchart
54
+ if 'start_node' not in data or 'nodes' not in data or 'connections' not in data:
55
+ raise ValueError("Missing required fields: 'start_node', 'nodes', or 'connections'")
56
+
57
+ # Define specific node shapes for flowchart types
58
+ node_shapes = {
59
+ "process": "box", # Rectangle for processes
60
+ "decision": "diamond", # Diamond for decisions
61
+ "start": "oval", # Oval for start
62
+ "end": "oval", # Oval for end
63
+ "io": "parallelogram", # Input/Output
64
+ "document": "note", # Document symbol
65
+ "default": "box" # Fallback
66
+ }
67
 
68
  dot = graphviz.Digraph(
69
  name='ProcessFlowDiagram',
 
78
  }
79
  )
80
 
81
+ # Ensure base_color is valid, fallback if not
82
+ if not isinstance(base_color, str) or not base_color.startswith('#') or len(base_color) != 7:
83
+ base_color = '#19191a' # Fallback to default dark if invalid
 
 
 
 
 
 
 
 
 
84
 
85
+ # Helper for color and font based on depth (simulated for flowcharts if needed, or consistent color)
86
+ # For flowcharts, often all process/decision nodes are the same color.
87
+ # If a gradient is desired, a 'depth' could be manually assigned or derived.
88
+ # For simplicity and typical flowchart appearance, we'll use a consistent base_color for all nodes.
89
+ fill_color_for_nodes = base_color
90
+ font_color_for_nodes = 'white' if base_color == '#19191a' or base_color.lower() in ['#000000', '#19191a'] else 'black'
91
+
92
+ # Store all nodes by ID for easy lookup
93
+ all_defined_nodes = {node['id']: node for node in data['nodes']}
94
 
95
+ # Add start node explicitly
96
+ start_node_id = data['start_node']
97
+ dot.node(
98
+ start_node_id,
99
+ start_node_id, # Label is typically the ID itself for start/end
100
+ shape=node_shapes['start'],
101
+ style='filled,rounded',
102
+ fillcolor='#2196F3', # A distinct blue for Start
103
+ fontcolor='white',
104
+ fontsize='14'
105
+ )
106
+
107
+ # Add all other nodes (process, decision, etc.)
108
+ for node_id, node_info in all_defined_nodes.items():
109
+ if node_id == start_node_id: # Skip if it's the start node, already added
110
+ continue
111
 
 
112
  node_type = node_info.get("type", "default")
113
+ shape = node_shapes.get(node_type, "box")
114
 
115
+ node_label = node_info['label']
 
 
116
 
117
+ # Use distinct color for end node if it exists
118
+ if node_type == 'end':
119
+ dot.node(
120
+ node_id,
121
+ node_label,
122
+ shape=shape,
123
+ style='filled,rounded',
124
+ fillcolor='#F44336', # A distinct red for End
125
+ fontcolor='white',
126
+ fontsize='14'
127
+ )
128
+ else: # Regular process, decision, etc. nodes use the selected base color
129
+ dot.node(
130
+ node_id,
131
+ node_label,
132
+ shape=shape,
133
+ style='filled,rounded',
134
+ fillcolor=fill_color_for_nodes,
135
+ fontcolor=font_color_for_nodes,
136
+ fontsize='14'
137
+ )
138
 
139
  # Add connections (edges)
140
+ for connection in data['connections']:
141
  dot.edge(
142
  connection['from'],
143
  connection['to'],