Esmaeilkianii commited on
Commit
8b94103
·
verified ·
1 Parent(s): d80c68b

Update dashboard.py

Browse files
Files changed (1) hide show
  1. dashboard.py +93 -559
dashboard.py CHANGED
@@ -1,565 +1,99 @@
1
  import streamlit as st
2
  import pandas as pd
3
- import plotly.graph_objects as go
4
  import plotly.express as px
5
- import numpy as np
6
- from plotly.subplots import make_subplots
7
 
8
- # تنظیمات صفحه
9
- st.set_page_config(
10
- page_title="داشبورد تحلیلی نیشکر",
11
- page_icon="🌾",
12
- layout="wide"
13
- )
14
-
15
- # استایل سفارشی
16
- st.markdown("""
17
- <style>
18
- @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
19
- @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css');
20
- @import url('https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css');
21
-
22
- .main {
23
- font-family: 'Vazirmatn', sans-serif;
24
- background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
25
- }
26
-
27
- /* Header with animation */
28
- .header {
29
- background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%);
30
- color: white;
31
- padding: 20px;
32
- border-radius: 15px;
33
- margin-bottom: 20px;
34
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
35
- text-align: center;
36
- position: relative;
37
- overflow: hidden;
38
- animation: fadeIn 0.8s ease-in-out;
39
- }
40
-
41
- .header::before {
42
- content: '';
43
- position: absolute;
44
- top: -50%;
45
- left: -50%;
46
- width: 200%;
47
- height: 200%;
48
- background: linear-gradient(45deg, transparent, rgba(255,255,255,0.1), transparent);
49
- transform: rotate(45deg);
50
- animation: shine 3s infinite linear;
51
- }
52
-
53
- .header h1 {
54
- margin: 0;
55
- font-size: 2.5em;
56
- font-weight: 900;
57
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
58
- animation: bounceIn 1s ease-in-out;
59
- }
60
-
61
- .card {
62
- background-color: #ffffff;
63
- border-radius: 15px;
64
- padding: 25px;
65
- box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
66
- margin: 15px 0;
67
- transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
68
- border: 1px solid rgba(0, 0, 0, 0.05);
69
- animation: fadeIn 0.6s ease-in-out;
70
- }
71
-
72
- .card:hover {
73
- transform: translateY(-10px);
74
- box-shadow: 0 15px 30px rgba(0, 0, 0, 0.12);
75
- }
76
-
77
- .metric-card {
78
- background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
79
- color: white;
80
- border-radius: 15px;
81
- padding: 25px;
82
- margin: 15px 0;
83
- text-align: center;
84
- position: relative;
85
- overflow: hidden;
86
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
87
- transition: all 0.5s ease;
88
- animation: bounceIn 0.8s ease-in-out;
89
- }
90
-
91
- .metric-card::after {
92
- content: '';
93
- position: absolute;
94
- bottom: 0;
95
- left: 0;
96
- width: 100%;
97
- height: 5px;
98
- background: linear-gradient(to right, #43cea2, #185a9d);
99
- }
100
-
101
- .metric-card:hover {
102
- transform: translateY(-5px) scale(1.02);
103
- box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
104
- }
105
-
106
- .metric-card h3 {
107
- font-size: 1.2em;
108
- opacity: 0.9;
109
- margin-bottom: 10px;
110
- font-weight: 500;
111
- }
112
-
113
- .metric-card h2 {
114
- font-size: 2.5em;
115
- font-weight: 900;
116
- margin: 0;
117
- padding: 0;
118
- line-height: 1;
119
- }
120
-
121
- .metric-card i {
122
- font-size: 2em;
123
- margin-bottom: 15px;
124
- display: block;
125
- opacity: 0.8;
126
- }
127
-
128
- .chart-container {
129
- background-color: #ffffff;
130
- border-radius: 15px;
131
- padding: 25px;
132
- margin: 20px 0;
133
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08);
134
- transition: all 0.3s ease;
135
- animation: fadeIn 0.8s ease-in-out;
136
- position: relative;
137
- border: 1px solid rgba(0, 0, 0, 0.05);
138
- }
139
-
140
- .chart-container:hover {
141
- transform: translateY(-5px);
142
- box-shadow: 0 15px 30px rgba(0, 0, 0, 0.12);
143
- }
144
-
145
- .chart-container h3 {
146
- color: #185a9d;
147
- font-weight: 700;
148
- margin-bottom: 20px;
149
- font-size: 1.5em;
150
- padding-bottom: 10px;
151
- border-bottom: 3px solid #43cea2;
152
- display: inline-block;
153
- }
154
-
155
- /* Animation keyframes */
156
- @keyframes fadeIn {
157
- from { opacity: 0; }
158
- to { opacity: 1; }
159
- }
160
-
161
- @keyframes bounceIn {
162
- 0% {
163
- opacity: 0;
164
- transform: scale(0.3);
165
- }
166
- 50% {
167
- opacity: 1;
168
- transform: scale(1.05);
169
- }
170
- 70% { transform: scale(0.9); }
171
- 100% { transform: scale(1); }
172
- }
173
-
174
- @keyframes shine {
175
- 0% {
176
- left: -100%;
177
- opacity: 0;
178
- }
179
- 100% {
180
- left: 100%;
181
- opacity: 0.3;
182
- }
183
- }
184
-
185
- /* Filter panel styling */
186
- .filter-container {
187
- background: #f8f9fa;
188
- border-radius: 15px;
189
- padding: 20px;
190
- margin-bottom: 20px;
191
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
192
- border: 1px solid rgba(0, 0, 0, 0.05);
193
- animation: fadeIn 0.6s ease-in-out;
194
- }
195
-
196
- /* Custom button styling */
197
- .custom-button {
198
- display: inline-block;
199
- background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%);
200
- color: white;
201
- padding: 10px 20px;
202
- border-radius: 8px;
203
- font-weight: 600;
204
- text-align: center;
205
- cursor: pointer;
206
- transition: all 0.3s ease;
207
- border: none;
208
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
209
- text-decoration: none;
210
- }
211
-
212
- .custom-button:hover {
213
- transform: translateY(-3px);
214
- box-shadow: 0 7px 14px rgba(0, 0, 0, 0.15);
215
- }
216
-
217
- .custom-button:active {
218
- transform: translateY(0);
219
- }
220
- </style>
221
- """, unsafe_allow_html=True)
222
-
223
- # هدر جدید با انیمیشن
224
- st.markdown("""
225
- <div class="header">
226
- <h1>🌾 داشبورد تحلیلی نیشکر</h1>
227
- <p style="margin-top: 10px; font-size: 1.2em; opacity: 0.9;">سیستم هوشمند مدیریت و پایش مزارع نیشکر</p>
228
- </div>
229
- """, unsafe_allow_html=True)
230
-
231
- # پنل فیلتر
232
- st.markdown("""
233
- <div class="filter-container">
234
- <h3 style="color: #185a9d; margin-bottom: 15px; font-size: 1.3em;">فیلترها</h3>
235
- </div>
236
- """, unsafe_allow_html=True)
237
- col_filter1, col_filter2, col_filter3 = st.columns(3)
238
-
239
- with col_filter1:
240
- variate_filter = st.selectbox("انتخاب واریته", ["همه", "CP69", "CP73", "CP48", "CP57", "CP65", "CP70", "IR01-412", "IRC99-07", "IRC00-14"])
241
-
242
- with col_filter2:
243
- department_filter = st.selectbox("انتخاب اداره", ["همه", "اداره یک", "اداره دو", "اداره سه", "اداره چهار"])
244
-
245
- with col_filter3:
246
- age_filter = st.selectbox("انتخاب سن", ["همه", "1", "2", "3", "4", "5", "6", "7", "8", "9"])
247
-
248
- # خواندن داده‌ها
249
- @st.cache_data
250
- def load_data():
251
- df = pd.read_csv('محاسبات 2.csv')
252
- return df
253
-
254
- df = load_data()
255
-
256
- # ایجاد کارت‌های متریک با آیکون و انیمیشن
257
- col1, col2, col3, col4 = st.columns(4)
258
-
259
- with col1:
260
- st.markdown("""
261
- <div class="metric-card">
262
- <i class="fas fa-chart-area"></i>
263
- <h3>کل مساحت (هکتار)</h3>
264
- <h2>9,421.30</h2>
265
- </div>
266
- """, unsafe_allow_html=True)
267
-
268
- with col2:
269
- st.markdown("""
270
- <div class="metric-card">
271
- <i class="fas fa-seedling"></i>
272
- <h3>تعداد واریته‌ها</h3>
273
- <h2>9</h2>
274
- </div>
275
- """, unsafe_allow_html=True)
276
-
277
- with col3:
278
- st.markdown("""
279
- <div class="metric-card">
280
- <i class="fas fa-building"></i>
281
- <h3>تعداد ادارات</h3>
282
- <h2>4</h2>
283
- </div>
284
- """, unsafe_allow_html=True)
285
-
286
- with col4:
287
- st.markdown("""
288
- <div class="metric-card">
289
- <i class="fas fa-calendar-alt"></i>
290
- <h3>تعداد سن‌ها</h3>
291
- <h2>9</h2>
292
- </div>
293
- """, unsafe_allow_html=True)
294
-
295
- # نمودار سه بعدی مساحت به تفکیک اداره، سن و واریته
296
- st.markdown("""
297
- <div class="chart-container">
298
- <h3>نمودار سه بعدی مساحت به تفکیک اداره، سن و واریته</h3>
299
- <p style="color: #666; margin-bottom: 20px;">این نمودار نمایش تعاملی از توزیع مساحت مزارع را بر اساس سه پارامتر اداره، سن و واریته نشان می‌دهد.</p>
300
- </div>
301
- """, unsafe_allow_html=True)
302
-
303
- # پردازش داده‌ها برای نمودار سه بعدی
304
- def prepare_3d_data(df):
305
- # تبدیل داده‌ها به فرمت مناسب برای نمودار سه بعدی
306
- data = []
307
- for _, row in df.iterrows():
308
- if row['اداره'] != 'Grand Total' and row['سن'] != 'total':
309
- for col in ['CP69', 'CP73', 'CP48', 'CP57', 'CP65', 'CP70', 'IR01-412', 'IRC99-07', 'IRC00-14']:
310
- if pd.notna(row[col]) and row[col] != 0:
311
- data.append({
312
- 'اداره': row['اداره'],
313
- 'سن': row['سن'],
314
- 'واریته': col,
315
- 'مساحت': row[col]
316
- })
317
- return pd.DataFrame(data)
318
-
319
- df_3d = prepare_3d_data(df)
320
-
321
- # ایجاد نمودار سه بعدی بهبود یافته
322
- fig = go.Figure(data=[go.Scatter3d(
323
- x=df_3d['اداره'],
324
- y=df_3d['سن'],
325
- z=df_3d['مساحت'],
326
- mode='markers',
327
- marker=dict(
328
- size=df_3d['مساحت']/10,
329
- color=df_3d['مساحت'],
330
- colorscale='Viridis',
331
- opacity=0.8,
332
- colorbar=dict(title="مساحت (هکتار)"),
333
- symbol='circle'
334
- ),
335
- text=df_3d['واریته'],
336
- hovertemplate="اداره: %{x}<br>سن: %{y}<br>مساحت: %{z:.2f} هکتار<br>واریته: %{text}<extra></extra>"
337
- )])
338
-
339
- fig.update_layout(
340
- scene = dict(
341
- xaxis_title=dict(text="اداره", font=dict(size=14, family="Vazirmatn")),
342
- yaxis_title=dict(text="سن", font=dict(size=14, family="Vazirmatn")),
343
- zaxis_title=dict(text="مساحت (هکتار)", font=dict(size=14, family="Vazirmatn")),
344
- xaxis=dict(backgroundcolor="rgba(230, 230, 230, 0.3)"),
345
- yaxis=dict(backgroundcolor="rgba(230, 230, 230, 0.3)"),
346
- zaxis=dict(backgroundcolor="rgba(230, 230, 230, 0.3)")
347
- ),
348
- margin=dict(l=0, r=0, b=0, t=30),
349
- height=600,
350
- scene_camera=dict(
351
- eye=dict(x=1.5, y=1.5, z=1.2)
352
- ),
353
- font=dict(family="Vazirmatn"),
354
- paper_bgcolor='rgba(0,0,0,0)',
355
- plot_bgcolor='rgba(0,0,0,0)'
356
- )
357
-
358
- st.plotly_chart(fig, use_container_width=True)
359
-
360
- # دکمه‌های تعاملی برای تغییر نمای نمودار
361
- col_btn1, col_btn2, col_btn3 = st.columns(3)
362
- with col_btn1:
363
- st.markdown("""
364
- <div class="custom-button" onclick="Plotly.relayout('_plotly_graph_0',
365
- {'scene.camera.eye': {'x': 1.5, 'y': 1.5, 'z': 1.2}})">
366
- نمای استاندارد
367
- </div>
368
- """, unsafe_allow_html=True)
369
- with col_btn2:
370
- st.markdown("""
371
- <div class="custom-button" onclick="Plotly.relayout('_plotly_graph_0',
372
- {'scene.camera.eye': {'x': 0, 'y': 2.5, 'z': 0.1}})">
373
- نمای از بالا
374
- </div>
375
- """, unsafe_allow_html=True)
376
- with col_btn3:
377
- st.markdown("""
378
- <div class="custom-button" onclick="Plotly.relayout('_plotly_graph_0',
379
- {'scene.camera.eye': {'x': 2.5, 'y': 0, 'z': 0.1}})">
380
- نمای از کنار
381
- </div>
382
- """, unsafe_allow_html=True)
383
-
384
- # نمودار هیستوگرام سورفیس
385
- st.markdown("""
386
- <div class="chart-container">
387
- <h3>هیستوگرام سورفیس مساحت به تفکیک اداره و سن</h3>
388
- <p style="color: #666; margin-bottom: 20px;">این نمودار توزیع سطحی مساحت را بر اساس اداره و سن نشان می‌دهد.</p>
389
- </div>
390
- """, unsafe_allow_html=True)
391
-
392
- # پردازش داده‌ها برای هیستوگرام سورفیس
393
- def prepare_surface_data(df):
394
- data = []
395
- for _, row in df.iterrows():
396
- if row['اداره'] != 'Grand Total' and row['سن'] != 'total':
397
- data.append({
398
- 'اداره': row['اداره'],
399
- 'سن': row['سن'],
400
- 'مساحت': row['Grand Total']
401
- })
402
- return pd.DataFrame(data)
403
-
404
- df_surface = prepare_surface_data(df)
405
-
406
- # ایجاد هیستوگرام سورفیس بهبود یافته
407
- fig_surface = go.Figure(data=[go.Surface(
408
- x=df_surface['اداره'].unique(),
409
- y=df_surface['سن'].unique(),
410
- z=df_surface.pivot(index='سن', columns='اداره', values='مساحت').values,
411
- colorscale='Viridis',
412
- colorbar=dict(title="مساحت (هکتار)"),
413
- lighting=dict(ambient=0.6, diffuse=0.5, fresnel=0.1, specular=0.2, roughness=0.5),
414
- contours=dict(
415
- z=dict(show=True, usecolormap=True, highlightcolor="white", project=dict(z=True))
416
- )
417
- )])
418
-
419
- fig_surface.update_layout(
420
- scene = dict(
421
- xaxis_title=dict(text="اداره", font=dict(size=14, family="Vazirmatn")),
422
- yaxis_title=dict(text="سن", font=dict(size=14, family="Vazirmatn")),
423
- zaxis_title=dict(text="مساحت (هکتار)", font=dict(size=14, family="Vazirmatn")),
424
- xaxis=dict(backgroundcolor="rgba(230, 230, 230, 0.3)"),
425
- yaxis=dict(backgroundcolor="rgba(230, 230, 230, 0.3)"),
426
- zaxis=dict(backgroundcolor="rgba(230, 230, 230, 0.3)")
427
- ),
428
- margin=dict(l=0, r=0, b=0, t=30),
429
- height=600,
430
- scene_camera=dict(
431
- eye=dict(x=1.5, y=1.5, z=1.2)
432
- ),
433
- font=dict(family="Vazirmatn"),
434
- paper_bgcolor='rgba(0,0,0,0)',
435
- plot_bgcolor='rgba(0,0,0,0)'
436
- )
437
-
438
- st.plotly_chart(fig_surface, use_container_width=True)
439
-
440
- # نمودار مقایسه‌ای واریته‌ها
441
- st.markdown("""
442
- <div class="chart-container">
443
- <h3>مقایسه واریته‌ها در ادارات مختلف</h3>
444
- <p style="color: #666; margin-bottom: 20px;">این نمودار مساحت اختصاص داده شده به هر واریته ر�� در ادارات مختلف مقایسه می‌کند.</p>
445
- </div>
446
- """, unsafe_allow_html=True)
447
-
448
- # پردازش داده‌ها برای نمودار مقایسه‌ای
449
- varieties = ['CP69', 'CP73', 'CP48', 'CP57', 'CP65', 'CP70', 'IR01-412', 'IRC99-07', 'IRC00-14']
450
- fig_varieties = go.Figure()
451
-
452
- for i, variety in enumerate(varieties):
453
- data = df[df['اداره'] != 'Grand Total'].groupby('اداره')[variety].sum()
454
- fig_varieties.add_trace(go.Bar(
455
- name=variety,
456
- x=data.index,
457
- y=data.values,
458
- marker=dict(
459
- color=px.colors.qualitative.G10[i % len(px.colors.qualitative.G10)],
460
- line=dict(color='rgba(0,0,0,0.1)', width=0.5)
461
- ),
462
- hovertemplate="اداره: %{x}<br>مساحت: %{y:.2f} هکتار<extra>%{fullData.name}</extra>"
463
- ))
464
-
465
- fig_varieties.update_layout(
466
- barmode='group',
467
- xaxis_title=dict(text="اداره", font=dict(size=14, family="Vazirmatn")),
468
- yaxis_title=dict(text="مساحت (هکتار)", font=dict(size=14, family="Vazirmatn")),
469
- height=450,
470
- font=dict(family="Vazirmatn"),
471
- legend=dict(
472
- title=dict(text="واریته"),
473
- orientation="h",
474
- y=1.1,
475
- xanchor="center",
476
- x=0.5
477
- ),
478
- margin=dict(l=0, r=0, b=0, t=50),
479
- plot_bgcolor='rgba(0,0,0,0)',
480
- paper_bgcolor='rgba(0,0,0,0)',
481
- hovermode="closest"
482
- )
483
-
484
- st.plotly_chart(fig_varieties, use_container_width=True)
485
-
486
- # بخش جدید: خلاصه آماری
487
- st.markdown("""
488
- <div class="chart-container">
489
- <h3>خلاصه آماری واریته‌ها</h3>
490
- <p style="color: #666; margin-bottom: 20px;">این نمودار آمار توصیفی واریته‌های مختلف را نمایش می‌دهد.</p>
491
- </div>
492
- """, unsafe_allow_html=True)
493
-
494
- # محاسبه آمار توصیفی
495
- summary_data = []
496
- for variety in varieties:
497
- variety_data = df[df['اداره'] != 'Grand Total'][variety]
498
- variety_data = variety_data[variety_data > 0] # حذف صفرها
499
- if not variety_data.empty:
500
- summary_data.append({
501
- 'واریته': variety,
502
- 'مساحت کل (هکتار)': variety_data.sum(),
503
- 'میانگین مساحت (هکتار)': variety_data.mean(),
504
- 'بیشترین مساحت (هکتار)': variety_data.max(),
505
- 'کمترین مساحت (هکتار)': variety_data.min(),
506
- 'تعداد قطعات': len(variety_data)
507
- })
508
-
509
- summary_df = pd.DataFrame(summary_data)
510
-
511
- # نمایش جدول خلاصه آماری
512
- st.dataframe(summary_df.style.format({
513
- 'مساحت کل (هکتار)': '{:.2f}',
514
- 'میانگین مساحت (هکتار)': '{:.2f}',
515
- 'بیشترین مساحت (هکتار)': '{:.2f}',
516
- 'کمترین مساحت (هکتار)': '{:.2f}'
517
- }), height=300, use_container_width=True)
518
-
519
- # نمودار راداری برای مقایسه واریته‌ها
520
- categories = ['مساحت کل', 'میانگین مساحت', 'بیشترین مساحت', 'تعداد قطعات']
521
-
522
- fig_radar = go.Figure()
523
-
524
- for i, row in summary_df.iterrows():
525
- variety = row['واریته']
526
 
527
- # نرمال‌سازی داده‌ها برای نمودار راداری
528
- total_area_normalized = row['مساحت کل (هکتار)'] / summary_df['مساحت کل (هکتار)'].max()
529
- mean_area_normalized = row['میانگین مساحت (هکتار)'] / summary_df['میانگین مساحت (هکتار)'].max()
530
- max_area_normalized = row['بیشترین مساحت (هکتار)'] / summary_df['بیشترین مساحت (هکتار)'].max()
531
- count_normalized = row['تعداد قطعات'] / summary_df['تعداد قطعات'].max()
532
 
533
- fig_radar.add_trace(go.Scatterpolar(
534
- r=[total_area_normalized, mean_area_normalized, max_area_normalized, count_normalized],
535
- theta=categories,
536
- fill='toself',
537
- name=variety
538
- ))
539
-
540
- fig_radar.update_layout(
541
- polar=dict(
542
- radialaxis=dict(
543
- visible=True,
544
- range=[0, 1]
545
- )
546
- ),
547
- showlegend=True,
548
- height=500,
549
- font=dict(family="Vazirmatn"),
550
- legend=dict(
551
- orientation="h",
552
- y=-0.1,
553
- xanchor="center",
554
- x=0.5
555
- )
556
- )
557
-
558
- st.plotly_chart(fig_radar, use_container_width=True)
559
-
560
- # Footer
561
- st.markdown("""
562
- <div style="text-align: center; margin-top: 50px; padding: 20px; border-top: 1px solid rgba(0,0,0,0.1);">
563
- <p style="color: #666; font-size: 0.9em;">© سامانه پایش هوشمند نیشکر - تمامی حقوق محفوظ است.</p>
564
- </div>
565
- """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import pandas as pd
 
3
  import plotly.express as px
 
 
4
 
5
+ def render_dashboard(farm_data_df, filters):
6
+ """
7
+ Renders the main dashboard with farm data visualizations
8
+ """
9
+ st.title("📊 داشبورد مدیریت مزارع نیشکر")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ if farm_data_df.empty:
12
+ st.warning("داده‌های مزارع بارگذاری نشده است")
13
+ return
 
 
14
 
15
+ # Filter data based on selected farm if available
16
+ filtered_df = farm_data_df
17
+ if 'selected_farm' in filters:
18
+ farm_name_col = 'farm_name' if 'farm_name' in farm_data_df.columns else 'name'
19
+ filtered_df = farm_data_df[farm_data_df[farm_name_col] == filters['selected_farm']]
20
+
21
+ # Display basic metrics
22
+ st.subheader("آمار کلی مزارع")
23
+
24
+ col1, col2, col3, col4 = st.columns(4)
25
+
26
+ with col1:
27
+ total_farms = len(filtered_df['farm_id'].unique()) if 'farm_id' in filtered_df.columns else len(filtered_df)
28
+ st.metric("تعداد مزارع", f"{total_farms}")
29
+
30
+ with col2:
31
+ if 'area_ha' in filtered_df.columns:
32
+ total_area = filtered_df['area_ha'].sum()
33
+ st.metric("مساحت کل (هکتار)", f"{total_area:.2f}")
34
+ else:
35
+ st.metric("مساحت کل (هکتار)", "داده موجود نیست")
36
+
37
+ with col3:
38
+ if 'yield_tons' in filtered_df.columns:
39
+ avg_yield = filtered_df['yield_tons'].mean()
40
+ st.metric("میانگین عملکرد (تن)", f"{avg_yield:.2f}")
41
+ else:
42
+ st.metric("میانگین عملکرد (تن)", "داده موجود نیست")
43
+
44
+ with col4:
45
+ if 'ndvi' in filtered_df.columns:
46
+ avg_ndvi = filtered_df['ndvi'].mean()
47
+ st.metric("میانگین NDVI", f"{avg_ndvi:.2f}")
48
+ else:
49
+ st.metric("میانگین NDVI", "داده موجود نیست")
50
+
51
+ # Create sample charts
52
+ st.subheader("نمودارها و تحلیل‌ها")
53
+
54
+ # Create charts based on available columns
55
+ chart_cols = [col for col in filtered_df.columns if filtered_df[col].dtype in ['int64', 'float64']]
56
+
57
+ if chart_cols:
58
+ col1, col2 = st.columns(2)
59
+
60
+ with col1:
61
+ try:
62
+ # Sample bar chart
63
+ if 'area_ha' in filtered_df.columns and 'farm_name' in filtered_df.columns:
64
+ fig = px.bar(
65
+ filtered_df,
66
+ x='farm_name',
67
+ y='area_ha',
68
+ title="مساحت مزارع (هکتار)",
69
+ labels={"farm_name": "نام مزرعه", "area_ha": "مساحت (هکتار)"}
70
+ )
71
+ st.plotly_chart(fig, use_container_width=True)
72
+ else:
73
+ st.info("داده‌های کافی برای نمایش نمودار موجود نیست")
74
+ except Exception as e:
75
+ st.error(f"خطا در ایجاد نمودار: {str(e)}")
76
+
77
+ with col2:
78
+ try:
79
+ # Sample pie chart for farm distribution
80
+ if 'farm_type' in filtered_df.columns:
81
+ type_counts = filtered_df['farm_type'].value_counts().reset_index()
82
+ type_counts.columns = ['farm_type', 'count']
83
+
84
+ fig = px.pie(
85
+ type_counts,
86
+ values='count',
87
+ names='farm_type',
88
+ title="توزیع انواع مزارع",
89
+ hole=0.4
90
+ )
91
+ st.plotly_chart(fig, use_container_width=True)
92
+ else:
93
+ st.info("داده‌های کافی برای نمایش نمودار موجود نیست")
94
+ except Exception as e:
95
+ st.error(f"خطا در ایجاد نمودار: {str(e)}")
96
+
97
+ # Display farm data table
98
+ st.subheader("جدول داده‌های مزارع")
99
+ st.dataframe(filtered_df, use_container_width=True)