From 278da6da2c6279a3101ed36ac2c8aae8f62f7225 Mon Sep 17 00:00:00 2001 From: Tom Gotsman Date: Fri, 19 Jan 2024 14:18:02 -0800 Subject: [PATCH] converting nba app to radix --- nba_radix/.gitignore | 4 + nba_radix/assets/favicon.ico | Bin 0 -> 4286 bytes nba_radix/assets/nba.png | Bin 0 -> 14901 bytes nba_radix/nba_radix/__init__.py | 0 nba_radix/nba_radix/helpers.py | 39 ++++++++ nba_radix/nba_radix/nba_radix.py | 150 +++++++++++++++++++++++++++++++ nba_radix/requirements.txt | 1 + nba_radix/rxconfig.py | 5 ++ 8 files changed, 199 insertions(+) create mode 100644 nba_radix/.gitignore create mode 100644 nba_radix/assets/favicon.ico create mode 100644 nba_radix/assets/nba.png create mode 100644 nba_radix/nba_radix/__init__.py create mode 100644 nba_radix/nba_radix/helpers.py create mode 100644 nba_radix/nba_radix/nba_radix.py create mode 100644 nba_radix/requirements.txt create mode 100644 nba_radix/rxconfig.py diff --git a/nba_radix/.gitignore b/nba_radix/.gitignore new file mode 100644 index 00000000..eab0d4b0 --- /dev/null +++ b/nba_radix/.gitignore @@ -0,0 +1,4 @@ +*.db +*.py[cod] +.web +__pycache__/ \ No newline at end of file diff --git a/nba_radix/assets/favicon.ico b/nba_radix/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..166ae995eaa63fc96771410a758282dc30e925cf GIT binary patch literal 4286 zcmeHL>rYc>81ELdEe;}zmYd}cUgmJRfwjUwD1`#s5KZP>mMqza#Viv|_7|8f+0+bX zHuqusuw-7Ca`DTu#4U4^o2bjO#K>4%N?Wdi*wZ3Vx%~Ef4}D1`U_EMRg3u z#2#M|V>}}q-@IaO@{9R}d*u7f&~5HfxSkmHVcazU#i30H zAGxQ5Spe!j9`KuGqR@aExK`-}sH1jvqoIp3C7Vm)9Tu=UPE;j^esN~a6^a$ZILngo;^ zGLXl(ZFyY&U!li`6}y-hUQ99v?s`U4O!kgog74FPw-9g+V)qs!jFGEQyvBf><U|E2vRmx|+(VI~S=lT?@~C5pvZOd`x{Q_+3tG6H=gtdWcf z)+7-Zp=UqH^J4sk^>_G-Ufn-2Hz z2mN12|C{5}U`^eCQuFz=F%wp@}SzA1MHEaM^CtJs<{}Tzu$bx2orTKiedgmtVGM{ zdd#vX`&cuiec|My_KW;y{Ryz2kFu9}=~us6hvx1ZqQCk(d+>HP>ks>mmHCjjDh{pe zKQkKpk0SeDX#XMqf$}QV{z=xrN!mQczJAvud@;zFqaU1ocq==Py)qsa=8UKrt!J7r z{RsTo^rgtZo%$rak)DN*D)!(Y^$@yL6Nd=#eu&?unzhH8yq>v{gkt8xcG3S%H)-y_ zqQ1|v|JT$0R~Y}omg2Y+nDvR+K|kzR5i^fmKF>j~N;A35Vr`JWh4yRqKl#P|qlx?` z@|CmBiP}ysYO%m2{eBG6&ix5 zr#u((F2{vb=W4jNmTQh3M^F2o80T49?w>*rv0mt)-o1y!{hRk`E#UVPdna6jnz`rw dKpn)r^--YJZpr;bYU`N~>#v3X5BRU&{{=gv-{1fM literal 0 HcmV?d00001 diff --git a/nba_radix/assets/nba.png b/nba_radix/assets/nba.png new file mode 100644 index 0000000000000000000000000000000000000000..004b4ec6859860b63235d4e8eac699a74760bbdd GIT binary patch literal 14901 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 literal 0 HcmV?d00001 diff --git a/nba_radix/nba_radix/__init__.py b/nba_radix/nba_radix/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/nba_radix/nba_radix/helpers.py b/nba_radix/nba_radix/helpers.py new file mode 100644 index 00000000..e3076823 --- /dev/null +++ b/nba_radix/nba_radix/helpers.py @@ -0,0 +1,39 @@ +import reflex as rx +import reflex.components.radix.themes as rdxt + +def navbar(): + return rdxt.box( + rx.hstack( + rx.hstack( + rx.image(src="/nba.png", width="50px"), + rdxt.heading("NBA Data", size="8"), + rdxt.flex( + rdxt.badge("2015-2016 Season"), + ), + ), + rdxt.dropdownmenu_root( + rdxt.dropdownmenu_trigger( + rdxt.button("Menu", color="white", size="3", radius="medium", px=4, py=2), + ), + rdxt.dropdownmenu_content( + rdxt.link(rdxt.dropdownmenu_item("Graph"), href="/"), + rdxt.dropdownmenu_separator(), + rdxt.link( + rdxt.dropdownmenu_item( + rx.hstack(rdxt.text("20Dataset"), rdxt.icon(tag="download")) + ), + href="https://media.geeksforgeeks.org/wp-content/uploads/nba.csv", + ), + ), + ), + justify="space-between", + border_bottom="0.2em solid #F0F0F0", + padding_x="2em", + padding_y="1em", + bg="rgba(255,255,255, 0.97)", + ), + position="fixed", + width="100%", + top="0px", + z_index="500", + ) \ No newline at end of file diff --git a/nba_radix/nba_radix/nba_radix.py b/nba_radix/nba_radix/nba_radix.py new file mode 100644 index 00000000..327e8567 --- /dev/null +++ b/nba_radix/nba_radix/nba_radix.py @@ -0,0 +1,150 @@ +"""Welcome to Reflex! This file outlines the steps to create a basic app.""" +import reflex as rx +import pandas as pd +import plotly.express as px +import plotly.graph_objects as go +from .helpers import navbar +from reflex.components.radix.themes import theme +import reflex.components.radix.themes as rdxt + +nba_overview = "https://media.geeksforgeeks.org/wp-content/uploads/nba.csv" +nba_data = pd.read_csv(nba_overview) +college = sorted(nba_data["College"].unique().astype(str)) + + +class State(rx.State): + """The app state.""" + + # Filters to apply to the data. + position: str + college: str + age: tuple[int, int] = (18, 50) + salary: tuple[int, int] = (0, 25000000) + + @rx.var + def df(self) -> pd.DataFrame: + """The data.""" + nba = nba_data[ + (nba_data["Age"] > int(self.age[0])) + & (nba_data["Age"] < int(self.age[1])) + & (nba_data["Salary"] > int(self.salary[0])) + & (nba_data["Salary"] < int(self.salary[1])) + ] + + if self.college and self.college != "All": + nba = nba[nba["College"] == self.college] + + if self.position and self.position != "All": + nba = nba[nba["Position"] == self.position] + + if nba.empty: + return pd.DataFrame() + else: + return nba.fillna("") + + @rx.var + def scat_fig(self) -> go.Figure: + """The scatter figure.""" + nba = self.df + + if nba.empty: + return go.Figure() + else: + return px.scatter( + nba, + x="Age", + y="Salary", + title="NBA Age/Salary plot", + color=nba["Position"], + hover_data=["Name"], + symbol=nba["Position"], + trendline="lowess", + trendline_scope="overall", + ) + + @rx.var + def hist_fig(self) -> go.Figure: + """The histogram figure.""" + nba = self.df + + if nba.empty: + return go.Figure() + else: + return px.histogram( + nba, x="Age", y="Salary", title="Age/Salary Distribution" + ) + + +def selection(): + return rx.vstack( + rx.hstack( + rx.vstack( + rdxt.select( + ["C", "PF", "SF", "PG", "SG"], + placeholder="Select a position. (All)", + on_value_change=State.set_position, + size="3", + ), + rdxt.select( + college, + placeholder="Select a college. (All)", + on_value_change=State.set_college, + size="3", + ), + ), + rx.vstack( + rx.vstack( + rx.hstack( + rdxt.badge("Min Age: ", State.age[0]), + rdxt.separator(orientation="vertical"), + rdxt.badge("Max Age: ", State.age[1]), + ), + rdxt.slider(default_value=[18, 50], min=18, max=50, on_value_commit=State.set_age,), + align_items="left", + width="100%", + ), + rx.vstack( + rx.hstack( + rdxt.badge("Min Sal: ", State.salary[0] // 1000000, "M"), + rdxt.separator(orientation="vertical"), + rdxt.badge("Max Sal: ", State.salary[1] // 1000000, "M"), + ), + rdxt.slider( + default_value=[0, 25000000], min=0, max=25000000, on_value_commit=State.set_salary, + ), + align_items="left", + width="100%", + ), + ), + spacing="1em", + ), + width="100%", + ) + + +def index(): + """The main view.""" + return rx.center( + rx.vstack( + navbar(), + selection(), + rdxt.separator(width="100%"), + rx.plotly(data=State.scat_fig, layout={"width": "1000", "height": "600"}), + rx.plotly(data=State.hist_fig, layout={"width": "1000", "height": "600"}), + rx.data_table( + data=nba_data, + pagination=True, + search=True, + sort=True, + resizable=True, + ), + rdxt.separator(width="100%"), + padding_top="6em", + width="100%", + ) + ) + + + +app = rx.App(theme=theme(appearance="light", has_background=True, radius="large", accent_color="amber", gray_color="sand",)) +app.add_page(index, title="NBA App") \ No newline at end of file diff --git a/nba_radix/requirements.txt b/nba_radix/requirements.txt new file mode 100644 index 00000000..9520ecbd --- /dev/null +++ b/nba_radix/requirements.txt @@ -0,0 +1 @@ +reflex==0.3.7 diff --git a/nba_radix/rxconfig.py b/nba_radix/rxconfig.py new file mode 100644 index 00000000..919ea29a --- /dev/null +++ b/nba_radix/rxconfig.py @@ -0,0 +1,5 @@ +import reflex as rx + +config = rx.Config( + app_name="nba_radix", +) \ No newline at end of file