MaxBDKT commited on
Commit
682f46c
·
verified ·
1 Parent(s): 605d964

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +43 -26
src/streamlit_app.py CHANGED
@@ -7,23 +7,43 @@ import os
7
  # Configuration de la page
8
  st.set_page_config(page_title="Brake Performance Lab", layout="wide", page_icon="🚲")
9
 
10
- # --- FORÇAGE CSS NOIR ABSOLU POUR STREAMLIT ---
11
  st.markdown("""
12
  <style>
13
- html, body, [class*="css"], .stMarkdown, p, span, label {
 
 
 
 
 
 
 
 
 
 
 
14
  color: #000000 !important;
15
- font-weight: 500 !important;
16
  }
 
 
 
 
 
 
 
17
  [data-testid="stMetricValue"] { color: #000000 !important; font-weight: 800 !important; font-size: 22px !important; }
18
  [data-testid="stMetricLabel"] { color: #000000 !important; font-weight: bold !important; }
19
  [data-testid="column"] {
20
  padding: 10px !important;
21
  border: 2px solid #000000 !important;
22
  border-radius: 8px !important;
23
- background-color: #ffffff !important;
24
  }
25
- .alert-red { color: #D32F2F !important; font-weight: 900 !important; font-size: 13px; }
26
- .check-green { color: #2E7D32 !important; font-weight: 900 !important; font-size: 13px; }
 
 
27
  </style>
28
  """, unsafe_allow_html=True)
29
 
@@ -77,6 +97,7 @@ try:
77
  filtered_df = df[df['model name'].isin(selected_models)]
78
  fig = go.Figure()
79
  x_range = np.linspace(40, 200, 150)
 
80
  colors = ['#0082C3', '#E63312', '#000000', '#00A14B', '#FFD200']
81
 
82
  row_ref = df[df['model name'] == ref_model].iloc[0]
@@ -91,53 +112,50 @@ try:
91
  comparison_results.append({"name": row['model name'], "dry": y_d, "wet": y_w, "row": row})
92
 
93
  if condition_view in ["Both", "Dry only"]:
94
- fig.add_trace(go.Scatter(x=x_range, y=row['dry a']*x_range+row['dry b'], mode='lines', name=f"{row['model name']} (Dry)", line=dict(color=color, width=4), hovertemplate=f"<b>{row['model name']}</b><br>Perf: %{{y:.1f}} N<extra></extra>"))
95
  if n_dry > 0:
96
  xt = (n_dry - row['dry b']) / row['dry a']
97
- if xt <= 200: fig.add_trace(go.Scatter(x=[xt], y=[n_dry], mode='markers+text', text=[f"{round(xt,1)}N"], textfont=dict(color="black", size=12, weight=700), textposition="top center", marker=dict(color=color, size=10, symbol='x'), showlegend=False))
98
 
99
  if condition_view in ["Both", "Wet only"]:
100
- fig.add_trace(go.Scatter(x=x_range, y=row['wet a']*x_range+row['wet b'], mode='lines', name=f"{row['model name']} (Wet)", line=dict(color=color, width=3, dash='dot'), hovertemplate=f"<b>{row['model name']}</b><br>Perf: %{{y:.1f}} N<extra></extra>"))
101
  if n_wet > 0:
102
  xtw = (n_wet - row['wet b']) / row['wet a']
103
- if xtw <= 200: fig.add_trace(go.Scatter(x=[xtw], y=[n_wet], mode='markers+text', text=[f"{round(xtw,1)}N"], textfont=dict(color="black", size=12, weight=700), textposition="bottom center", marker=dict(color=color, size=10, symbol='circle-open'), showlegend=False))
104
 
105
  # Lignes de normes
106
  if n_dry > 0 and (condition_view in ["Both", "Dry only"]):
107
- fig.add_hline(y=n_dry, line_width=3, line_color="#000000", annotation_text=f"<b>Norm Dry: {n_dry}N</b>", annotation_font=dict(color="black", size=12))
108
  if n_wet > 0 and (condition_view in ["Both", "Wet only"]):
109
- fig.add_hline(y=n_wet, line_width=3, line_dash="dot", line_color="#000000", annotation_text=f"<b>Norm Wet: {n_wet}N</b>", annotation_font=dict(color="black", size=12))
110
 
111
  fig.add_vline(x=x_input, line_width=2, line_dash="dash", line_color="#000000")
112
 
113
- # --- NOIR TOTAL AVEC 'WEIGHT' AU LIEU DE 'BOLD' ---
114
  fig.update_layout(
115
  height=480,
116
  xaxis=dict(title="Lever Effort [N]", color="#000000", linecolor="#000000", linewidth=3, tickfont=dict(color="#000000", size=13, weight=700), gridcolor="#E0E0E0"),
117
  yaxis=dict(title="Performance [N]", color="#000000", linecolor="#000000", linewidth=3, tickfont=dict(color="#000000", size=13, weight=700), gridcolor="#E0E0E0"),
118
  font=dict(color="#000000", size=12),
119
- plot_bgcolor='white', paper_bgcolor='white',
120
  hovermode="x unified",
121
- legend=dict(font=dict(color="#000000", size=12, weight=700), bordercolor="#000000", borderwidth=2, bgcolor="white")
122
  )
123
  st.plotly_chart(fig, use_container_width=True)
124
 
125
- # --- ANALYSIS DASHBOARD (BOTTOM) ---
126
- st.markdown(f"<p style='color:black; font-weight:900; font-size:16px;'>📊 Performance Analysis [N] | Ref: {ref_model}</p>", unsafe_allow_html=True)
127
 
128
  if not filtered_df.empty:
129
  cols = st.columns(len(comparison_results))
130
  for i, res in enumerate(comparison_results):
131
  with cols[i]:
132
- is_ref = (res['name'] == ref_model)
133
- st.markdown(f"<p style='font-size:14px; font-weight:900; color:black; margin-bottom:5px; text-decoration: underline;'>{res['name']} {'⭐' if is_ref else ''}</p>", unsafe_allow_html=True)
134
 
135
  if condition_view in ["Both", "Dry only"]:
136
  dv = round(res['dry'], 1)
137
- if enable_comparison and not is_ref:
138
  diff = dv - round(ref_dry_val, 1)
139
- pct = (diff / ref_dry_val * 100) if ref_dry_val != 0 else 0
140
- st.metric("Dry Perf.", f"{dv} N", f"{diff:+.1f} N ({pct:+.1f}%) Vs Ref.")
141
  else: st.metric("Dry Perf.", f"{dv} N")
142
 
143
  if n_dry > 0:
@@ -147,10 +165,9 @@ try:
147
 
148
  if condition_view in ["Both", "Wet only"]:
149
  wv = round(res['wet'], 1)
150
- if enable_comparison and not is_ref:
151
  diffw = wv - round(ref_wet_val, 1)
152
- pctw = (diffw / ref_wet_val * 100) if ref_wet_val != 0 else 0
153
- st.metric("Wet Perf.", f"{wv} N", f"{diffw:+.1f} N ({pctw:+.1f}%) Vs Ref.")
154
  else: st.metric("Wet Perf.", f"{wv} N")
155
 
156
  if n_wet > 0:
@@ -160,7 +177,7 @@ try:
160
 
161
  if show_loss and condition_view == "Both":
162
  loss_pct = ((res['dry'] - res['wet']) / res['dry'] * 100) if res['dry'] != 0 else 0
163
- st.metric("Efficiency Loss", f"-{round(loss_pct, 1)}%", f"{round(res['wet']-res['dry'], 1)} N vs Dry", delta_color="inverse")
164
 
165
  except Exception as e:
166
  st.error(f"Error: {e}")
 
7
  # Configuration de la page
8
  st.set_page_config(page_title="Brake Performance Lab", layout="wide", page_icon="🚲")
9
 
10
+ # --- LE "SUPER CSS" POUR FORCER LE BLANC ET LE NOIR ---
11
  st.markdown("""
12
  <style>
13
+ /* 1. On force le fond de toute la page en BLANC */
14
+ .stApp {
15
+ background-color: #FFFFFF !important;
16
+ }
17
+
18
+ /* 2. On force TOUT le texte en NOIR ABSOLU */
19
+ * {
20
+ color: #000000 !important;
21
+ }
22
+
23
+ /* 3. On force les étiquettes des menus (Selectbox, Slider, Multiselect) en NOIR */
24
+ label, .stMultiSelect div, .stSelectbox div, .stSlider div {
25
  color: #000000 !important;
26
+ font-weight: bold !important;
27
  }
28
+
29
+ /* 4. On s'assure que les entrées de texte et menus ont un fond clair pour voir le texte noir dedans */
30
+ .stMultiSelect span, .stSelectbox div[data-baseweb="select"] {
31
+ background-color: #F0F2F6 !important;
32
+ }
33
+
34
+ /* 5. Metrics et boîtes d'analyse */
35
  [data-testid="stMetricValue"] { color: #000000 !important; font-weight: 800 !important; font-size: 22px !important; }
36
  [data-testid="stMetricLabel"] { color: #000000 !important; font-weight: bold !important; }
37
  [data-testid="column"] {
38
  padding: 10px !important;
39
  border: 2px solid #000000 !important;
40
  border-radius: 8px !important;
41
+ background-color: #FFFFFF !important;
42
  }
43
+
44
+ /* 6. Alertes (on garde les couleurs mais en version foncée pour la lisibilité) */
45
+ .alert-red { color: #B71C1C !important; font-weight: 900 !important; }
46
+ .check-green { color: #1B5E20 !important; font-weight: 900 !important; }
47
  </style>
48
  """, unsafe_allow_html=True)
49
 
 
97
  filtered_df = df[df['model name'].isin(selected_models)]
98
  fig = go.Figure()
99
  x_range = np.linspace(40, 200, 150)
100
+ # Couleurs courbes : Bleu Decathlon, Rouge, Noir, Vert, Jaune
101
  colors = ['#0082C3', '#E63312', '#000000', '#00A14B', '#FFD200']
102
 
103
  row_ref = df[df['model name'] == ref_model].iloc[0]
 
112
  comparison_results.append({"name": row['model name'], "dry": y_d, "wet": y_w, "row": row})
113
 
114
  if condition_view in ["Both", "Dry only"]:
115
+ fig.add_trace(go.Scatter(x=x_range, y=row['dry a']*x_range+row['dry b'], mode='lines', name=f"{row['model name']} (Dry)", line=dict(color=color, width=4)))
116
  if n_dry > 0:
117
  xt = (n_dry - row['dry b']) / row['dry a']
118
+ if xt <= 200: fig.add_trace(go.Scatter(x=[xt], y=[n_dry], mode='markers+text', text=[f"{round(xt,1)}N"], textfont=dict(color="#000000", size=12, weight=700), textposition="top center", marker=dict(color=color, size=10, symbol='x'), showlegend=False))
119
 
120
  if condition_view in ["Both", "Wet only"]:
121
+ fig.add_trace(go.Scatter(x=x_range, y=row['wet a']*x_range+row['wet b'], mode='lines', name=f"{row['model name']} (Wet)", line=dict(color=color, width=3, dash='dot')))
122
  if n_wet > 0:
123
  xtw = (n_wet - row['wet b']) / row['wet a']
124
+ if xtw <= 200: fig.add_trace(go.Scatter(x=[xtw], y=[n_wet], mode='markers+text', text=[f"{round(xtw,1)}N"], textfont=dict(color="#000000", size=12, weight=700), textposition="bottom center", marker=dict(color=color, size=10, symbol='circle-open'), showlegend=False))
125
 
126
  # Lignes de normes
127
  if n_dry > 0 and (condition_view in ["Both", "Dry only"]):
128
+ fig.add_hline(y=n_dry, line_width=3, line_color="#000000", annotation_text=f"Norm Dry: {n_dry}N", annotation_font=dict(color="black", size=12, weight=700))
129
  if n_wet > 0 and (condition_view in ["Both", "Wet only"]):
130
+ fig.add_hline(y=n_wet, line_width=3, line_dash="dot", line_color="#000000", annotation_text=f"Norm Wet: {n_wet}N", annotation_font=dict(color="black", size=12, weight=700))
131
 
132
  fig.add_vline(x=x_input, line_width=2, line_dash="dash", line_color="#000000")
133
 
 
134
  fig.update_layout(
135
  height=480,
136
  xaxis=dict(title="Lever Effort [N]", color="#000000", linecolor="#000000", linewidth=3, tickfont=dict(color="#000000", size=13, weight=700), gridcolor="#E0E0E0"),
137
  yaxis=dict(title="Performance [N]", color="#000000", linecolor="#000000", linewidth=3, tickfont=dict(color="#000000", size=13, weight=700), gridcolor="#E0E0E0"),
138
  font=dict(color="#000000", size=12),
139
+ plot_bgcolor='#FFFFFF', paper_bgcolor='#FFFFFF',
140
  hovermode="x unified",
141
+ legend=dict(font=dict(color="#000000", size=12, weight=700), bordercolor="#000000", borderwidth=2, bgcolor="#FFFFFF")
142
  )
143
  st.plotly_chart(fig, use_container_width=True)
144
 
145
+ # --- ANALYSIS DASHBOARD ---
146
+ st.markdown(f"<p style='color:#000000; font-weight:900; font-size:16px;'>📊 Performance Analysis [N] | Ref: {ref_model}</p>", unsafe_allow_html=True)
147
 
148
  if not filtered_df.empty:
149
  cols = st.columns(len(comparison_results))
150
  for i, res in enumerate(comparison_results):
151
  with cols[i]:
152
+ st.markdown(f"<p style='font-size:14px; font-weight:900; color:#000000; margin-bottom:5px; text-decoration: underline;'>{res['name']} {'⭐' if (res['name'] == ref_model) else ''}</p>", unsafe_allow_html=True)
 
153
 
154
  if condition_view in ["Both", "Dry only"]:
155
  dv = round(res['dry'], 1)
156
+ if enable_comparison and not (res['name'] == ref_model):
157
  diff = dv - round(ref_dry_val, 1)
158
+ st.metric("Dry Perf.", f"{dv} N", f"{diff:+.1f} N Vs Ref.")
 
159
  else: st.metric("Dry Perf.", f"{dv} N")
160
 
161
  if n_dry > 0:
 
165
 
166
  if condition_view in ["Both", "Wet only"]:
167
  wv = round(res['wet'], 1)
168
+ if enable_comparison and not (res['name'] == ref_model):
169
  diffw = wv - round(ref_wet_val, 1)
170
+ st.metric("Wet Perf.", f"{wv} N", f"{diffw:+.1f} N Vs Ref.")
 
171
  else: st.metric("Wet Perf.", f"{wv} N")
172
 
173
  if n_wet > 0:
 
177
 
178
  if show_loss and condition_view == "Both":
179
  loss_pct = ((res['dry'] - res['wet']) / res['dry'] * 100) if res['dry'] != 0 else 0
180
+ st.metric("Efficiency Loss", f"-{round(loss_pct, 1)}%", delta_color="inverse")
181
 
182
  except Exception as e:
183
  st.error(f"Error: {e}")