8000 Merge pull request #27 from anaconda/panel_deckgl · Positive-Conative/pyscript@956de2a · GitHub
[go: up one dir, main page]

Skip to content

Commit 956de2a

Browse files
authored
Merge pull request pyscript#27 from anaconda/panel_deckgl
Add Panel DeckGL example
2 parents 556feda + 05dbc2e commit 956de2a

File tree

4 files changed

+245
-20
lines changed

4 files changed

+245
-20
lines changed

pyscriptjs/examples/panel.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ <h1>Panel Example</h1>
2020
import asyncio
2121
import micropip
2222

23-
await micropip.install(['panel==0.13.0rc10'])
23+
await micropip.install(['panel'])
2424

2525
import panel as pn
2626

pyscriptjs/examples/panel_deckgl.html

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="apple-mobile-web-app-capable" content="yes">
6+
<meta name="apple-mobile-web-app-status-bar-style" content="default">
7+
<meta name="theme-color" content="#0072b5">
8+
<meta name="name" content="Pyscript/Panel DeckGL Demo">
9+
10+
<title>Pyscript/Panel DeckGL Demo</title>
11+
12+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" type="text/css" />
13+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/widgets.css" type="text/css" />
14+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/markdown.css" type="text/css" />
15+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/loading.css" type="text/css" />
16+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/dataframe.css" type="text/css" />
17+
18+
<script type="text/javascript" src="https://unpkg.com/h3-js@3.7.2/dist/h3-js.umd.js"></script>
19+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/deck.gl@8.6.7/dist.min.js"></script>
20+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@deck.gl/json@8.6.7/dist.min.js"></script>
21+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@loaders.gl/csv@3.1.7/dist/dist.min.js"></script>
22+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@loaders.gl/json@3.1.7/dist/dist.min.js"></script>
23+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@3.1.7/dist/dist.min.js"></script>
24+
<script type="text/javascript" src="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.js"></script>
25+
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.js"></script>
26+
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
27+
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
28+
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.0/dist/panel.js"></script>
29+
30+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
31+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/bundled/bootstraptemplate/bootstrap.css">
32+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/bundled/defaulttheme/default.css">
33+
34+
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
35+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
36+
<style>
37+
#sidebar {
38+
width: 400px;
39+
}
40+
</style>
41+
<link rel="stylesheet" href="../build/pyscript.css" />
42+
<script defer src="../build/pyscript.js"></script>
43+
</head>
44+
<body>
45+
<py-env>
46+
- bokeh
47+
- numpy
48+
- pandas
49+
</py-env>
50+
51+
<div class="container-fluid d-flex flex-column vh-100 overflow-hidden" id="container">
52+
<nav class="navbar navbar-expand-md navbar-dark sticky-top shadow" id="header" style="background-color: #0072b5;">
53+
<button type="button" class="navbar-toggle collapsed" id="sidebarCollapse">
54+
<span class="navbar-toggler-icon"></span>
55+
</button>
56+
<div class="app-header">
57+
<a class="title" href="/" >&nbsp;Panel</a>
58+
<span class="title">&nbsp;-</span>
59+
<a class="title" href="" >&nbsp;Pyscript DeckGL NYC Taxi</a>
60+
</div>
61+
</nav>
62+
63+
<div class="row overflow-hidden" id="content">
64+
<div class="sidenav" id="sidebar">
65+
<ul class="nav flex-column">
66+
<div class="bk-root" id="widgets" data-root-id="1021"></div>
67+
<py-repl id="my-repl" auto-generate="true"> </py-repl>
68+
</ul>
69+
</div>
70+
<div class="col mh-100 float-left" style="padding: 0;">
71+
<div class="bk- F438 root" id="plot" data-root-id="1008"></div>
72+
</div>
73+
</div>
74+
</div>
75+
<py-script>
76+
import asyncio
77+
import micropip
78+
79+
from io import StringIO
80+
from js import fetch
81+
82+
await micropip.install(['panel==0.13.1a1'])
83+
84+
import panel as pn
85+
import param
86+
import pandas as pd
87+
88+
from panel.io.pyodide import show
89+
90+
MAPBOX_KEY = "pk.eyJ1IjoicGFuZWxvcmciLCJhIjoiY2s1enA3ejhyMWhmZjNobjM1NXhtbWRrMyJ9.B_frQsAVepGIe-HiOJeqvQ"
91+
92+
class App(pn.viewable.Viewer):
93+
94+
data = param.DataFrame(precedence=-1)
95+
96+
view = param.DataFrame(precedence=-1)
97+
98+
arc_view = param.DataFrame(precedence=-1)
99+
100+
radius = param.Integer(default=50, bounds=(20, 1000))
101+
102+
elevation = param.Integer(default=10, bounds=(0, 50))
103+
104+
hour = param.Integer(default=0, bounds=(0, 23))
105+
106+
speed = param.Integer(default=1, bounds=(0, 10), precedence=-1)
107+
108+
play = param.Event(label='▷')
109+
110+
def __init__(self, **params):
111+
self.deck_gl = None
112+
super().__init__(**params)
113+
self.deck_gl = pn.pane.DeckGL(
114+
dict(self.spec), mapbox_api_key=MAPBOX_KEY, throttle={'click': 10},
115+
sizing_mode='stretch_both', margin=0)
116+
self.deck_gl.param.watch(self._update_arc_view, 'click_state')
117+
self._playing = False
118+
self._cb = pn.state.add_periodic_callback(
119+
self._update_hour, 1000//self.speed, start=False
120+
)
121+
122+
def __panel__(self):
123+
return self.deck_gl
124+
125+
@property
126+
def spec(self):
127+
return {
128+
"initialViewState": {
129+
"bearing": 0,
130+
"latitude": 40.7,
131+
"longitude": -73.9,
132+
"maxZoom": 15,
133+
"minZoom": 5,
134+
"pitch": 40.5,
135+
"zoom": 11
136+
},
137+
"layers": [self.hex_layer, self.arc_layer],
138+
"mapStyle": "mapbox://styles/mapbox/dark-v9",
139+
"views": [
140+
{"@@type": "MapView", "controller": True}
141+
]
142+
}
143+
144+
@property
145+
def hex_layer(self):
146+
return {
147+
"@@type": "HexagonLayer",
148+
"autoHighlight": True,
149+
"coverage": 1,
150+
"data": self.data if self.view is None else self.view,
151+
"elevationRange": [0, 100],
152+
"elevationScale": self.elevation,
153+
"radius": self.radius,
154+
"extruded": True,
155+
"getPosition": "@@=[pickup_x, pickup_y]",
156+
"id": "8a553b25-ef3a-489c-bbe2-e102d18a3211"
157+
}
158+
159+
@property
160+
def arc_layer(self):
161+
return {
162+
"@@type": "ArcLayer",
163+
"id": 'arc-layer',
164+
"data": self.arc_view,
165+
"pickable": True,
166+
"getWidth": 1,
167+
"getSourcePosition": "@@=[pickup_x, pickup_y]",
168+
"getTargetPosition": "@@=[dropoff_x, dropoff_y]",
169+
"getSourceColor": [0, 255, 0, 180],
170+
"getTargetColor": [240, 100, 0, 180]
171+
}
172+
173+
def _update_hour(self):
174+
self.hour = (self.hour+1) % 24
175+
176+
@param.depends('view', watch=True)
177+
def _update_arc_view(self, event=None):
178+
data = self.data if self.view is None else self.view
179+
if not self.deck_gl or not self.deck_gl.click_state:
180+
self.arc_view = data.iloc[:0]
181+
else:
182+
lon, lat = self.deck_gl.click_state['coordinate']
183+
tol = 0.001
184+
self.arc_view = data[
185+
(df.pickup_x>=float(lon-tol)) &
186+
(df.pickup_x<=float(lon+tol)) &
187+
(df.pickup_y>=float(lat-tol)) &
188+
(df.pickup_y<=float(lat+tol))
189+
]
190+
191+
@param.depends('hour', watch=True)
192+
def _update_hourly_view(self):
193+
self.view = self.data[self.data.hour==self.hour]
194+
195+
@param.depends('speed', watch=True)
196+
def _update_speed(self):
197+
self._cb.period = 1000//self.speed
198+
199+
@param.depends('play', watch=True)
200+
def _play_pause(self):
201+
if self._playing:
202+
self._cb.stop()
203+
self.param.play.label = '▷'
204+
self.param.speed.precedence = -1
205+
else:
206+
self._cb.start()
207+
self.param.play.label = '❚❚'
208+
self.param.speed.precedence = 1
209+
self._playing = not self._playing
210+
211+
@param.depends('view', 'radius', 'elevation', 'arc_view', watch=True)
212+
def update_spec(self):
213+
self.deck_gl.object = dict(self.spec)
214+
215+
216+
data = await fetch('https://s3.eu-west-1.amazonaws.com/assets.holoviews.org/data/nyc_taxi_wide.csv')
217+
df = pd.read_csv(StringIO(await data.text()))
218+
219+
app = App(data=df)
220+
controls = pn.Param(app.param, sizing_mode='stretch_width', show_name=False)
221+
222+
await show(controls, 'widgets')
223+
await show(app, 'plot')
224+
</py-script>
225+
</body>
226+
</html>

pyscriptjs/examples/panel_kmeans.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
<meta charset="utf-8">
55
<title>Pyscript/Panel KMeans Demo</title>
66

7-
<link rel="icon" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/icons/favicon.ico" type="">
7+
<link rel="icon" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/icons/favicon.ico" type="">
88
<meta name="name" content="PyScript/Panel KMeans Demo">
99

1010
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" type="text/css" />
11-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/css/widgets.css" type="text/css" />
12-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/css/markdown.css" type="text/css" />
13-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/css/loading.css" type="text/css" />
14-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/css/dataframe.css" type="text/css" />
11+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/widgets.css" type="text/css" />
12+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/markdown.css" type="text/css" />
13+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/loading.css" type="text/css" />
14+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/dataframe.css" type="text/css" />
1515

1616
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@5"></script>
1717
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
@@ -20,14 +20,14 @@
2020
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.js"></script>
2121
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
2222
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
23-
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/panel.min.js"></script>
23+
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.0/dist/panel.min.js"></script>
2424
<script type="text/javascript">
2525
Bokeh.set_log_level("info");
2626
</script>
2727

2828
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
29-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/bundled/bootstraptemplate/bootstrap.css">
30-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.10/dist/bundled/defaulttheme/default.css">
29+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/bundled/bootstraptemplate/bootstrap.css">
30+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/bundled/defaulttheme/default.css">
3131

3232
<style>
3333
#sidebar {
@@ -83,7 +83,7 @@
8383
from io import StringIO
8484
from js import fetch
8585

86-
await micropip.install(['panel==0.13.0rc10', 'altair'])
86+
await micropip.install(['panel', 'altair'])
8787

8888
import altair as alt
8989
import panel as pn

pyscriptjs/examples/panel_stream.html

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,27 @@
44
<meta charset="utf-8">
55
<title>PyScript/Panel Streaming Demo</title>
66

7-
<link rel="icon" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/icons/favicon.ico" type="">
7+
<link rel="icon" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/icons/favicon.ico" type="">
88
<meta name="name" content="PyScript/Panel Streaming Demo">
99

1010
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" type="text/css" />
11-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/css/widgets.css" type="text/css" />
12-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/css/markdown.css" type="text/css" />
13-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/css/loading.css" type="text/css" />
14-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/css/dataframe.css" type="text/css" />
11+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/widgets.css" type="text/css" />
12+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/markdown.css" type="text/css" />
13+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/loading.css" type="text/css" />
14+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/css/dataframe.css" type="text/css" />
1515

1616
<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.9.3/dist/js/tabulator.js"></script>
1717
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.js"></script>
1818
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
1919
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
20-
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/panel.min.js"></script>
20+
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.0/dist/panel.min.js"></script>
2121
<script type="text/javascript">
2222
Bokeh.set_log_level("info");
2323
</script>
2424

2525
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
26-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/bundled/bootstraptemplate/bootstrap.css">
27-
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0-rc.11/dist/bundled/defaulttheme/default.css">
26+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/bundled/bootstraptemplate/bootstrap.css">
27+
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.0/dist/bundled/defaulttheme/default.css">
2828

2929
<style>
3030
#sidebar {
@@ -43,7 +43,6 @@
4343
- bokeh
4444
- numpy
4545
- pandas
46-
- scikit-learn
4746
</py-env>
4847

4948
<div class="container-fluid d-flex flex-column vh-100 overflow-hidden" id="container">
@@ -72,7 +71,7 @@
7271
import asyncio
7372
import micropip
7473

75-
await micropip.install(['panel==0.13.0rc11', 'altair'])
74+
await micropip.install(['panel'])
7675

7776
import panel as pn
7877
import numpy as np

0 commit comments

Comments
 (0)
0