MaxBDKT commited on
Commit
9a4d60e
·
verified ·
1 Parent(s): 87df95b

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +68 -39
src/streamlit_app.py CHANGED
@@ -4,42 +4,67 @@ import os
4
  import numpy as np
5
 
6
  # ==============================================================================
7
- # 1. STYLE CSS V2.2 (SOCLE INVIOLABLE)
8
  # ==============================================================================
9
- st.set_page_config(page_title="Brake Lab V2.2", layout="centered")
10
 
11
  st.markdown("""
12
  <style>
 
13
  .stApp { background-color: #FFFFFF !important; }
14
  * { color: #000000 !important; font-family: 'Arial', sans-serif; }
15
 
16
- /* INPUTS : TEXTE BLANC SUR NOIR */
17
  input[type="number"], .stNumberInput div[data-baseweb="input"] {
18
  color: #FFFFFF !important;
19
  background-color: #1E1E1E !important;
20
  border-radius: 8px !important;
21
  font-weight: bold !important;
22
- border: 2px solid #000 !important;
23
  }
 
 
 
 
 
 
 
24
 
25
- /* SELECTBOX : BLANC SUR NOIR */
26
  div[data-baseweb="select"] {
27
  background-color: #1E1E1E !important;
28
  border: 2px solid #000000 !important;
29
- border-radius: 8px !important;
30
  }
31
- div[data-baseweb="select"] div { color: #FFFFFF !important; font-weight: bold !important; }
 
 
 
 
32
 
33
- /* LISTE DÉROULANTE (VISIBILITÉ) */
34
- div[role="listbox"], ul[role="listbox"] { background-color: #1E1E1E !important; }
35
- li[role="option"], li[role="option"] p, li[role="option"] span, li[role="option"] div {
 
 
 
 
36
  color: #FFFFFF !important;
37
  background-color: #1E1E1E !important;
38
  font-weight: bold !important;
39
  }
40
- li[role="option"]:hover { background-color: #0082C3 !important; }
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- /* CARTES DE RÉSULTATS */
43
  .perf-box {
44
  padding: 40px;
45
  border: 4px solid #000000;
@@ -49,7 +74,11 @@ st.markdown("""
49
  margin-top: 20px;
50
  box-shadow: 8px 8px 0px #000;
51
  }
52
- .perf-value { font-size: 55px; font-weight: 900; color: #0082C3 !important; margin: 0px; }
 
 
 
 
53
  </style>
54
  """, unsafe_allow_html=True)
55
 
@@ -68,7 +97,7 @@ def load_data():
68
  df = load_data()
69
 
70
  # ==============================================================================
71
- # 3. INTERFACE V2.2 : ARCHITECTURE 2 BLOCS
72
  # ==============================================================================
73
  if not df.empty:
74
 
@@ -77,58 +106,58 @@ if not df.empty:
77
  c1, c2 = st.columns(2)
78
  with c1:
79
  effort_val = st.number_input("Effort Levier [N]", value=100, step=1)
80
- mass_total = st.number_input("Masse Totale (Vélo + Cycliste) [kg]", value=100, step=1)
81
- wheel_size = st.number_input("Taille de roue [inch]", value=28, step=1)
82
  with c2:
83
- speed_kmh = st.number_input("Vitesse du vélo [km/h]", value=25, step=1)
84
- mass_ratio = st.number_input("Rapport de masse arrière [%]", value=70, step=1, min_value=0, max_value=100)
85
 
86
  # --- BLOC 2 : DONNÉES COMPOSANTS ---
87
  with st.expander("⚙️ Données composant", expanded=True):
88
  model_list = df['model name'].unique().tolist()
89
-
90
  col_comp1, col_comp2 = st.columns(2)
91
  with col_comp1:
92
- main_model = st.selectbox("Système de freinage étudié", options=model_list)
93
  with col_comp2:
94
  comp_options = ["Aucun"] + model_list
95
  compare_model = st.selectbox("Système de comparaison", options=comp_options)
96
 
97
- # --- LOGIQUE DE CALCUL (MODÈLE PRINCIPAL) ---
98
  row = df[df['model name'] == main_model].iloc[0]
99
  res_dry = row['dry a'] * effort_val + row['dry b']
100
  res_wet = row['wet a'] * effort_val + row['wet b']
101
 
102
- # --- LOGIQUE DE CALCUL (MODÈLE COMPARAISON) ---
103
- res_dry_comp, res_wet_comp = None, None
104
- if compare_model != "Aucun":
105
- row_c = df[df['model name'] == compare_model].iloc[0]
106
- res_dry_comp = row_c['dry a'] * effort_val + row_c['dry b']
107
- res_wet_comp = row_c['wet a'] * effort_val + row_c['wet b']
108
-
109
- # --- AFFICHAGE DES RÉSULTATS ---
110
  st.write("")
111
-
112
- # Titre dynamique pour savoir ce qu'on regarde
113
- if compare_model == "Aucun":
114
- st.markdown(f"<h3 style='text-align:center;'>Résultats : {main_model}</h3>", unsafe_allow_html=True)
115
- else:
116
- st.markdown(f"<h3 style='text-align:center;'>Comparaison : {main_model} vs {compare_model}</h3>", unsafe_allow_html=True)
117
-
118
  res_c1, res_c2 = st.columns(2)
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  with res_c1:
121
  st.markdown(f"""<div class="perf-box">
122
  <p style="font-size: 20px; font-weight: bold; color: #555 !important; margin-bottom:10px;">CONDITION : SEC</p>
123
- <p class="perf-value">{round(res_dry, 1)} N</p>
124
- {f'<p style="color:#0082C3; font-weight:bold; margin-top:10px;">vs {round(res_dry_comp, 1)} N</p>' if res_dry_comp else ''}
125
  </div>""", unsafe_allow_html=True)
126
 
127
  with res_c2:
128
  st.markdown(f"""<div class="perf-box">
129
  <p style="font-size: 20px; font-weight: bold; color: #555 !important; margin-bottom:10px;">CONDITION : HUMIDE</p>
130
  <p class="perf-value" style="color: #E63312 !important;">{round(res_wet, 1)} N</p>
131
- {f'<p style="color:#E63312; font-weight:bold; margin-top:10px;">vs {round(res_wet_comp, 1)} N</p>' if res_wet_comp else ''}
132
  </div>""", unsafe_allow_html=True)
133
 
134
  else:
 
4
  import numpy as np
5
 
6
  # ==============================================================================
7
+ # 1. STYLE CSS V2.3 (FOCUS VISIBILITÉ TOTALE & BOUTONS)
8
  # ==============================================================================
9
+ st.set_page_config(page_title="Brake Lab V2.3", layout="centered")
10
 
11
  st.markdown("""
12
  <style>
13
+ /* 1.1 FOND GLOBAL */
14
  .stApp { background-color: #FFFFFF !important; }
15
  * { color: #000000 !important; font-family: 'Arial', sans-serif; }
16
 
17
+ /* 1.2 INPUTS NUMÉRIQUES : BLANC SUR NOIR + BOUTONS VISIBLES */
18
  input[type="number"], .stNumberInput div[data-baseweb="input"] {
19
  color: #FFFFFF !important;
20
  background-color: #1E1E1E !important;
21
  border-radius: 8px !important;
22
  font-weight: bold !important;
 
23
  }
24
+
25
+ /* FORCE LA VISIBILITÉ DES BOUTONS + ET - */
26
+ button[aria-label="Step up"], button[aria-label="Step down"], button {
27
+ color: #FFFFFF !important;
28
+ background-color: #333333 !important;
29
+ }
30
+ button:hover { background-color: #0082C3 !important; }
31
 
32
+ /* 1.3 SELECTBOX : FIX VISIBILITÉ LORS DU CLIC */
33
  div[data-baseweb="select"] {
34
  background-color: #1E1E1E !important;
35
  border: 2px solid #000000 !important;
 
36
  }
37
+
38
+ /* Texte sélectionné et curseur */
39
+ div[data-baseweb="select"] * {
40
+ color: #FFFFFF !important;
41
+ }
42
 
43
+ /* Menu déroulant (Options) */
44
+ div[role="listbox"], ul[role="listbox"] {
45
+ background-color: #1E1E1E !important;
46
+ border: 1px solid #FFFFFF !important;
47
+ }
48
+
49
+ li[role="option"], li[role="option"] * {
50
  color: #FFFFFF !important;
51
  background-color: #1E1E1E !important;
52
  font-weight: bold !important;
53
  }
54
+
55
+ li[role="option"]:hover {
56
+ background-color: #0082C3 !important;
57
+ }
58
+
59
+ /* 1.4 EXPANDERS : TITRES BIEN NOIRS SUR BLANC */
60
+ .streamlit-expanderHeader {
61
+ background-color: #F0F2F6 !important;
62
+ color: #000000 !important;
63
+ font-weight: bold !important;
64
+ border-radius: 8px !important;
65
+ }
66
 
67
+ /* 1.5 CARTES DE RÉSULTATS */
68
  .perf-box {
69
  padding: 40px;
70
  border: 4px solid #000000;
 
74
  margin-top: 20px;
75
  box-shadow: 8px 8px 0px #000;
76
  }
77
+ .perf-value { font-size: 55px; font-weight: 900; margin: 0px; }
78
+
79
+ /* COULEURS COMPARAISON */
80
+ .comp-pos { color: #1B5E20 !important; font-weight: bold; font-size: 18px; margin-top: 10px; } /* Vert */
81
+ .comp-neg { color: #B71C1C !important; font-weight: bold; font-size: 18px; margin-top: 10px; } /* Rouge */
82
  </style>
83
  """, unsafe_allow_html=True)
84
 
 
97
  df = load_data()
98
 
99
  # ==============================================================================
100
+ # 3. INTERFACE V2.3
101
  # ==============================================================================
102
  if not df.empty:
103
 
 
106
  c1, c2 = st.columns(2)
107
  with c1:
108
  effort_val = st.number_input("Effort Levier [N]", value=100, step=1)
109
+ mass_total = st.number_input("Masse Totale (kg)", value=100, step=1)
110
+ wheel_size = st.number_input("Roue [inch]", value=28, step=1)
111
  with c2:
112
+ speed_kmh = st.number_input("Vitesse [km/h]", value=25, step=1)
113
+ mass_ratio = st.number_input("Rapport masse AR [%]", value=70, step=1)
114
 
115
  # --- BLOC 2 : DONNÉES COMPOSANTS ---
116
  with st.expander("⚙️ Données composant", expanded=True):
117
  model_list = df['model name'].unique().tolist()
 
118
  col_comp1, col_comp2 = st.columns(2)
119
  with col_comp1:
120
+ main_model = st.selectbox("Système étudié", options=model_list)
121
  with col_comp2:
122
  comp_options = ["Aucun"] + model_list
123
  compare_model = st.selectbox("Système de comparaison", options=comp_options)
124
 
125
+ # --- CALCULS ---
126
  row = df[df['model name'] == main_model].iloc[0]
127
  res_dry = row['dry a'] * effort_val + row['dry b']
128
  res_wet = row['wet a'] * effort_val + row['wet b']
129
 
130
+ # --- AFFICHAGE ---
 
 
 
 
 
 
 
131
  st.write("")
 
 
 
 
 
 
 
132
  res_c1, res_c2 = st.columns(2)
133
 
134
+ # Fonction pour générer le texte de comparaison en %
135
+ def get_comp_html(val_main, val_comp):
136
+ if val_comp is None: return ""
137
+ diff_pct = ((val_main - val_comp) / val_comp) * 100
138
+ color_class = "comp-pos" if diff_pct >= 0 else "comp-neg"
139
+ sign = "+" if diff_pct >= 0 else ""
140
+ return f'<p class="{color_class}">{sign}{round(diff_pct, 1)}% vs comp</p>'
141
+
142
+ # Calcul comparaison si nécessaire
143
+ res_dry_c, res_wet_c = None, None
144
+ if compare_model != "Aucun":
145
+ row_c = df[df['model name'] == compare_model].iloc[0]
146
+ res_dry_c = row_c['dry a'] * effort_val + row_c['dry b']
147
+ res_wet_c = row_c['wet a'] * effort_val + row_c['wet b']
148
+
149
  with res_c1:
150
  st.markdown(f"""<div class="perf-box">
151
  <p style="font-size: 20px; font-weight: bold; color: #555 !important; margin-bottom:10px;">CONDITION : SEC</p>
152
+ <p class="perf-value" style="color: #0082C3 !important;">{round(res_dry, 1)} N</p>
153
+ {get_comp_html(res_dry, res_dry_c)}
154
  </div>""", unsafe_allow_html=True)
155
 
156
  with res_c2:
157
  st.markdown(f"""<div class="perf-box">
158
  <p style="font-size: 20px; font-weight: bold; color: #555 !important; margin-bottom:10px;">CONDITION : HUMIDE</p>
159
  <p class="perf-value" style="color: #E63312 !important;">{round(res_wet, 1)} N</p>
160
+ {get_comp_html(res_wet, res_wet_c)}
161
  </div>""", unsafe_allow_html=True)
162
 
163
  else: