-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchartctl.py
executable file
·95 lines (75 loc) · 3.46 KB
/
chartctl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python3
import json
import argparse
import os
from graphviz import Digraph
def validate_json(config):
"""
Validate the structure of the JSON file.
Ensure it has "nodes" and "connectors" as top-level keys.
"""
if not isinstance(config, dict):
raise ValueError("JSON root must be an object (dictionary)")
if 'nodes' not in config:
raise ValueError('The JSON file must contain a "nodes" section.')
if not isinstance(config['nodes'], dict):
raise ValueError('"nodes" must be a dictionary of node definitions.')
if 'connectors' not in config:
raise ValueError('The JSON file must contain an "connectors" section.')
if not isinstance(config['connectors'], list):
raise ValueError('"connectors" must be a list of edge definitions.')
def generate_flowchart_from_json(config_file, output_file):
"""
Generate a flowchart based on the provided JSON configuration file.
"""
try:
# Check if the input file exists
if not os.path.isfile(config_file):
raise FileNotFoundError(f"The input file '{config_file}' does not exist.")
# Read and parse the JSON file
with open(config_file, 'r') as f:
config = json.load(f)
# Validate the structure of the JSON
validate_json(config)
except FileNotFoundError as fnf_error:
print(fnf_error)
return
except json.JSONDecodeError as json_error:
print(f"Error parsing JSON: {json_error}")
return
except ValueError as val_error:
print(f"Validation error: {val_error}")
return
except Exception as e:
print(f"An unexpected error occurred: {e}")
return
# Create a new directed graph for the flowchart
dot = Digraph(comment="Flowchart", format="png")
# Add nodes with optional shape, fillcolor, style, and color
if 'nodes' in config:
for node, attributes in config['nodes'].items():
label = attributes.get('label', node)
shape = attributes.get('shape', 'rectangle') # Default shape is rectangle if not specified
fillcolor = attributes.get('fillcolor', 'white') # Default fill color is white
style = attributes.get('style', 'solid') # Default style is solid
color = attributes.get('color', 'black') # Default border color is black
dot.node(node, label, shape=shape, fillcolor=fillcolor, style=style, color=color)
# Add connectors with optional labels and colors
if 'connectors' in config:
for edge in config['connectors']:
src = edge['from']
dst = edge['to']
label = edge.get('label', '') # Optional label
color = edge.get('color', 'black') # Default edge color is black
dot.edge(src, dst, label, color=color)
# Render the flowchart to the specified output file
dot.render(output_file)
print(f"Flowchart saved as {output_file}.png")
def main():
parser = argparse.ArgumentParser(description="Generate a flowchart from a JSON configuration file.")
parser.add_argument('-i', '--input', type=str, required=True, help='Path to the input JSON configuration file')
parser.add_argument('-o', '--output', type=str, default='flowchart', help='Path to save the output PNG file (without extension)')
args = parser.parse_args()
generate_flowchart_from_json(args.input, args.output)
if __name__ == "__main__":
main()