import streamlit as st import plotly.express as px import plotly.graph_objects as go import pandas as pd from datetime import datetime, timedelta from app.services.main_process_service import MainProcessService def show_main_process_dashboard(): # 初始化服务 service = MainProcessService() # 页面标题 st.title("主流程控制数据分析") # 初始化会话状态用于日期同步 if 'main_process_start_date' not in st.session_state: st.session_state['main_process_start_date'] = datetime.now().date() - timedelta(days=7) if 'main_process_end_date' not in st.session_state: st.session_state['main_process_end_date'] = datetime.now().date() if 'main_process_quick_select' not in st.session_state: st.session_state['main_process_quick_select'] = "最近7天" # 定义回调函数 def update_dates(qs): st.session_state['main_process_quick_select'] = qs today = datetime.now().date() if qs == "今天": st.session_state['main_process_start_date'] = today st.session_state['main_process_end_date'] = today elif qs == "最近3天": st.session_state['main_process_start_date'] = today - timedelta(days=3) st.session_state['main_process_end_date'] = today elif qs == "最近7天": st.session_state['main_process_start_date'] = today - timedelta(days=7) st.session_state['main_process_end_date'] = today elif qs == "最近30天": st.session_state['main_process_start_date'] = today - timedelta(days=30) st.session_state['main_process_end_date'] = today def on_date_change(): st.session_state['main_process_quick_select'] = "自定义" # 查询条件区域 with st.expander("🔍 查询配置", expanded=True): # 添加自定义 CSS 实现响应式换行 st.markdown(""" """, unsafe_allow_html=True) # 创建布局 cols = st.columns([1, 1, 1, 1, 1, 1.5, 1.5, 1]) options = ["今天", "最近3天", "最近7天", "最近30天", "自定义"] for i, option in enumerate(options): with cols[i]: # 根据当前选择状态决定按钮类型 button_type = "primary" if st.session_state['main_process_quick_select'] == option else "secondary" if st.button(option, key=f"btn_main_{option}", width='stretch', type=button_type): update_dates(option) st.rerun() with cols[5]: st.date_input( "开始日期", label_visibility="collapsed", key="main_process_start_date", on_change=on_date_change ) with cols[6]: st.date_input( "结束日期", label_visibility="collapsed", key="main_process_end_date", on_change=on_date_change ) with cols[7]: query_button = st.button("🚀 查询", key="main_process_query", width='stretch') # 转换为datetime对象 start_dt = datetime.combine(st.session_state['main_process_start_date'], datetime.min.time()) end_dt = datetime.combine(st.session_state['main_process_end_date'], datetime.max.time()) if query_button: with st.spinner("正在获取主流程数据..."): # 1. 获取主速度数据 df_speed = service.get_cutting_setting_data(start_dt, end_dt) # 2. 获取电机监控数据 df_motor = service.get_motor_monitoring_data(start_dt, end_dt) # 3. 获取温度控制数据 df_temp = service.get_temperature_control_data(start_dt, end_dt) # --- 趋势图 1: 流程主速度 --- st.subheader("📈 流程主速度趋势") if not df_speed.empty: fig_speed = px.line(df_speed, x='time', y='process_main_speed', title="流程主速度 (M/Min)", labels={'time': '时间', 'process_main_speed': '主速度 (M/Min)'}) fig_speed.update_layout( xaxis=dict(rangeslider=dict(visible=True), type='date'), yaxis=dict(fixedrange=False), hovermode='x unified', dragmode='zoom', ) st.plotly_chart(fig_speed, width='stretch', config={ 'scrollZoom': True, 'modeBarButtonsToAdd': ['zoom2d', 'zoomIn2d', 'zoomOut2d'], 'doubleClick': 'reset', 'displayModeBar': True, 'toImageButtonOptions': {'format': 'png'} }) else: st.info("该时间段内无主速度数据") # --- 趋势图 2: 电机运行线速 --- st.subheader("📈 电机运行线速趋势") if not df_motor.empty: fig_motor = go.Figure() fig_motor.add_trace(go.Scatter(x=df_motor['time'], y=df_motor['m1_line_speed'], name='拉出一段线速')) fig_motor.add_trace(go.Scatter(x=df_motor['time'], y=df_motor['m2_line_speed'], name='拉出二段线速')) fig_motor.update_layout( title="电机线速 (M/Min)", xaxis_title="时间", yaxis_title="线速 (M/Min)", xaxis=dict(rangeslider=dict(visible=True), type='date'), yaxis=dict(fixedrange=False), hovermode='x unified', dragmode='zoom' ) st.plotly_chart(fig_motor, width='stretch', config={ 'scrollZoom': True, 'modeBarButtonsToAdd': ['zoom2d', 'zoomIn2d', 'zoomOut2d'], 'doubleClick': 'reset', 'displayModeBar': True }) else: st.info("该时间段内无电机监控数据") # --- 趋势图 3: 中田挤出机温度控制 --- st.subheader("📈 中田挤出机温度趋势") if not df_temp.empty: fig_temp = go.Figure() # 螺杆温度 fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_screw_set_temp'], name='螺杆设定', line=dict(dash='dash'))) fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_screw_display_temp'], name='螺杆显示')) # 后机筒温度 fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_rear_barrel_set_temp'], name='后机筒设定', line=dict(dash='dash'))) fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_rear_barrel_display_temp'], name='后机筒显示')) # 前机筒温度 fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_front_barrel_set_temp'], name='前机筒设定', line=dict(dash='dash'))) fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_front_barrel_display_temp'], name='前机筒显示')) # 机头温度 fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_head_set_temp'], name='机头设定', line=dict(dash='dash'))) fig_temp.add_trace(go.Scatter(x=df_temp['time'], y=df_temp['nakata_extruder_head_display_temp'], name='机头显示')) fig_temp.update_layout( title="中田挤出机温度 (°C)", xaxis_title="时间", yaxis_title="温度 (°C)", xaxis=dict(rangeslider=dict(visible=True), type='date'), yaxis=dict(fixedrange=False), hovermode='x unified', dragmode='zoom' ) st.plotly_chart(fig_temp, width='stretch', config={ 'scrollZoom': True, 'modeBarButtonsToAdd': ['zoom2d', 'zoomIn2d', 'zoomOut2d'], 'doubleClick': 'reset', 'displayModeBar': True }) else: st.info("该时间段内无温度控制数据")