import streamlit as st import pandas as pd from graphviz import Digraph import os import base64 from io import StringIO # Configure system path for Hugging Face Spaces os.environ["PATH"] += os.pathsep + '/usr/bin/graphviz' # Enhanced 3D styling CSS st.markdown(""" """, unsafe_allow_html=True) def create_org_chart(df, title): """Create professional org chart with 3D effects""" dot = Digraph(comment=title) dot.attr(rankdir='TB', labelloc='t', label=title, fontsize='24', fontname='Arial', margin='0.5', splines='ortho', bgcolor='transparent') # 3D Node styling with gradient and shadow dot.attr('node', shape='box', style='filled,rounded', fillcolor='linear-gradient(45deg, #45a049 0%, #4CAF50 100%)', gradientangle='270', fontname='Arial', fontcolor='white', margin='0.4', width='2', height='0.9', fixedsize='false', fontsize='14', penwidth='0', color='#2c3e50') # Edge styling for 3D effect dot.attr('edge', color='#666666', arrowsize='0.8', penwidth='1.5', dir='forward') # Process relationships added_nodes = set() for _, row in df.iterrows(): parent = row['Parent'].strip() child = row['Child'].strip() if parent and child: if parent not in added_nodes: dot.node(parent, _attributes={'label': f'<{parent}>'}) added_nodes.add(parent) if child not in added_nodes: dot.node(child, _attributes={'label': f'<{child}>'}) added_nodes.add(child) dot.edge(parent, child) return dot def main(): st.title("🏢 3D Organization Chart Generator") with st.sidebar: st.header("⚙️ Configuration") chart_title = st.text_input("Chart Title", "Company Structure") st.markdown("---") st.markdown("### 📋 CSV Template") # CSV template download with 3D styling template = "Parent,Child\nCEO,CTO\nCEO,CFO\nCTO,Engineering Manager" b64 = base64.b64encode(template.encode()).decode() href = f''' 📥 Download Template ''' st.markdown(href, unsafe_allow_html=True) uploaded_file = st.file_uploader("📤 Upload CSV File", type=["csv"]) if uploaded_file: try: df = pd.read_csv(uploaded_file) if {'Parent', 'Child'}.issubset(df.columns): with st.spinner("🔍 Generating 3D visualization..."): chart = create_org_chart(df, chart_title) # Two-column layout col1, col2 = st.columns([3, 1]) with col1: st.graphviz_chart(chart, use_container_width=True) with col2: st.markdown("### 📤 Export Options") # PDF Export pdf_bytes = chart.pipe(format='pdf') st.download_button( label="📄 Download PDF", data=pdf_bytes, file_name=f"{chart_title.replace(' ', '_')}.pdf", mime="application/pdf", ) # PNG Export png_bytes = chart.pipe(format='png') st.download_button( label="🖼️ Download PNG", data=png_bytes, file_name=f"{chart_title.replace(' ', '_')}.png", mime="image/png", ) else: st.error("❌ CSV must contain 'Parent' and 'Child' columns") except Exception as e: st.error(f"🚨 Error processing file: {str(e)}") if __name__ == "__main__": main()