Skip to content

Commit 06b56d9

Browse files
Merge branch 'master' into bump_version_2.8.1
2 parents 5b0fda8 + d1eaeb7 commit 06b56d9

File tree

9 files changed

+304
-128
lines changed

9 files changed

+304
-128
lines changed
-116 KB
Loading

docs/requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@ sphinxcontrib-qthelp==1.0.3
99
sphinxcontrib-serializinghtml==1.1.5
1010
nbsphinx==0.8.8
1111
sphinx_material==0.0.35
12-
numpy<2

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ build-backend = "setuptools.build_meta"
55
[project]
66
name = "shapash"
77
version = "2.8.1"
8+
89
authors = [
910
{name = "Yann Golhen"},
1011
{name = "Sebastien Bidault"},
@@ -43,7 +44,7 @@ dependencies = [
4344
"nbformat>5.8.0",
4445
"numba>=0.60.0",
4546
"numpy>=2.0.0",
46-
"pandas>=2.2.2",
47+
"pandas>=2.2.2,<3.0.0",
4748
"plotly>=5.0.0,<6.0.0",
4849
"scikit-learn>=1.4.2,<1.6.0",
4950
"scipy>=1.13.0",

shapash/webapp/assets/material-icons.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
font-family: 'Material Icons';
1111
font-weight: normal;
1212
font-style: normal;
13-
font-size: 24px;
13+
font-size: calc(0.5rem + 0.85vw);
1414
line-height: 1;
1515
letter-spacing: normal;
1616
text-transform: none;

shapash/webapp/assets/style.css

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
h3 {
2+
font-size: calc(0.6rem + 1.1vw) !important;
3+
}
4+
5+
h4 {
6+
font-size: calc(0.55rem + 0.95vw) !important;
7+
}
18
:root {
29
--main-color: #f4c000;
310
--bkg-color: #343736;
11+
--bs-body-font-size: calc(0.3rem + 0.5vw);
412
}
513

614
#shapash_title {
@@ -59,6 +67,10 @@
5967
border-color: var(--main-color);
6068
}
6169

70+
.rc-slider-mark {
71+
font-size: calc(0.25rem + 0.45vw);
72+
}
73+
6274

6375
/* CHECKBOX */
6476
.custom-control-input:checked~.custom-control-label::before {
@@ -75,6 +87,7 @@
7587
.Select--multi .Select-value {
7688
color: var(--bkg-color) !important;
7789
background-color: var(--main-color) !important;
90+
margin-top: 1px !important;
7891
}
7992

8093
/* DATATABLE */
@@ -92,6 +105,9 @@
92105
margin-left: 0 !important;
93106
}
94107

108+
.dash-spreadsheet.dash-freeze-top, .dash-spreadsheet.dash-virtualized {
109+
max-height: 100% !important;
110+
}
95111

96112
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner td.cell--selected, td.focused {
97113
background-color : Transparent !important;
@@ -115,11 +131,11 @@
115131
/* EXPAND */
116132

117133
.dock-expand {
118-
width: 40px;
119-
height: 40px;
134+
width: 2vw;
135+
height: 2vw;
120136
position: absolute;
121-
top: -10px;
122-
right: -10px;
137+
top: -0.5vw;
138+
right: -0.5vw;
123139
background-color: white;
124140
border-radius: 26px;
125141
box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2);
@@ -181,3 +197,55 @@
181197
{
182198
margin-bottom: 0;
183199
}
200+
201+
.Select-placeholder, .Select__placeholder {
202+
line-height: 1.4vw !important;
203+
font-size: calc(0.3rem + 0.5vw) !important;
204+
}
205+
206+
.Select-control, .Select__control {
207+
height: 1.4vw !important;
208+
line-height: 1.4vw !important;
209+
font-size: calc(0.3rem + 0.5vw) !important;
210+
}
211+
212+
.Select-value, .Select__single-value {
213+
line-height: 0.9vw !important;
214+
font-size: calc(0.3rem + 0.5vw) !important;
215+
margin-top: 0.3vw !important;
216+
}
217+
218+
.Select-input{
219+
padding: 0;
220+
height: 1.4vw !important;
221+
line-height: 1.4vw !important;
222+
}
223+
224+
.Select-input input {
225+
padding: 0;
226+
height: 1.4vw !important;
227+
line-height: 1.4vw !important;
228+
}
229+
230+
.Select-clear {
231+
font-size: calc(0.4rem + 0.65vw) !important;
232+
}
233+
234+
.Select-multi-value-wrapper, .Select__value-container {
235+
height: 1.4vw !important;
236+
min-height: 1.4vw !important;
237+
line-height: 1.4vw !important;
238+
}
239+
240+
input.form-control-s, input.form-control-s.form-control {
241+
height: 1.5vw !important;
242+
line-height: 1.5vw !important;
243+
font-size: 0.7vw !important;
244+
}
245+
246+
button#id_card, .btn-warning {
247+
height: 1.5vw !important;
248+
font-size: calc(0.3rem + 0.5vw) !important;
249+
align-items: center;
250+
padding-top: 0.2vw !important;
251+
}

shapash/webapp/smart_app.py

Lines changed: 116 additions & 57 deletions
Large diffs are not rendered by default.

shapash/webapp/utils/MyGraph.py

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,42 +54,78 @@ def adjust_graph_static(figure, x_ax="", y_ax=""):
5454
y_ax: title of the y-axis
5555
---------------------------------------
5656
"""
57-
new_title = update_title(figure.layout.title.text)
57+
main_title, subtitle = split_title_and_subtitle(figure.layout.title.text)
58+
title_html = f'<span style="font-size: calc(1.5vh + 0.5vw);">{main_title}</span>'
59+
if subtitle:
60+
title_html += (
61+
'<br><span style="display:block; font-size:calc(1vh + 0.4vw);margin-top:1vh;">' + subtitle + "</span>"
62+
)
5863
figure.update_layout(
5964
autosize=True,
6065
margin=dict(l=50, r=10, b=10, t=67, pad=0),
6166
width=None,
6267
height=None,
6368
title={
64-
"y": 0.95,
69+
"y": 0.94,
6570
"x": 0.5,
6671
"xanchor": "center",
6772
"yanchor": "top",
68-
# update title and font-size of the title
69-
"text": '<span style="font-size: 1.2vw;">' + new_title + "</span>",
73+
"text": title_html,
7074
},
7175
)
7276
# update x title and font-size of the title
73-
figure.update_xaxes(title='<span style="font-size: 1vw;">' + x_ax + "</span>", automargin=True)
77+
figure.update_xaxes(
78+
title='<span style="font-size: calc(0.45rem + 0.7vw);">' + x_ax + "</span>", automargin=True
79+
)
7480
# update y title and font-size of the title
75-
figure.update_yaxes(title='<span style="font-size: 1vw;">' + y_ax + "</span>", automargin=True)
81+
figure.update_yaxes(
82+
title='<span style="font-size: calc(0.45rem + 0.7vw);">' + y_ax + "</span>", automargin=True
83+
)
7684

7785

78-
def update_title(title):
86+
def split_title_and_subtitle(title: str):
7987
"""
80-
adapt title content the app layout
88+
Split an HTML-formatted title into a main title and an optional subtitle.
89+
90+
The function searches for a specific separator in the input string:
91+
a line break followed by either a <sup>...</sup> or <span ...>...</span> block,
92+
i.e., "<br><sup>...</sup>" or "<br><span ...>...</span>". If the pattern is
93+
present and the entire string matches this structure, it returns a tuple with
94+
the text before the separator as the main title and the inner text of the
95+
<sup> or <span> element as the subtitle. If no such pattern is found, it
96+
returns the original title and None.
97+
8198
Parameters
8299
----------
83100
title : str
84-
string to ba adapted
101+
The full title string, optionally containing "<br><sup>...</sup>" or
102+
"<br><span ...>...</span>" at the end.
103+
85104
Returns
86105
-------
87-
str
106+
tuple[str, Optional[str]]
107+
(main_title, subtitle) where subtitle is None when no subtitle is detected.
108+
If a subtitle tag is present but empty, an empty string is returned.
109+
110+
Notes
111+
-----
112+
- The match is anchored to the start and end of the string; the subtitle (if any)
113+
must appear as the final part of the title.
114+
- Attributes inside the <span> tag are allowed and ignored.
115+
- Whitespace is preserved as-is.
116+
117+
Examples
118+
--------
119+
>>> split_title_and_subtitle("Report<br><sup>Q1 2026</sup>")
120+
('Report', 'Q1 2026')
121+
>>> split_title_and_subtitle('Sales<br><span class="sub">Forecast</span>')
122+
('Sales', 'Forecast')
123+
>>> split_title_and_subtitle("Overview")
124+
('Overview', None)
88125
"""
89-
patt = re.compile("^(.+)<span.+?(Predict: .*|Proba: .*)?</span>$")
90-
try:
91-
list_non_empty_str_matches = [x for x in patt.findall(title)[0] if x != ""]
92-
updated = " - ".join(map(str, list_non_empty_str_matches))
93-
except Exception:
94-
updated = title
95-
return updated
126+
match = re.match(r"^(.*?)(?:<br><(?:sup|span)[^>]*>(.*?)</(?:sup|span)>)?$", title)
127+
if match:
128+
main_title = match.group(1)
129+
subtitle = match.group(2) if match.lastindex and match.lastindex >= 2 else None
130+
return main_title, subtitle
131+
return title, None

shapash/webapp/utils/callbacks.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,10 @@ def create_dropdown_feature_filter(n_clicks_add: Optional[int], options: list) -
599599
# div with dopdown button to select feature to filter
600600
html.Div(
601601
dcc.Dropdown(
602-
id={"type": "var_dropdown", "index": index_id}, options=options, placeholder="Variable"
602+
id={"type": "var_dropdown", "index": index_id},
603+
options=options,
604+
placeholder="Variable",
605+
style={"line-height": "1.2vh", "height": "1.2vh"},
603606
),
604607
style={"width": "30%"},
605608
),

0 commit comments

Comments
 (0)