Jon Solow commited on
Commit
71f25bb
1 Parent(s): 33ea4bb

Change to use custom html and css grid

Browse files
src/pages/80_Maximum_Roster_Strategy.py CHANGED
@@ -1,8 +1,10 @@
1
  import pandas as pd
2
  import streamlit as st
 
 
3
 
4
  from config import DEFAULT_ICON
5
- from shared_page import common_page_config
6
  from maximum_roster_strategy import data_loader
7
 
8
 
@@ -27,20 +29,36 @@ def load_data():
27
  return data_loader.get_google_sheet_data()
28
 
29
 
30
- def get_player_container(player_series: pd.Series):
31
- with st.expander(label=player_series["Formatted"]):
32
- st.write(player_series["Hold Condition"])
33
- if isinstance(notes := player_series["Article Notes"], str):
34
- st.write(notes)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
 
 
36
 
37
- # https://github.com/alanjones2/alan-jones-article-code/blob/master/stgrid/app/gridapp.py
38
- def make_grid(cols, rows):
39
- grid = [0] * cols
40
- for i in range(cols):
41
- with st.container():
42
- grid[i] = st.columns(rows[i])
43
- return grid
44
 
45
 
46
  def get_position_breakdown(df: pd.DataFrame, position_abbr: str, position_full_str: str):
@@ -48,21 +66,29 @@ def get_position_breakdown(df: pd.DataFrame, position_abbr: str, position_full_s
48
  st.header(position_full_str)
49
  df_pos = df[df["Position"] == position_abbr]
50
  time_slots = df.sort_values("WeekTimeSlotIndex")["TimeSlotName"].unique().tolist()
 
 
 
 
51
  tier_list = list(range(MIN_TIER, MAX_TIER + 1))
52
- num_time_slots = len(time_slots)
53
- column_len_list = [num_time_slots] + [1, num_time_slots] * len(tier_list)
54
- tier_time_grid = make_grid(len(tier_list) * 2 + 1, column_len_list)
55
-
56
- for time_idx, time_slot in enumerate(time_slots):
57
- with tier_time_grid[0][time_idx]:
58
- st.markdown(f"<h3 style='text-align: center;'>{time_slot}</h3>", unsafe_allow_html=True)
59
- for tier_idx, tier in enumerate(tier_list):
60
- if time_idx == 0:
61
- with tier_time_grid[(tier_idx + 1) * 2 - 1][0]:
62
- st.markdown(f"<h4 style='text-align: center;'>Tier {tier}</h4>", unsafe_allow_html=True)
63
  df_tier_slot = df_pos[(df_pos["TimeSlotName"] == time_slot) & (df_pos["Tier"] == tier)]
64
- with tier_time_grid[(tier_idx + 1) * 2][time_idx]:
65
- df_tier_slot.apply(get_player_container, axis=1)
 
 
 
 
 
 
 
 
 
 
 
66
 
67
 
68
  def get_page():
 
1
  import pandas as pd
2
  import streamlit as st
3
+ import streamlit.components.v1 as components
4
+
5
 
6
  from config import DEFAULT_ICON
7
+ from shared_page import common_page_config, get_local_style
8
  from maximum_roster_strategy import data_loader
9
 
10
 
 
29
  return data_loader.get_google_sheet_data()
30
 
31
 
32
+ def get_player_grid_div(player_series: pd.Series) -> str:
33
+ player_notes = player_series["Hold Condition"]
34
+ if isinstance(player_weekly_note := player_series["Article Notes"], str):
35
+ player_notes += "<br><br>" + player_weekly_note
36
+ return f"""
37
+ <details class="mrs-grid-player content">
38
+ <summary>
39
+ {player_series["Formatted"]}
40
+ </summary>
41
+ <p>
42
+ {player_notes}
43
+ </p>
44
+ </details>
45
+ """
46
+
47
+
48
+ def get_time_slot_div(time_slot_list: list[str]) -> str:
49
+ code_str = ""
50
+ for time_slot_idx, time_slot in enumerate(time_slot_list):
51
+ code_str += f"""<div class="timeslot{time_slot_idx + 1} timeslot">{time_slot}</div>\n"""
52
+ return code_str
53
+
54
 
55
+ def get_tier_div(tier_str: str | int, tier_num: str | int) -> str:
56
+ return f"""<div class="tier{tier_num} tier">Tier {tier_str}</div>"""
57
 
58
+
59
+ def get_player_container(df_players: pd.DataFrame, slot_number: int | str) -> str:
60
+ player_code_str = "\n".join(df_players.apply(get_player_grid_div, axis=1).tolist())
61
+ return f"""<div class="playerslot{slot_number} playerslot">{player_code_str}</div>"""
 
 
 
62
 
63
 
64
  def get_position_breakdown(df: pd.DataFrame, position_abbr: str, position_full_str: str):
 
66
  st.header(position_full_str)
67
  df_pos = df[df["Position"] == position_abbr]
68
  time_slots = df.sort_values("WeekTimeSlotIndex")["TimeSlotName"].unique().tolist()
69
+
70
+ grid_code_str = ""
71
+ grid_code_str += get_time_slot_div(time_slots)
72
+
73
  tier_list = list(range(MIN_TIER, MAX_TIER + 1))
74
+ slot_number = 0
75
+ for tier_idx, tier in enumerate(tier_list):
76
+ grid_code_str += get_tier_div(tier, tier_idx + 1)
77
+ for time_slot in time_slots:
 
 
 
 
 
 
 
78
  df_tier_slot = df_pos[(df_pos["TimeSlotName"] == time_slot) & (df_pos["Tier"] == tier)]
79
+ slot_number += 1
80
+ grid_code_str += get_player_container(df_tier_slot, slot_number)
81
+
82
+ components.html(
83
+ f"""
84
+ {get_local_style()}
85
+ <div class="grid-container-{len(time_slots)}">
86
+ {grid_code_str}
87
+ </div>
88
+ """,
89
+ height=1000,
90
+ scrolling=True,
91
+ )
92
 
93
 
94
  def get_page():
src/shared_page.py CHANGED
@@ -5,12 +5,18 @@ from page_selector import remove_seasonal_pages
5
  from login_component import get_authorization_button
6
 
7
 
8
- def local_css(file_name):
9
- with open(file_name) as f:
10
- st.markdown("<style>{}</style>".format(f.read()), unsafe_allow_html=True)
 
 
 
 
 
 
11
 
12
 
13
  def common_page_config():
 
14
  get_authorization_button()
15
  remove_seasonal_pages()
16
- local_css(os.path.join(os.path.dirname(__file__), "style.css"))
 
5
  from login_component import get_authorization_button
6
 
7
 
8
+ def get_local_style():
9
+ code_str = ""
10
+ with open(os.path.join(os.path.dirname(__file__), "style.css")) as f:
11
+ code_str = "<style>{}</style>".format(f.read())
12
+ return code_str
13
+
14
+
15
+ def local_css():
16
+ return st.markdown(get_local_style(), unsafe_allow_html=True)
17
 
18
 
19
  def common_page_config():
20
+ local_css()
21
  get_authorization_button()
22
  remove_seasonal_pages()
 
src/style.css CHANGED
@@ -11,4 +11,90 @@ div[data-testid="stHorizontalBlock"] {
11
 
12
  div[data-testid="stVerticalBlock"] {
13
  gap: 0;
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  div[data-testid="stVerticalBlock"] {
13
  gap: 0;
14
+ }
15
+
16
+
17
+ .mrs-grid-player {
18
+ font-size: x-small;
19
+ margin-bottom: 5px;
20
+ padding-left: 4px;
21
+ padding-right: 4px;
22
+ }
23
+
24
+ .tier {
25
+ text-align: center;
26
+ }
27
+
28
+ .timeslot {
29
+ text-align: center;
30
+ }
31
+
32
+ .tier1 {
33
+ border: 2px solid blue;
34
+ }
35
+ .tier2 {
36
+ border: 2px solid gold;
37
+ }
38
+
39
+ .tier3 {
40
+ border: 2px solid silver;
41
+ }
42
+
43
+ .tier4 {
44
+ border: 2px solid brown;
45
+ }
46
+
47
+
48
+ .playerslot {
49
+ border-left: 1px solid white;
50
+ border-right: 1px solid white;
51
+ }
52
+
53
+ .grid-container-7 {
54
+ display: grid;
55
+ grid-template-columns: repeat(7, 1fr);
56
+ grid-template-rows: repeat(9, auto);
57
+ grid-column-gap: 0px;
58
+ grid-row-gap: 10px;
59
+ color: white;
60
+ }
61
+
62
+ .timeslot1 { grid-area: 1 / 1 / 2 / 2; }
63
+ .timeslot2 { grid-area: 1 / 2 / 2 / 3; }
64
+ .timeslot3 { grid-area: 1 / 3 / 2 / 4; }
65
+ .timeslot4 { grid-area: 1 / 4 / 2 / 5; }
66
+ .timeslot5 { grid-area: 1 / 5 / 2 / 6; }
67
+ .timeslot6 { grid-area: 1 / 6 / 2 / 7; }
68
+ .timeslot7 { grid-area: 1 / 7 / 2 / 8; }
69
+ .tier1 { grid-area: 2 / 1 / 3 / 8; }
70
+ .playerslot1 { grid-area: 3 / 1 / 4 / 2; }
71
+ .playerslot2 { grid-area: 3 / 2 / 4 / 3; }
72
+ .playerslot3 { grid-area: 3 / 3 / 4 / 4; }
73
+ .playerslot4 { grid-area: 3 / 4 / 4 / 5; }
74
+ .playerslot5 { grid-area: 3 / 5 / 4 / 6; }
75
+ .playerslot6 { grid-area: 3 / 6 / 4 / 7; }
76
+ .playerslot7 { grid-area: 3 / 7 / 4 / 8; }
77
+ .tier2 { grid-area: 4 / 1 / 5 / 8; }
78
+ .playerslot8 { grid-area: 5 / 1 / 6 / 2; }
79
+ .playerslot9 { grid-area: 5 / 2 / 6 / 3; }
80
+ .playerslot10 { grid-area: 5 / 3 / 6 / 4; }
81
+ .playerslot11 { grid-area: 5 / 4 / 6 / 5; }
82
+ .playerslot12 { grid-area: 5 / 5 / 6 / 6; }
83
+ .playerslot13 { grid-area: 5 / 6 / 6 / 7; }
84
+ .playerslot14 { grid-area: 5 / 7 / 6 / 8; }
85
+ .tier3 { grid-area: 6 / 1 / 7 / 8; }
86
+ .playerslot15 { grid-area: 7 / 1 / 8 / 2; }
87
+ .playerslot16 { grid-area: 7 / 2 / 8 / 3; }
88
+ .playerslot17 { grid-area: 7 / 3 / 8 / 4; }
89
+ .playerslot18 { grid-area: 7 / 4 / 8 / 5; }
90
+ .playerslot19 { grid-area: 7 / 5 / 8 / 6; }
91
+ .playerslot20 { grid-area: 7 / 6 / 8 / 7; }
92
+ .playerslot21 { grid-area: 7 / 7 / 8 / 8; }
93
+ .tier4 { grid-area: 8 / 1 / 9 / 8; }
94
+ .playerslot22 { grid-area: 9 / 1 / 10 / 2; }
95
+ .playerslot23 { grid-area: 9 / 2 / 10 / 3; }
96
+ .playerslot24 { grid-area: 9 / 3 / 10 / 4; }
97
+ .playerslot25 { grid-area: 9 / 4 / 10 / 5; }
98
+ .playerslot26 { grid-area: 9 / 5 / 10 / 6; }
99
+ .playerslot27 { grid-area: 9 / 6 / 10 / 7; }
100
+ .playerslot28 { grid-area: 9 / 7 / 10 / 8; }