-
Notifications
You must be signed in to change notification settings - Fork 99
/
Copy pathapp.py
107 lines (93 loc) · 3.02 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import pandas as pd
import seaborn as sns
from shinyswatch.theme import darkly
from shiny import App, Inputs, reactive, render, req, ui
def app_ui(req):
dark = True if "dark" in req.query_params else None
return ui.page_fluid(
ui.head_content(
ui.tags.meta(name="viewport", content="width=device-width, initial-scale=1")
),
darkly() if dark else None,
light_dark_switcher(dark),
ui.input_select("dataset", "Dataset", sns.get_dataset_names()),
ui.input_select(
"selection_mode",
"Selection mode",
{
"none": "(None)",
"row": "Single row",
"rows": "Multiple rows",
},
selected="multiple",
),
ui.input_switch("editable", "Edit", False),
ui.input_switch("filters", "Filters", True),
ui.input_switch("gridstyle", "Grid", True),
ui.input_switch("fullwidth", "Take full width", True),
ui.output_data_frame("grid"),
ui.panel_fixed(
ui.output_code("detail"),
right="10px",
bottom="10px",
),
class_="p-3",
)
def light_dark_switcher(dark):
return (
ui.div(
ui.a(
{"class": "btn-primary" if not dark else "btn-outline-primary"},
"Light",
href="?" if dark else None,
class_="btn",
),
ui.a(
{"class": "btn-primary" if dark else "btn-outline-primary"},
"Dark",
href="?dark=1" if not dark else None,
class_="btn",
),
class_="float-end btn-group",
),
)
def server(input: Inputs):
df: reactive.value[pd.DataFrame] = reactive.value()
@reactive.effect
def update_df():
return df.set(sns.load_dataset(req(input.dataset())))
@render.data_frame
def grid():
height = 350
width = "100%" if input.fullwidth() else "fit-content"
if input.gridstyle():
return render.DataGrid(
df(),
width=width,
height=height,
filters=input.filters(),
editable=input.editable(),
selection_mode=input.selection_mode(),
)
else:
return render.DataTable(
df(),
width=width,
height=height,
filters=input.filters(),
editable=input.editable(),
selection_mode=input.selection_mode(),
)
@reactive.effect
@reactive.event(input.grid_cell_edit)
def handle_edit():
edit = input.grid_cell_edit()
df_copy = df().copy()
df_copy.iat[edit["row"], edit["col"]] = edit["new_value"]
df.set(df_copy)
@render.code
def detail():
selected_rows = grid.cell_selection()["rows"]
if len(selected_rows) > 0:
return df().iloc[list(selected_rows)]
app = App(app_ui, server)