MarcSkovMadsen's picture
Update index.js
2c81abe
importScripts("https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js");
function sendPatch(patch, buffers, msg_id) {
self.postMessage({
type: 'patch',
patch: patch,
buffers: buffers
})
}
async function startApplication() {
console.log("Loading pyodide!");
self.postMessage({type: 'status', msg: 'Loading pyodide'})
self.pyodide = await loadPyodide();
self.pyodide.globals.set("sendPatch", sendPatch);
console.log("Loaded!");
await self.pyodide.loadPackage("micropip");
const env_spec = ['https://cdn.holoviz.org/panel/wheels/bokeh-3.3.2-py3-none-any.whl', 'https://cdn.holoviz.org/panel/1.3.6/dist/wheels/panel-1.3.6-py3-none-any.whl', 'pyodide-http==0.2.1', 'hvplot', 'pandas']
for (const pkg of env_spec) {
let pkg_name;
if (pkg.endsWith('.whl')) {
pkg_name = pkg.split('/').slice(-1)[0].split('-')[0]
} else {
pkg_name = pkg
}
self.postMessage({type: 'status', msg: `Installing ${pkg_name}`})
try {
await self.pyodide.runPythonAsync(`
import micropip
await micropip.install('${pkg}');
`);
} catch(e) {
console.log(e)
self.postMessage({
type: 'status',
msg: `Error while installing ${pkg_name}`
});
}
}
console.log("Packages loaded!");
self.postMessage({type: 'status', msg: 'Executing code'})
const code = `
import asyncio
from panel.io.pyodide import init_doc, write_doc
init_doc()
"""The purpose of this app is to test that a **multi-page Dashboard Layout** similar to the
[bootstrap dashboard template](https://getbootstrap.com/docs/4.3/examples/dashboard/)
from [getboostrap.com](https://getbootstrap.com/) can be implemented in
[Panel](https://panel.pyviz.org/).
"""
import hvplot.pandas # pylint: disable=unused-import
import pandas as pd
import panel as pn
BOOTSTRAP_DASHBOARD_CHART_URL="https://awesomepanel.blob.core.windows.net/resources/bootstrap_dashboard/bootstrap_dashboard_chart.csv"
BOOTSTRAP_DASHBOARD_TABLE_URL="https://awesomepanel.blob.core.windows.net/resources/bootstrap_dashboard/bootstrap_dashboard_table.csv"
COLOR="#0072B5"
@pn.cache
def _get_chart_data():
return pd.read_csv(BOOTSTRAP_DASHBOARD_CHART_URL)
@pn.cache
def _get_table_data():
return pd.read_csv(BOOTSTRAP_DASHBOARD_TABLE_URL)
def _holoviews_chart():
"""## Dashboard Orders Chart generated by HoloViews"""
data = _get_chart_data()
line_plot = data.hvplot.line(
x="Day",
y="Orders",
height=500,
line_color=COLOR,
line_width=6,
)
scatter_plot = data.hvplot.scatter(x="Day", y="Orders", height=300,).opts(
marker="o",
size=10,
color=COLOR,
)
fig = line_plot * scatter_plot
gridstyle = {
"grid_line_color": "black",
"grid_line_width": 0.1,
}
fig = fig.opts(
responsive=True,
toolbar=None,
yticks=list(
range(
12000,
26000,
2000,
)
),
ylim=(
12000,
26000,
),
gridstyle=gridstyle,
show_grid=True,
)
return fig
app = pn.extension("tabulator", sizing_mode="stretch_width")
pn.template.FastListTemplate(
site="Awesome Panel", site_url="https://awesome-panel.org", title="Bootstrap Dashboard",
main=[
pn.Column(
pn.pane.Markdown("## Dashboard"),
_holoviews_chart()),
pn.Column(pn.pane.Markdown("## Section Title"),
pn.widgets.Tabulator(_get_table_data(), layout='fit_data_stretch')),
], main_max_width="800px", main_layout=None,
).servable()
await write_doc()
`
try {
const [docs_json, render_items, root_ids] = await self.pyodide.runPythonAsync(code)
self.postMessage({
type: 'render',
docs_json: docs_json,
render_items: render_items,
root_ids: root_ids
})
} catch(e) {
const traceback = `${e}`
const tblines = traceback.split('\n')
self.postMessage({
type: 'status',
msg: tblines[tblines.length-2]
});
throw e
}
}
self.onmessage = async (event) => {
const msg = event.data
if (msg.type === 'rendered') {
self.pyodide.runPythonAsync(`
from panel.io.state import state
from panel.io.pyodide import _link_docs_worker
_link_docs_worker(state.curdoc, sendPatch, setter='js')
`)
} else if (msg.type === 'patch') {
self.pyodide.globals.set('patch', msg.patch)
self.pyodide.runPythonAsync(`
state.curdoc.apply_json_patch(patch.to_py(), setter='js')
`)
self.postMessage({type: 'idle'})
} else if (msg.type === 'location') {
self.pyodide.globals.set('location', msg.location)
self.pyodide.runPythonAsync(`
import json
from panel.io.state import state
from panel.util import edit_readonly
if state.location:
loc_data = json.loads(location)
with edit_readonly(state.location):
state.location.param.update({
k: v for k, v in loc_data.items() if k in state.location.param
})
`)
}
}
startApplication()