arif670 commited on
Commit
5d2ac6d
·
verified ·
1 Parent(s): acf542a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +165 -60
app.py CHANGED
@@ -1,76 +1,181 @@
1
  import streamlit as st
2
- from graphviz import Digraph
3
- import re
 
 
4
 
5
- def create_org_chart(data, direction='TB'):
6
- """Create organization chart using Graphviz"""
7
- dot = Digraph(comment='Organization Chart', format='png')
8
- dot.attr(rankdir=direction)
9
-
10
- # Track all added nodes to prevent duplicates
11
- added_nodes = set()
12
-
13
- # Add relationships
14
- for line in data:
15
- if ':' in line:
16
- parent, children = line.split(':', 1)
17
- parent = parent.strip()
18
- children = [child.strip() for child in children.split(',') if child.strip()]
19
-
20
- # Add parent node if not exists
21
- if parent and parent not in added_nodes:
22
- dot.node(parent)
23
- added_nodes.add(parent)
24
-
25
- # Add children and relationships
26
- for child in children:
27
- if child and child not in added_nodes:
28
- dot.node(child)
29
- added_nodes.add(child)
30
- if parent and child:
31
- dot.edge(parent, child)
32
-
33
- return dot
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  def main():
36
- st.title("Organization Chart Generator")
37
- st.markdown("### Enter your organizational hierarchy")
 
 
 
 
 
38
 
39
- # Input format explanation
40
- with st.expander("How to format your input"):
41
  st.markdown("""
42
- **Format:**
43
- `Parent Position: Child1, Child2, ...`
44
-
45
- **Example:**
46
- ```
47
- CEO: CTO, CFO, CMO
48
- CTO: Engineering Manager, QA Manager
49
- CFO: Accounting Manager, Tax Specialist
50
- Engineering Manager: Senior Developer, Junior Developer
51
- ```
52
  """)
53
 
54
- # User input
55
- direction = st.selectbox('Chart Direction',
56
- ('Top-Bottom (TB)', 'Left-Right (LR)'),
57
- index=0).split(' ')[0]
 
 
 
 
 
 
58
 
59
- input_data = st.text_area("Enter your organizational structure",
60
- height=300,
61
- value="CEO: CTO, CFO\nCTO: Engineering Manager\nCFO: Accounting Manager")
62
 
63
- # Process input
64
  if st.button('Generate Organization Chart'):
65
- if input_data:
66
- # Split and clean input
67
- lines = [line.strip() for line in input_data.split('\n') if line.strip()]
68
 
69
- # Create chart
70
- chart = create_org_chart(lines, direction)
 
 
 
 
 
71
 
72
- # Display chart
73
- st.graphviz_chart(chart)
 
 
 
 
 
 
 
 
 
74
  else:
75
  st.warning("Please enter some organizational data first")
76
 
 
1
  import streamlit as st
2
+ import pandas as pd
3
+ import plotly.graph_objects as go
4
+ import base64
5
+ from io import StringIO
6
 
7
+ # Custom CSS for modern UI
8
+ st.markdown("""
9
+ <style>
10
+ .stTextInput>div>div>input, .stTextArea>div>div>textarea {
11
+ background-color: #f0f2f6;
12
+ border-radius: 8px;
13
+ padding: 12px;
14
+ }
15
+ .stButton>button {
16
+ background-color: #4CAF50;
17
+ color: white;
18
+ border-radius: 8px;
19
+ padding: 10px 24px;
20
+ border: none;
21
+ font-size: 16px;
22
+ }
23
+ .stDownloadButton>button {
24
+ background-color: #008CBA;
25
+ color: white;
26
+ border-radius: 8px;
27
+ padding: 10px 24px;
28
+ border: none;
29
+ font-size: 16px;
30
+ }
31
+ .stSelectbox>div>div>select {
32
+ background-color: #f0f2f6;
33
+ border-radius: 8px;
34
+ padding: 8px;
35
+ }
36
+ </style>
37
+ """, unsafe_allow_html=True)
38
+
39
+ def create_org_chart(df, title, direction='TB'):
40
+ positions = {}
41
+ edge_x = []
42
+ edge_y = []
43
+ node_x = []
44
+ node_y = []
45
+ node_text = []
46
+
47
+ # Create hierarchical positions
48
+ levels = {}
49
+ for _, row in df.iterrows():
50
+ parent = row['Parent']
51
+ child = row['Child']
52
+ if parent not in levels:
53
+ levels[parent] = 0
54
+ if child not in levels:
55
+ levels[child] = levels[parent] + 1
56
+
57
+ # Assign coordinates
58
+ max_level = max(levels.values())
59
+ level_positions = {level: [] for level in range(max_level + 1)}
60
+
61
+ for node, level in levels.items():
62
+ level_positions[level].append(node)
63
+
64
+ for level, nodes in level_positions.items():
65
+ y_pos = max_level - level
66
+ x_positions = [i - (len(nodes)-1)/2 for i in range(len(nodes))]
67
+ for node, x_pos in zip(nodes, x_positions):
68
+ positions[node] = (x_pos, y_pos)
69
+
70
+ # Create edges
71
+ for _, row in df.iterrows():
72
+ parent = row['Parent']
73
+ child = row['Child']
74
+ x0, y0 = positions[parent]
75
+ x1, y1 = positions[child]
76
+ edge_x.extend([x0, x1, None])
77
+ edge_y.extend([y0, y1, None])
78
+
79
+ # Create nodes
80
+ for node, (x, y) in positions.items():
81
+ node_x.append(x)
82
+ node_y.append(y)
83
+ node_text.append(node)
84
+
85
+ # Create 3D effect
86
+ edge_trace = go.Scatter(
87
+ x=edge_x, y=edge_y,
88
+ line=dict(width=2, color='#888'),
89
+ hoverinfo='none',
90
+ mode='lines')
91
+
92
+ node_trace = go.Scatter(
93
+ x=node_x, y=node_y,
94
+ mode='markers+text',
95
+ text=node_text,
96
+ textposition="top center",
97
+ marker=dict(
98
+ symbol='square',
99
+ size=[100]*len(node_x),
100
+ color='#4CAF50',
101
+ line=dict(width=2, color='DarkSlateGrey')
102
+ ),
103
+ hoverinfo='text',
104
+ textfont=dict(size=14, color='white')
105
+ )
106
+
107
+ fig = go.Figure(data=[edge_trace, node_trace],
108
+ layout=go.Layout(
109
+ title=f'<b>{title}</b><br>',
110
+ titlefont_size=24,
111
+ showlegend=False,
112
+ hovermode='closest',
113
+ margin=dict(b=20,l=5,r=5,t=40),
114
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
115
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
116
+ )
117
+
118
+ return fig
119
 
120
  def main():
121
+ st.title("Professional Organization Chart Generator")
122
+
123
+ # Title input
124
+ chart_title = st.text_input("Enter Chart Title", "Organization Chart")
125
+
126
+ # File upload
127
+ uploaded_file = st.file_uploader("Upload CSV File", type=["csv"])
128
 
129
+ # Input format
130
+ with st.expander("CSV Format Instructions"):
131
  st.markdown("""
132
+ **CSV Format:**
133
+ Parent,Child
134
+ CEO,CTO
135
+ CEO,CFO
136
+ CTO,Engineering Manager
137
+ CFO,Accounting Manager
 
 
 
 
138
  """)
139
 
140
+ # Input data
141
+ if uploaded_file:
142
+ df = pd.read_csv(uploaded_file)
143
+ else:
144
+ default_data = """Parent,Child
145
+ CEO,CTO
146
+ CEO,CFO
147
+ CTO,Engineering Manager
148
+ CFO,Accounting Manager"""
149
+ df = pd.read_csv(StringIO(default_data))
150
 
151
+ # Show editable dataframe
152
+ edited_df = st.experimental_data_editor(df, num_rows="dynamic")
 
153
 
154
+ # Generate chart
155
  if st.button('Generate Organization Chart'):
156
+ if not edited_df.empty:
157
+ fig = create_org_chart(edited_df, chart_title)
158
+ st.plotly_chart(fig, use_container_width=True)
159
 
160
+ # PDF download options
161
+ st.subheader("Download Options")
162
+ col1, col2 = st.columns(2)
163
+ with col1:
164
+ orientation = st.selectbox("PDF Orientation", ["Portrait", "Landscape"])
165
+ with col2:
166
+ paper_size = st.selectbox("Paper Size", ["A4", "Letter", "Legal"])
167
 
168
+ # Convert to PDF
169
+ if st.button("Download as PDF"):
170
+ img_bytes = fig.to_image(format="pdf",
171
+ width=800 if orientation == "Portrait" else 1200,
172
+ height=1200 if orientation == "Portrait" else 800)
173
+ st.download_button(
174
+ label="Download PDF",
175
+ data=img_bytes,
176
+ file_name="org_chart.pdf",
177
+ mime="application/pdf"
178
+ )
179
  else:
180
  st.warning("Please enter some organizational data first")
181