import dash from dash import html, dcc import plotly.express as px import pandas as pd import requests from dash.dependencies import Output, Input # إنشاء التطبيق app = dash.Dash(__name__) app.title = "Fas7ni Dashboard" # جلب البيانات def fetch_users(): try: url = "https://fas7nii.runasp.net/api/Analysis/GetDashboardAnalysis" res = requests.get(url) res.raise_for_status() data = res.json() return pd.DataFrame(data) except Exception as e: print("Error fetching users:", e) return pd.DataFrame(columns=["gender", "age", "languages"]) def fetch_feedback(): try: url = "https://fas7nii.runasp.net/api/Analysis/GetFeedbackAnalysis" res = requests.get(url) res.raise_for_status() data = res.json() return pd.DataFrame(data) except Exception as e: print("Error fetching feedback:", e) return pd.DataFrame(columns=["value"]) # تخطيط الواجهة app.layout = html.Div(style={ "backgroundColor": "#f4f7f9", "padding": "20px", "fontFamily": "Arial, sans-serif" }, children=[ html.H1("🌐 Fas7ni Dashboard", style={"textAlign": "center", "color": "#2c3e50"}), html.Div([ dcc.Graph(id='sentiment-pie', style={"width": "42%", "height": "300px", "margin": "10px", "minWidth": "300px"}), dcc.Graph(id='gender-bar', style={"width": "42%", "height": "300px", "margin": "10px", "minWidth": "300px"}), dcc.Graph(id='age-bar', style={"width": "42%", "height": "300px", "margin": "10px", "minWidth": "300px"}), dcc.Graph(id='language-bar', style={"width": "42%", "height": "300px", "margin": "10px", "minWidth": "300px"}), ], style={ "display": "flex", "flexWrap": "wrap", "justifyContent": "space-around", "alignItems": "center" }), dcc.Interval(id='interval-update', interval=10*1000, n_intervals=0) ]) # التحديث التلقائي @app.callback( Output('sentiment-pie', 'figure'), Output('gender-bar', 'figure'), Output('age-bar', 'figure'), Output('language-bar', 'figure'), Input('interval-update', 'n_intervals') ) def update_charts(n): df_users = fetch_users() df_feedback = fetch_feedback() colors = ['#3498db', '#9b59b6', '#2ecc71', '#f39c12', '#e74c3c'] # Pie chart - Sentiment if not df_feedback.empty: sentiment_counts = df_feedback["value"].value_counts().reset_index() sentiment_counts.columns = ["Sentiment", "Count"] fig_sentiment = px.pie(sentiment_counts, names="Sentiment", values="Count", title="Sentiment Distribution", hole=0.4, color_discrete_sequence=colors) fig_sentiment.update_traces(textinfo='percent+label') else: fig_sentiment = px.pie(title="No Feedback Data") # Bar chart - Gender if not df_users.empty and "gender" in df_users.columns: df_users["gender"] = df_users["gender"].fillna("Unknown") gender_counts = df_users["gender"].value_counts().reset_index() gender_counts.columns = ["Gender", "Count"] fig_gender = px.bar(gender_counts, x="Gender", y="Count", title="Gender Distribution", color="Gender", color_discrete_sequence=colors) else: fig_gender = px.bar(title="No Gender Data") # Line chart - Age Distribution if not df_users.empty and "age" in df_users.columns: df_users["age"] = pd.to_numeric(df_users["age"], errors='coerce') age_counts = df_users["age"].value_counts().sort_index().reset_index() age_counts.columns = ["Age", "Count"] fig_age = px.line(age_counts, x="Age", y="Count", title="Age Distribution", markers=True, color_discrete_sequence=colors) else: fig_age = px.line(title="No Age Data") # Bar chart - Languages if not df_users.empty and "languages" in df_users.columns: df_users["languages"] = df_users["languages"].apply(lambda x: x if isinstance(x, list) else ([] if pd.isna(x) else [x])) all_languages = df_users["languages"].explode() lang_counts = all_languages.value_counts().reset_index() lang_counts.columns = ["Language", "Count"] fig_lang = px.bar(lang_counts, x="Language", y="Count", title="Languages Used", color="Language", color_discrete_sequence=colors) else: fig_lang = px.bar(title="No Language Data") return fig_sentiment, fig_gender, fig_age, fig_lang # تشغيل التطبيق if __name__ == '__main__': app.run(host='0.0.0.0', port=7860, debug=True)