Spaces:
Running
Running
Commit
•
ece1a60
1
Parent(s):
83c2d47
Update app.py
Browse files
app.py
CHANGED
@@ -1,134 +1,190 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
6 |
import panel as pn
|
7 |
import param
|
8 |
-
from
|
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 |
-
"""A component that demonstrates how to run a Blocking Background task asynchronously
|
67 |
-
in Panel"""
|
68 |
-
|
69 |
-
select = param.Selector(objects=range(10))
|
70 |
-
slider = param.Number(2, bounds=(0, 10))
|
71 |
-
|
72 |
-
run_blocking_task = param.Event(label="RUN")
|
73 |
-
result = param.Number(0)
|
74 |
-
view = param.Parameter()
|
75 |
|
76 |
def __init__(self, **params):
|
77 |
super().__init__(**params)
|
78 |
|
79 |
-
self.
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
),
|
87 |
-
|
88 |
-
pn.pane.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
pn.Param(
|
90 |
self,
|
91 |
-
parameters=["
|
92 |
-
widgets={
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
show_name=False,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
),
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
)
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
result = await wrap_future(future)
|
117 |
-
self._update(result)
|
118 |
-
|
119 |
-
@progress.increment()
|
120 |
-
def _update(self, number):
|
121 |
-
self.result += number
|
122 |
-
|
123 |
-
@staticmethod
|
124 |
-
def _run_blocking_task():
|
125 |
-
time.sleep(np.random.randint(1, 2))
|
126 |
-
return 5
|
127 |
|
128 |
if pn.state.served:
|
129 |
-
pn.extension()
|
130 |
-
|
131 |
-
component = AsyncComponent()
|
132 |
-
pn.template.FastListTemplate(
|
133 |
-
site="Awesome Panel", site_url="https://awesome-panel.org", title="Async Tasks", main=[component], main_layout=None, main_max_width="400px"
|
134 |
-
).servable()
|
|
|
1 |
+
"""
|
2 |
+
See https://awesome-panel.org/resources/classic_dashboard/
|
3 |
+
"""
|
4 |
+
import pathlib
|
5 |
+
|
6 |
+
import holoviews as hv
|
7 |
+
import hvplot.pandas # pylint: disable=unused-import
|
8 |
+
import pandas as pd
|
9 |
import panel as pn
|
10 |
import param
|
11 |
+
from holoviews.plotting.util import process_cmap
|
12 |
+
|
13 |
+
DASHBOARD_A_PATH="https://cdn.awesome-panel.org/resources/classic_dashboard/dashboard_A.csv"
|
14 |
+
DASHBOARD_B_PATH="https://cdn.awesome-panel.org/resources/classic_dashboard/dashboard_B.csv"
|
15 |
+
|
16 |
+
COLOR_MAPS = hv.plotting.util.list_cmaps()
|
17 |
+
STYLE = """
|
18 |
+
body {
|
19 |
+
margin: 0px;
|
20 |
+
min-height: 100vh;
|
21 |
+
overflow-x: hidden;
|
22 |
+
width: 100%;
|
23 |
+
background: #f2f2f2;
|
24 |
+
}
|
25 |
+
.bk.app-body {
|
26 |
+
background: #f2f2f2;
|
27 |
+
color: #000000;
|
28 |
+
font-family: roboto, sans-serif, Verdana;
|
29 |
+
}
|
30 |
+
.bk.app-bar {
|
31 |
+
background: #212121;
|
32 |
+
border-color: white;
|
33 |
+
box-shadow: 5px 5px 20px #9E9E9E;
|
34 |
+
color: #ffffff;
|
35 |
+
z-index: 50;
|
36 |
+
}
|
37 |
+
.bk.app-container {
|
38 |
+
background: #ffffff;
|
39 |
+
border-radius: 5px;
|
40 |
+
box-shadow: 2px 2px 2px lightgrey;
|
41 |
+
color: #000000;
|
42 |
+
}
|
43 |
+
|
44 |
+
.bk.app-settings {
|
45 |
+
background: #e0e0e0;
|
46 |
+
color: #000000;
|
47 |
+
}
|
48 |
+
|
49 |
+
"""
|
50 |
+
|
51 |
+
DATA_A = pd.read_csv(DASHBOARD_A_PATH, index_col=0)
|
52 |
+
DATA_B = pd.read_csv(DASHBOARD_B_PATH, index_col=0)
|
53 |
+
|
54 |
+
|
55 |
+
class Dashboard(pn.viewable.Viewer):
|
56 |
+
"""This application show cases how to build a Classic Dashboard
|
57 |
+
in Panel.
|
58 |
+
"""
|
59 |
+
|
60 |
+
tool = param.ObjectSelector(label="Tool", default="S1_1", objects=["S1_1", "S2_1"])
|
61 |
+
variable = param.ObjectSelector(
|
62 |
+
label="Variable",
|
63 |
+
default="Cut Distance",
|
64 |
+
objects=["Cut Distance", "Removed Volume", "Av. uncut chip thickness"],
|
65 |
+
)
|
66 |
+
color_map = param.ObjectSelector(default="rainbow", objects=COLOR_MAPS)
|
67 |
+
|
68 |
+
view = param.ClassSelector(class_=pn.Column)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
def __init__(self, **params):
|
71 |
super().__init__(**params)
|
72 |
|
73 |
+
self.insert_plot_pane = pn.pane.HoloViews(
|
74 |
+
self._get_insert_plot, sizing_mode="stretch_width", margin=10, height=300
|
75 |
+
)
|
76 |
+
self.edge_plot_pane = pn.pane.HoloViews(
|
77 |
+
self._get_edge_plot, sizing_mode="stretch_width", margin=10, height=300
|
78 |
+
)
|
79 |
+
self.history_plot_pane = pn.pane.HoloViews(
|
80 |
+
self._update_history_plot, sizing_mode="stretch_width", margin=10, height=300
|
81 |
+
)
|
82 |
+
self.view = pn.Column(sizing_mode="stretch_both")
|
83 |
+
self._init_view()
|
84 |
+
|
85 |
+
def _init_view(self):
|
86 |
+
appbar = pn.Row(
|
87 |
+
pn.pane.Markdown(
|
88 |
+
"#### Classic Dashboard in Panel ",
|
89 |
+
margin=(15, 5, 5, 25),
|
90 |
+
sizing_mode="stretch_width",
|
91 |
+
align="center",
|
92 |
),
|
93 |
+
pn.layout.HSpacer(height=0),
|
94 |
+
pn.pane.PNG(
|
95 |
+
"https://panel.holoviz.org/_static/logo_horizontal.png",
|
96 |
+
width=200,
|
97 |
+
align="center",
|
98 |
+
sizing_mode="fixed",
|
99 |
+
margin=(10, 50, 10, 5),
|
100 |
+
embed=False,
|
101 |
+
),
|
102 |
+
sizing_mode="stretch_width",
|
103 |
+
css_classes=["app-bar"],
|
104 |
+
)
|
105 |
+
settings_bar = pn.Column(
|
106 |
pn.Param(
|
107 |
self,
|
108 |
+
parameters=["tool", "variable", "color_map"],
|
109 |
+
widgets={
|
110 |
+
"tool": {"align": "center", "width": 75, "sizing_mode": "fixed"},
|
111 |
+
"variable": {
|
112 |
+
"type": pn.widgets.RadioBoxGroup,
|
113 |
+
"inline": True,
|
114 |
+
"align": "end",
|
115 |
+
"sizing_mode": "stretch_width",
|
116 |
+
},
|
117 |
+
},
|
118 |
+
default_layout=pn.Row,
|
119 |
show_name=False,
|
120 |
+
sizing_mode="stretch_width",
|
121 |
+
),
|
122 |
+
pn.layout.HSpacer(height=0),
|
123 |
+
sizing_mode="stretch_width",
|
124 |
+
css_classes=["app-container"],
|
125 |
+
margin=(50, 25, 25, 25),
|
126 |
+
)
|
127 |
+
|
128 |
+
self.view[:] = [ # pylint: disable=unsupported-assignment-operation
|
129 |
+
pn.Column(
|
130 |
+
appbar,
|
131 |
+
settings_bar,
|
132 |
+
pn.Row(
|
133 |
+
pn.Column(
|
134 |
+
self.insert_plot_pane,
|
135 |
+
css_classes=["app-container"],
|
136 |
+
margin=25,
|
137 |
+
sizing_mode="stretch_both",
|
138 |
+
),
|
139 |
+
pn.Column(
|
140 |
+
self.edge_plot_pane,
|
141 |
+
css_classes=["app-container"],
|
142 |
+
margin=25,
|
143 |
+
sizing_mode="stretch_both",
|
144 |
+
),
|
145 |
+
sizing_mode="stretch_both",
|
146 |
+
min_height=300,
|
147 |
+
),
|
148 |
+
pn.Row(
|
149 |
+
self.history_plot_pane,
|
150 |
+
css_classes=["app-container"],
|
151 |
+
margin=25,
|
152 |
+
min_height=300,
|
153 |
+
sizing_mode="stretch_both",
|
154 |
+
),
|
155 |
+
css_classes=["app-body"],
|
156 |
+
sizing_mode="stretch_both",
|
157 |
),
|
158 |
+
pn.layout.HSpacer(height=25),
|
159 |
+
]
|
160 |
+
|
161 |
+
@pn.depends("tool", "variable", "color_map")
|
162 |
+
def _get_insert_plot(self):
|
163 |
+
plot_data = DATA_A.loc[self.tool]
|
164 |
+
data = [(plot_data["Xo"], plot_data["Yo"], plot_data[self.variable])]
|
165 |
+
return hv.Path(data, vdims=self.variable).opts(
|
166 |
+
cmap=self.color_map, color=self.variable, line_width=4, colorbar=True, responsive=True
|
167 |
)
|
168 |
|
169 |
+
@pn.depends("tool", "variable", "color_map")
|
170 |
+
def _get_edge_plot(self):
|
171 |
+
plot_data = DATA_A.loc[self.tool]
|
172 |
+
return plot_data.hvplot(
|
173 |
+
x="Number", y=self.variable, kind="area", alpha=0.6, color=self._color, responsive=True
|
174 |
+
)
|
175 |
+
|
176 |
+
@pn.depends("tool", "color_map")
|
177 |
+
def _update_history_plot(self):
|
178 |
+
plot_data = DATA_B.loc[self.tool]
|
179 |
+
return plot_data.hvplot(
|
180 |
+
x="Cut Distance", y="Feed", kind="line", line_width=4, responsive=True
|
181 |
+
).opts(color=self._color)
|
182 |
+
|
183 |
+
@property
|
184 |
+
def _color(self):
|
185 |
+
return process_cmap(self.color_map, 1)[0]
|
186 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
|
188 |
if pn.state.served:
|
189 |
+
pn.extension(raw_css=[STYLE], design="bootstrap")
|
190 |
+
Dashboard().view.servable()
|
|
|
|
|
|
|
|