clidx commited on
Commit
e059c56
·
verified ·
1 Parent(s): b7fc2e9

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +124 -3
src/streamlit_app.py CHANGED
@@ -1,8 +1,10 @@
1
  import streamlit as st
2
  import pandas as pd
3
- import math
4
  import plotly.graph_objects as go
5
  import plotly.express as px
 
 
 
6
 
7
  # 页面配置(必须在最开始)
8
  st.set_page_config(
@@ -12,6 +14,53 @@ st.set_page_config(
12
  initial_sidebar_state="expanded"
13
  )
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  # 自定义CSS样式
16
  st.markdown("""
17
  <style>
@@ -75,6 +124,16 @@ st.markdown("""
75
  overflow: hidden;
76
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
77
  }
 
 
 
 
 
 
 
 
 
 
78
  </style>
79
  """, unsafe_allow_html=True)
80
 
@@ -129,7 +188,15 @@ LANGUAGES = {
129
  "instruction_4": "4. **查看结果**: 右侧显示转换结果和详细信息",
130
  "note": "⚠️ **注意**: 本计算假设理想混合,实际情况可能存在偏差。",
131
  "language": "🌐 语言",
132
- "visualization": "📈 可视化"
 
 
 
 
 
 
 
 
133
  },
134
  "English": {
135
  "page_title": "Solvent Fraction Converter",
@@ -180,7 +247,15 @@ LANGUAGES = {
180
  "instruction_4": "4. **View Results**: Results and detailed information are displayed on the right",
181
  "note": "⚠️ **Note**: This calculation assumes ideal mixing; actual situations may deviate.",
182
  "language": "🌐 Language",
183
- "visualization": "📈 Visualization"
 
 
 
 
 
 
 
 
184
  }
185
  }
186
 
@@ -298,6 +373,52 @@ with st.sidebar:
298
  rho_b = current_solvents[solvent_b_name]["density"]
299
  st.info(f"📊 {lang['molar_mass']}: **{M_b}** g/mol \n📊 {lang['density']}: **{rho_b}** g/cm³")
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  # 主界面内容
302
  col1, col2 = st.columns([1, 1], gap="large")
303
 
 
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 json
6
+ import os
7
+ from datetime import datetime
8
 
9
  # 页面配置(必须在最开始)
10
  st.set_page_config(
 
14
  initial_sidebar_state="expanded"
15
  )
16
 
17
+ # 访问统计功能
18
+ def manage_visit_stats():
19
+ """管理访问统计"""
20
+ stats_file = "visit_stats.json"
21
+
22
+ # 初始化统计数据
23
+ if os.path.exists(stats_file):
24
+ try:
25
+ with open(stats_file, 'r', encoding='utf-8') as f:
26
+ stats = json.load(f)
27
+ except:
28
+ stats = {
29
+ "total_visits": 0,
30
+ "daily_visits": {},
31
+ "first_visit": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
32
+ "last_visit": None
33
+ }
34
+ else:
35
+ stats = {
36
+ "total_visits": 0,
37
+ "daily_visits": {},
38
+ "first_visit": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
39
+ "last_visit": None
40
+ }
41
+
42
+ # 检查是否需要更新统计
43
+ if 'visit_counted' not in st.session_state:
44
+ st.session_state.visit_counted = True
45
+
46
+ # 更新统计
47
+ today = datetime.now().strftime("%Y-%m-%d")
48
+ stats["total_visits"] += 1
49
+ stats["daily_visits"][today] = stats["daily_visits"].get(today, 0) + 1
50
+ stats["last_visit"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
51
+
52
+ # 保存统计
53
+ try:
54
+ with open(stats_file, 'w', encoding='utf-8') as f:
55
+ json.dump(stats, f, ensure_ascii=False, indent=2)
56
+ except:
57
+ pass # 忽略写入错误
58
+
59
+ return stats
60
+
61
+ # 在页面配置后调用
62
+ visit_stats = manage_visit_stats()
63
+
64
  # 自定义CSS样式
65
  st.markdown("""
66
  <style>
 
124
  overflow: hidden;
125
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
126
  }
127
+
128
+ /* 访问统计样式 */
129
+ .visit-stats {
130
+ background: linear-gradient(135deg, #00b894 0%, #00a085 100%);
131
+ color: white;
132
+ padding: 1rem;
133
+ border-radius: 10px;
134
+ margin: 1rem 0;
135
+ text-align: center;
136
+ }
137
  </style>
138
  """, unsafe_allow_html=True)
139
 
 
188
  "instruction_4": "4. **查看结果**: 右侧显示转换结果和详细信息",
189
  "note": "⚠️ **注意**: 本计算假设理想混合,实际情况可能存在偏差。",
190
  "language": "🌐 语言",
191
+ "visualization": "📈 可视化",
192
+ "visit_stats": "📊 访问统计",
193
+ "total_visits": "总访问量",
194
+ "today_visits": "今日访问",
195
+ "last_visit": "上次访问",
196
+ "visit_trend": "访问趋势",
197
+ "recent_days": "最近访问趋势",
198
+ "date": "日期",
199
+ "visits": "访问次数"
200
  },
201
  "English": {
202
  "page_title": "Solvent Fraction Converter",
 
247
  "instruction_4": "4. **View Results**: Results and detailed information are displayed on the right",
248
  "note": "⚠️ **Note**: This calculation assumes ideal mixing; actual situations may deviate.",
249
  "language": "🌐 Language",
250
+ "visualization": "📈 Visualization",
251
+ "visit_stats": "📊 Visit Statistics",
252
+ "total_visits": "Total Visits",
253
+ "today_visits": "Today's Visits",
254
+ "last_visit": "Last Visit",
255
+ "visit_trend": "Visit Trend",
256
+ "recent_days": "Recent Visit Trend",
257
+ "date": "Date",
258
+ "visits": "Visits"
259
  }
260
  }
261
 
 
373
  rho_b = current_solvents[solvent_b_name]["density"]
374
  st.info(f"📊 {lang['molar_mass']}: **{M_b}** g/mol \n📊 {lang['density']}: **{rho_b}** g/cm³")
375
 
376
+ # 访问统计显示
377
+ st.markdown("---")
378
+ st.markdown("### " + lang["visit_stats"])
379
+
380
+ # 显示统计信息
381
+ col1, col2 = st.columns(2)
382
+ with col1:
383
+ st.metric(lang["total_visits"], visit_stats["total_visits"])
384
+ with col2:
385
+ today = datetime.now().strftime("%Y-%m-%d")
386
+ today_visits = visit_stats["daily_visits"].get(today, 0)
387
+ st.metric(lang["today_visits"], today_visits)
388
+
389
+ # 显示最近访问时间
390
+ if visit_stats["last_visit"]:
391
+ st.caption(f"{lang['last_visit']}: {visit_stats['last_visit']}")
392
+
393
+ # 显示访问趋势(简单的条形图)
394
+ if len(visit_stats["daily_visits"]) > 1:
395
+ recent_days = list(visit_stats["daily_visits"].items())[-7:] # 最近7天
396
+ dates = [item[0] for item in recent_days]
397
+ counts = [item[1] for item in recent_days]
398
+
399
+ if len(dates) > 1:
400
+ df_visits = pd.DataFrame({
401
+ lang["date"]: dates,
402
+ lang["visits"]: counts
403
+ })
404
+ fig_visits = px.bar(
405
+ df_visits,
406
+ x=lang["date"],
407
+ y=lang["visits"],
408
+ title=lang["recent_days"],
409
+ height=200,
410
+ color=lang["visits"],
411
+ color_continuous_scale="viridis"
412
+ )
413
+ fig_visits.update_layout(
414
+ showlegend=False,
415
+ margin=dict(l=20, r=20, t=40, b=20),
416
+ xaxis_title="",
417
+ yaxis_title="",
418
+ font=dict(size=10)
419
+ )
420
+ st.plotly_chart(fig_visits, use_container_width=True)
421
+
422
  # 主界面内容
423
  col1, col2 = st.columns([1, 1], gap="large")
424