MarcSkovMadsen
commited on
Commit
•
597e03a
1
Parent(s):
0ac4332
Upload 5 files
Browse files- README.md +16 -4
- index.html +338 -18
- index.js +197 -0
- index.py +93 -0
- requirements.txt +2 -0
README.md
CHANGED
@@ -1,11 +1,23 @@
|
|
1 |
---
|
2 |
title: Streaming Indicators
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: static
|
7 |
pinned: false
|
8 |
license: mit
|
9 |
---
|
10 |
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
---
|
2 |
title: Streaming Indicators
|
3 |
+
emoji: ⚡
|
4 |
+
colorFrom: green
|
5 |
+
colorTo: red
|
6 |
sdk: static
|
7 |
pinned: false
|
8 |
license: mit
|
9 |
---
|
10 |
|
11 |
+
See [streaming_indicators](https://awesome-panel.org/resources/streaming_indicators/) by [awesome-panel.org](https://awesome-panel.org) for more info.
|
12 |
+
|
13 |
+
## Serve
|
14 |
+
|
15 |
+
```python
|
16 |
+
panel serve *.py --autoreload
|
17 |
+
```
|
18 |
+
|
19 |
+
## Build
|
20 |
+
|
21 |
+
```bash
|
22 |
+
panel convert *.py --to pyodide-worker
|
23 |
+
```
|
index.html
CHANGED
@@ -1,19 +1,339 @@
|
|
1 |
<!DOCTYPE html>
|
2 |
-
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<!DOCTYPE html>
|
2 |
+
<html lang="en" >
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8">
|
5 |
+
<title>Streaming Indicators</title>
|
6 |
+
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.holoviz.org/panel/1.3.1/dist/images/apple-touch-icon.png">
|
7 |
+
<link rel="icon" href="https://cdn.holoviz.org/panel/1.3.1/dist/images/favicon.ico" type=""><meta name="name" content="Streaming Indicators"> <style>
|
8 |
+
html, body {
|
9 |
+
display: flow-root;
|
10 |
+
box-sizing: border-box;
|
11 |
+
height: 100%;
|
12 |
+
margin: 0;
|
13 |
+
padding: 0;
|
14 |
+
}
|
15 |
+
</style>
|
16 |
+
<style>
|
17 |
+
|
18 |
+
:host(.pn-loading) .pn-loading-msg,
|
19 |
+
.pn-loading .pn-loading-msg {
|
20 |
+
color: var(--panel-on-background-color, black) !important;
|
21 |
+
}
|
22 |
+
|
23 |
+
</style>
|
24 |
+
|
25 |
+
<style type="text/css">
|
26 |
+
:host(.pn-loading),
|
27 |
+
.pn-loading {
|
28 |
+
overflow: hidden;
|
29 |
+
}
|
30 |
+
|
31 |
+
:host(.pn-loading):before,
|
32 |
+
.pn-loading:before {
|
33 |
+
position: absolute;
|
34 |
+
height: 100%;
|
35 |
+
width: 100%;
|
36 |
+
content: '';
|
37 |
+
z-index: 1000;
|
38 |
+
background-color: rgb(255, 255, 255, 0.5);
|
39 |
+
border-color: lightgray;
|
40 |
+
background-repeat: no-repeat;
|
41 |
+
background-position: center;
|
42 |
+
background-size: auto 50%;
|
43 |
+
border-width: 1px;
|
44 |
+
cursor: progress;
|
45 |
+
}
|
46 |
+
|
47 |
+
:host(.pn-loading) .pn-loading-msg,
|
48 |
+
.pn-loading .pn-loading-msg {
|
49 |
+
position: absolute;
|
50 |
+
top: 72%;
|
51 |
+
font-size: 2em;
|
52 |
+
color: black;
|
53 |
+
width: 100%;
|
54 |
+
text-align: center;
|
55 |
+
}
|
56 |
+
|
57 |
+
|
58 |
+
:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {
|
59 |
+
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=");
|
60 |
+
background-size: auto calc(min(50%, 400px));
|
61 |
+
}
|
62 |
+
</style><script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.3.0.min.js"></script>
|
63 |
+
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.3.0.min.js"></script>
|
64 |
+
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.3.0.min.js"></script>
|
65 |
+
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.3.0.min.js"></script>
|
66 |
+
<script type="text/javascript" src="https://cdn.holoviz.org/panel/1.3.1/dist/panel.min.js"></script>
|
67 |
+
|
68 |
+
<script type="text/javascript">
|
69 |
+
Bokeh.set_log_level("info");
|
70 |
+
</script><!-- Template CSS -->
|
71 |
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans">
|
72 |
+
<link rel="stylesheet" href="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/theme/dark.css">
|
73 |
+
<link rel="stylesheet" href="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fastbasetemplate/fast.css">
|
74 |
+
<link rel="stylesheet" href="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fastlisttemplate/fast_list_template.css">
|
75 |
+
<style type="text/css">
|
76 |
+
|
77 |
+
:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {
|
78 |
+
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=");
|
79 |
+
background-size: auto calc(min(50%, 400px));
|
80 |
+
}
|
81 |
+
</style>
|
82 |
+
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />
|
83 |
+
|
84 |
+
<style>
|
85 |
+
:root {
|
86 |
+
--background-color: #181818;
|
87 |
+
--body-font: Open Sans, sans-serif;
|
88 |
+
--corner-radius: 3;
|
89 |
+
--header-background: #00A170;
|
90 |
+
--header-color: #ffffff;
|
91 |
+
--sidebar-width: 330px;
|
92 |
+
}
|
93 |
+
body {
|
94 |
+
color: #ffffff;
|
95 |
+
background-color: var(--background-color);
|
96 |
+
font-family: var(--body-font);
|
97 |
+
}
|
98 |
+
#header a {
|
99 |
+
color: currentColor;
|
100 |
+
}
|
101 |
+
#header-design-provider {
|
102 |
+
--neutral-fill-hover: var(--header-background);
|
103 |
+
--neutral-fill-rest: var(--header-background);
|
104 |
+
--neutral-foreground-rest: var(--header-color);
|
105 |
+
background: var(--header-background);
|
106 |
+
color: var(--header-color);
|
107 |
+
}
|
108 |
+
#sidebar {
|
109 |
+
min-width: var(--sidebar-width);
|
110 |
+
max-width: var(--sidebar-width);
|
111 |
+
}
|
112 |
+
</style>
|
113 |
+
|
114 |
+
<!-- Template JS -->
|
115 |
+
<script src="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fastbasetemplate/fast_template.js"></script>
|
116 |
+
<script src="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/@microsoft/fast-components@2.30.6/dist/fast-components.js" type="module"></script>
|
117 |
+
<script src="https://cdn.holoviz.org/panel/1.3.1/dist/bundled/fast/js/fast_design.js" type="module"></script>
|
118 |
+
|
119 |
+
<!-- Fast Script -->
|
120 |
+
<script type="text/javascript">
|
121 |
+
document.addEventListener('DOMContentLoaded', (event) => {
|
122 |
+
const header_design = new window.fastDesignProvider("#header-design-provider");
|
123 |
+
const body_design = window.bodyDesign = new window.fastDesignProvider("#body-design-provider");
|
124 |
+
body_design.setLuminance(0.1);
|
125 |
+
body_design.setAccentColor("#00A170")
|
126 |
+
body_design.setNeutralColor("#000000");
|
127 |
+
header_design.setLuminance(0.1);
|
128 |
+
header_design.setAccentColor("#ffffff");
|
129 |
+
header_design.setNeutralColor("#ffffff");
|
130 |
+
});
|
131 |
+
</script>
|
132 |
+
</head>
|
133 |
+
<body class="pn-loading pn-arc">
|
134 |
+
<fast-design-system-provider id="body-design-provider" use-defaults>
|
135 |
+
<div id="container">
|
136 |
+
<fast-design-system-provider id="header-design-provider">
|
137 |
+
<nav id="header" >
|
138 |
+
<div class="app-header">
|
139 |
+
<a class="title" href="https://awesome-panel.org" > Awesome Panel</a>
|
140 |
+
<span class="title">-</span>
|
141 |
+
<a class="title" href="" >Streaming Indicators</a>
|
142 |
+
</div>
|
143 |
+
<div id="header-items">
|
144 |
+
</div>
|
145 |
+
<div class="pn-busy-container" id="busy-container">
|
146 |
+
<div id="dc27639d-6954-4159-b9e2-54e13851f586" data-root-id="p1016" style="display: contents;"></div>
|
147 |
+
</div>
|
148 |
+
<fast-tooltip anchor="busy-container" position="left">
|
149 |
+
Busy Indicator
|
150 |
+
</fast-tooltip>
|
151 |
+
</nav>
|
152 |
+
</fast-design-system-provider>
|
153 |
+
|
154 |
+
<div class="row" id="content">
|
155 |
+
|
156 |
+
<div class="main" id="main">
|
157 |
+
<div class="card-margin stretch_width">
|
158 |
+
<div class="pn-wrapper">
|
159 |
+
<span class="fullscreen-button" onclick="toggleFullScreen(this)">
|
160 |
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 18 18">
|
161 |
+
<path d="M4.5 11H3v4h4v-1.5H4.5V11zM3 7h1.5V4.5H7V3H3v4zm10.5 6.5H11V15h4v-4h-1.5v2.5zM11 3v1.5h2.5V7H15V3h-4z"/>
|
162 |
+
</svg>
|
163 |
+
</span>
|
164 |
+
<div id="b743e158-f85d-48fe-a5b1-d55d64457f34" data-root-id="p1019" style="display: contents;"></div>
|
165 |
+
</div>
|
166 |
+
</div>
|
167 |
+
</div>
|
168 |
+
<fast-dialog id="pn-Modal" hidden>
|
169 |
+
<fast-button class="pn-modal-close" id="pn-closeModal">×</fast-button>
|
170 |
+
<div>
|
171 |
+
</div>
|
172 |
+
</fast-dialog>
|
173 |
+
</div>
|
174 |
+
</div>
|
175 |
+
</fast-design-system-provider>
|
176 |
+
|
177 |
+
<script type="text/javascript">
|
178 |
+
|
179 |
+
</script>
|
180 |
+
|
181 |
+
<script type="text/javascript">
|
182 |
+
function openNav() {
|
183 |
+
document.getElementById("sidebar").classList.remove("hidden");
|
184 |
+
document.getElementById("sidebar-button").onclick = closeNav;
|
185 |
+
}
|
186 |
+
|
187 |
+
function closeNav() {
|
188 |
+
document.getElementById("sidebar").classList.add("hidden");
|
189 |
+
document.getElementById("sidebar-button").onclick = openNav;
|
190 |
+
}
|
191 |
+
|
192 |
+
var modal = document.getElementById("pn-Modal");
|
193 |
+
var span = document.getElementById("pn-closeModal");
|
194 |
+
|
195 |
+
span.onclick = function() {
|
196 |
+
modal.style.display = "none";
|
197 |
+
}
|
198 |
+
|
199 |
+
window.onclick = function(event) {
|
200 |
+
if (event.target == modal) {
|
201 |
+
modal.style.display = "none";
|
202 |
+
}
|
203 |
+
}
|
204 |
+
</script>
|
205 |
+
|
206 |
+
<div id="f0d93c75-04ce-412f-9f11-ea02a25b0b6a" data-root-id="p1009" style="display: contents;"></div>
|
207 |
+
<div id="ab651035-4297-49e7-9e0e-e325fbde91bc" data-root-id="p1012" style="display: contents;"></div>
|
208 |
+
<div id="c48707f6-64d2-4938-bf38-4bd1a0e1d042" data-root-id="p1002" style="display: contents;"></div>
|
209 |
+
<div id="b60c8fe2-e0b0-4bac-bbd6-b727c1bfc3a6" data-root-id="p1013" style="display: contents;"></div>
|
210 |
+
|
211 |
+
|
212 |
+
<script type="text/javascript">
|
213 |
+
const pyodideWorker = new Worker("./index.js");
|
214 |
+
pyodideWorker.busy = false
|
215 |
+
pyodideWorker.queue = []
|
216 |
+
|
217 |
+
function send_change(jsdoc, event) {
|
218 |
+
if (event.setter_id != null && event.setter_id == 'py') {
|
219 |
+
return
|
220 |
+
} else if (pyodideWorker.busy && event.model && event.attr) {
|
221 |
+
let events = []
|
222 |
+
for (const old_event of pyodideWorker.queue) {
|
223 |
+
if (!(old_event.model === event.model && old_event.attr === event.attr)) {
|
224 |
+
events.push(old_event)
|
225 |
+
}
|
226 |
+
}
|
227 |
+
events.push(event)
|
228 |
+
pyodideWorker.queue = events
|
229 |
+
return
|
230 |
+
}
|
231 |
+
const patch = jsdoc.create_json_patch([event])
|
232 |
+
pyodideWorker.busy = true
|
233 |
+
pyodideWorker.postMessage({type: 'patch', patch: patch})
|
234 |
+
}
|
235 |
+
|
236 |
+
pyodideWorker.onmessage = async (event) => {
|
237 |
+
const msg = event.data
|
238 |
+
|
239 |
+
const body = document.getElementsByTagName('body')[0]
|
240 |
+
const loading_msgs = document.getElementsByClassName('pn-loading-msg')
|
241 |
+
if (msg.type === 'idle') {
|
242 |
+
if (pyodideWorker.queue.length) {
|
243 |
+
const patch = pyodideWorker.jsdoc.create_json_patch(pyodideWorker.queue)
|
244 |
+
pyodideWorker.busy = true
|
245 |
+
pyodideWorker.queue = []
|
246 |
+
pyodideWorker.postMessage({type: 'patch', patch: patch})
|
247 |
+
} else {
|
248 |
+
pyodideWorker.busy = false
|
249 |
+
}
|
250 |
+
} else if (msg.type === 'status') {
|
251 |
+
let loading_msg
|
252 |
+
if (loading_msgs.length) {
|
253 |
+
loading_msg = loading_msgs[0]
|
254 |
+
} else if (body.classList.contains('pn-loading')) {
|
255 |
+
loading_msg = document.createElement('div')
|
256 |
+
loading_msg.classList.add('pn-loading-msg')
|
257 |
+
body.appendChild(loading_msg)
|
258 |
+
}
|
259 |
+
if (loading_msg != null) {
|
260 |
+
loading_msg.innerHTML = msg.msg
|
261 |
+
}
|
262 |
+
} else if (msg.type === 'render') {
|
263 |
+
const docs_json = JSON.parse(msg.docs_json)
|
264 |
+
const render_items = JSON.parse(msg.render_items)
|
265 |
+
const root_ids = JSON.parse(msg.root_ids)
|
266 |
+
|
267 |
+
// Remap roots in message to element IDs
|
268 |
+
const root_els = document.querySelectorAll('[data-root-id]')
|
269 |
+
const data_roots = []
|
270 |
+
for (const el of root_els) {
|
271 |
+
el.innerHTML = ''
|
272 |
+
data_roots.push([el.getAttribute('data-root-id'), el.id])
|
273 |
+
}
|
274 |
+
data_roots.sort((a, b) => a[0]<b[0] ? -1: 1)
|
275 |
+
const roots = {}
|
276 |
+
for (let i=0; i<data_roots.length; i++) {
|
277 |
+
roots[root_ids[i]] = data_roots[i][1]
|
278 |
+
}
|
279 |
+
render_items[0]['roots'] = roots
|
280 |
+
render_items[0]['root_ids'] = root_ids
|
281 |
+
|
282 |
+
// Embed content
|
283 |
+
const [views] = await Bokeh.embed.embed_items(docs_json, render_items)
|
284 |
+
|
285 |
+
// Remove loading spinner and message
|
286 |
+
body.classList.remove("pn-loading", "arc")
|
287 |
+
for (const loading_msg of loading_msgs) {
|
288 |
+
loading_msg.remove()
|
289 |
+
}
|
290 |
+
|
291 |
+
// Setup bi-directional syncing
|
292 |
+
pyodideWorker.jsdoc = jsdoc = [...views.roots.values()][0].model.document
|
293 |
+
jsdoc.on_change(send_change.bind(null, jsdoc), false)
|
294 |
+
pyodideWorker.postMessage({'type': 'rendered'})
|
295 |
+
pyodideWorker.postMessage({'type': 'location', location: JSON.stringify(window.location)})
|
296 |
+
} else if (msg.type === 'patch') {
|
297 |
+
pyodideWorker.jsdoc.apply_json_patch(msg.patch, msg.buffers, setter_id='py')
|
298 |
+
}
|
299 |
+
};
|
300 |
+
</script>
|
301 |
+
<script type="application/json" id="p1109">
|
302 |
+
{"225512b5-1496-4b2a-bcb3-fb1b6aa765ca":{"version":"3.3.0","title":"Streaming Indicators","roots":[{"type":"object","name":"panel.models.location.Location","id":"p1002","attributes":{"name":"location","reload":false}},{"type":"object","name":"panel.models.markup.HTML","id":"p1009","attributes":{"name":"js_area","stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1061","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"type":"object","name":"ImportedStyleSheet","id":"p1058","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/bundled/theme/fast.css"}}],"width":0,"height":0,"margin":0,"sizing_mode":"fixed","align":"start","disable_math":true}},{"type":"object","name":"panel.models.reactive_html.ReactiveHTML","id":"p1012","attributes":{"name":"actions","subscribed_events":{"type":"set","entries":["dom_event"]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1062","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"margin":0,"align":"start","data":{"type":"object","name":"TemplateActions1","id":"p1010","attributes":{"name":"TemplateActions00202"}},"scripts":{"type":"map","entries":[["open_modal",["document.getElementById(&#x27;pn-Modal&#x27;).style.display = &#x27;block&#x27;"]],["close_modal",["document.getElementById(&#x27;pn-Modal&#x27;).style.display = &#x27;none&#x27;"]]]}}},{"type":"object","name":"panel.models.browser.BrowserInfo","id":"p1013","attributes":{"name":"browser_info"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1016","attributes":{"name":"busy_indicator","css_classes":["loader","light"],"stylesheets":[":host { --loading-spinner-size: 20px; }","\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1063","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"type":"object","name":"ImportedStyleSheet","id":"p1064","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loadingspinner.css"}},{"id":"p1058"}],"min_width":20,"min_height":20,"margin":[5,10],"align":"start"}},{"type":"object","name":"panel.models.reactive_html.ReactiveHTML","id":"p1019","attributes":{"name":"main-140455927946768","tags":["main"],"subscribed_events":{"type":"set","entries":["dom_event"]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1065","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"margin":0,"sizing_mode":"stretch_width","align":"start","attrs":{"type":"map","entries":[["flexbox",[["style",["flex_wrap","justify_content","flex_direction","align_content","align_items"],"display: flex; flex-wrap: {flex_wrap}; justify-content: {justify_content}; flex-direction: {flex_direction}; align-content: {align_content}; align-items: {align_items}; height: 100%;"]]]]},"children":{"type":"map","entries":[["flex-item",[{"type":"object","name":"panel.models.markup.HTML","id":"p1021","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1066","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 0&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1023","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1067","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 1&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1025","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1068","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 2&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1027","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1069","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 3&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1029","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1070","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 4&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1031","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1071","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 5&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1033","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1072","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 6&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1035","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1073","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 7&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1037","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1074","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 8&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1039","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1075","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 9&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1041","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1076","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 10&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1043","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1077","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 11&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1045","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1078","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 12&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1047","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1079","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 13&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1049","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1080","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 14&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1051","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1081","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 15&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1053","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1082","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 16&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}},{"type":"object","name":"panel.models.markup.HTML","id":"p1055","attributes":{"styles":{"type":"map","entries":[["border","1px solid #00A170"],["padding","1em"],["border-radius","3px"]]},"stylesheets":["\n:host(.pn-loading.pn-arc):before, .pn-loading.pn-arc:before {\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46IGF1dG87IGJhY2tncm91bmQ6IG5vbmU7IGRpc3BsYXk6IGJsb2NrOyBzaGFwZS1yZW5kZXJpbmc6IGF1dG87IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjYzNjM2MzIiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij4gICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiB0eXBlPSJyb3RhdGUiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiBkdXI9IjFzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIj48L2FuaW1hdGVUcmFuc2Zvcm0+ICA8L2NpcmNsZT48L3N2Zz4=\");\n background-size: auto calc(min(50%, 400px));\n}",{"type":"object","name":"ImportedStyleSheet","id":"p1083","attributes":{"url":"https://cdn.holoviz.org/panel/1.3.1/dist/css/loading.css"}},"\n:host(.pn-loading) .pn-loading-msg,\n.pn-loading .pn-loading-msg {\n color: var(--panel-on-background-color, black) !important; \n}\n",{"id":"p1058"}],"width":165,"min_width":165,"margin":10,"align":"start","text":"&lt;div style=&quot;font-size: 18pt; color: #00A170&quot;&gt;Sensor 17&lt;/div&gt;\n&lt;div style=&quot;font-size: 54pt; color: #00A170&quot;&gt;77%&lt;/div&gt;"}}]]]},"data":{"type":"object","name":"FlexBox1","id":"p1017","attributes":{"name":"FlexBox00192"}},"html":"&lt;div id=&quot;flexbox-${id}&quot; style=&quot;display: flex; flex-wrap: ${flex_wrap}; justify-content: ${justify_content}; flex-direction: ${flex_direction}; align-content: ${align_content}; align-items: ${align_items}; height: 100%;&quot;&gt;\n\n &lt;div id=&quot;flex-item-0-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-1-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-2-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-3-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-4-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-5-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-6-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-7-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-8-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-9-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-10-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-11-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-12-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-13-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-14-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-15-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-16-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n &lt;div id=&quot;flex-item-17-${id}&quot; style=&quot;display: contents;&quot;&gt;\n\n &lt;/div&gt;\n\n&lt;/div&gt;","looped":["flex-item"],"nodes":["flexbox","flex-item-0","flex-item-1","flex-item-2","flex-item-3","flex-item-4","flex-item-5","flex-item-6","flex-item-7","flex-item-8","flex-item-9","flex-item-10","flex-item-11","flex-item-12","flex-item-13","flex-item-14","flex-item-15","flex-item-16","flex-item-17"]}}],"defs":[{"type":"model","name":"ReactiveHTML1"},{"type":"model","name":"FlexBox1","properties":[{"name":"align_content","kind":"Any","default":"flex-start"},{"name":"align_items","kind":"Any","default":"flex-start"},{"name":"flex_direction","kind":"Any","default":"row"},{"name":"flex_wrap","kind":"Any","default":"wrap"},{"name":"justify_content","kind":"Any","default":"flex-start"}]},{"type":"model","name":"FloatPanel1","properties":[{"name":"config","kind":"Any","default":{"type":"map"}},{"name":"contained","kind":"Any","default":true},{"name":"position","kind":"Any","default":"right-top"},{"name":"offsetx","kind":"Any","default":null},{"name":"offsety","kind":"Any","default":null},{"name":"theme","kind":"Any","default":"primary"},{"name":"status","kind":"Any","default":"normalized"}]},{"type":"model","name":"GridStack1","properties":[{"name":"mode","kind":"Any","default":"warn"},{"name":"ncols","kind":"Any","default":null},{"name":"nrows","kind":"Any","default":null},{"name":"allow_resize","kind":"Any","default":true},{"name":"allow_drag","kind":"Any","default":true},{"name":"state","kind":"Any","default":[]}]},{"type":"model","name":"drag1","properties":[{"name":"slider_width","kind":"Any","default":5},{"name":"slider_color","kind":"Any","default":"black"},{"name":"value","kind":"Any","default":50}]},{"type":"model","name":"click1","properties":[{"name":"terminal_output","kind":"Any","default":""},{"name":"debug_name","kind":"Any","default":""},{"name":"clears","kind":"Any","default":0}]},{"type":"model","name":"toggle_value1","properties":[{"name":"active_icons","kind":"Any","default":{"type":"map"}},{"name":"options","kind":"Any","default":{"type":"map","entries":[["favorite","heart"]]}},{"name":"value","kind":"Any","default":[]},{"name":"_reactions","kind":"Any","default":[]},{"name":"_base_url","kind":"Any","default":"https://tabler-icons.io/static/tabler-icons/icons/"}]},{"type":"model","name":"copy_to_clipboard1","properties":[{"name":"value","kind":"Any","default":null},{"name":"fill","kind":"Any","default":"none"}]},{"type":"model","name":"FastWrapper1","properties":[{"name":"object","kind":"Any","default":null},{"name":"style","kind":"Any","default":null}]},{"type":"model","name":"NotificationAreaBase1","properties":[{"name":"js_events","kind":"Any","default":{"type":"map"}},{"name":"position","kind":"Any","default":"bottom-right"},{"name":"_clear","kind":"Any","default":0}]},{"type":"model","name":"NotificationArea1","properties":[{"name":"js_events","kind":"Any","default":{"type":"map"}},{"name":"notifications","kind":"Any","default":[]},{"name":"position","kind":"Any","default":"bottom-right"},{"name":"_clear","kind":"Any","default":0},{"name":"types","kind":"Any","default":[{"type":"map","entries":[["type","warning"],["background","#ffc107"],["icon",{"type":"map","entries":[["className","fas fa-exclamation-triangle"],["tagName","i"],["color","white"]]}]]},{"type":"map","entries":[["type","info"],["background","#007bff"],["icon",{"type":"map","entries":[["className","fas fa-info-circle"],["tagName","i"],["color","white"]]}]]}]}]},{"type":"model","name":"Notification","properties":[{"name":"background","kind":"Any","default":null},{"name":"duration","kind":"Any","default":3000},{"name":"icon","kind":"Any","default":null},{"name":"message","kind":"Any","default":""},{"name":"notification_type","kind":"Any","default":null},{"name":"_destroyed","kind":"Any","default":false}]},{"type":"model","name":"TemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]},{"type":"model","name":"BootstrapTemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]},{"type":"model","name":"MaterialTemplateActions1","properties":[{"name":"open_modal","kind":"Any","default":0},{"name":"close_modal","kind":"Any","default":0}]}]}}
|
303 |
+
</script>
|
304 |
+
<script type="text/javascript">
|
305 |
+
(function() {
|
306 |
+
const fn = function() {
|
307 |
+
Bokeh.safely(function() {
|
308 |
+
(function(root) {
|
309 |
+
function embed_document(root) {
|
310 |
+
const docs_json = document.getElementById('p1109').textContent;
|
311 |
+
const render_items = [{"docid":"225512b5-1496-4b2a-bcb3-fb1b6aa765ca","roots":{"p1002":"c48707f6-64d2-4938-bf38-4bd1a0e1d042","p1009":"f0d93c75-04ce-412f-9f11-ea02a25b0b6a","p1012":"ab651035-4297-49e7-9e0e-e325fbde91bc","p1013":"b60c8fe2-e0b0-4bac-bbd6-b727c1bfc3a6","p1016":"dc27639d-6954-4159-b9e2-54e13851f586","p1019":"b743e158-f85d-48fe-a5b1-d55d64457f34"},"root_ids":["p1002","p1009","p1012","p1013","p1016","p1019"]}];
|
312 |
+
root.Bokeh.embed.embed_items(docs_json, render_items);
|
313 |
+
}
|
314 |
+
if (root.Bokeh !== undefined) {
|
315 |
+
embed_document(root);
|
316 |
+
} else {
|
317 |
+
let attempts = 0;
|
318 |
+
const timer = setInterval(function(root) {
|
319 |
+
if (root.Bokeh !== undefined) {
|
320 |
+
clearInterval(timer);
|
321 |
+
embed_document(root);
|
322 |
+
} else {
|
323 |
+
attempts++;
|
324 |
+
if (attempts > 100) {
|
325 |
+
clearInterval(timer);
|
326 |
+
console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
|
327 |
+
}
|
328 |
+
}
|
329 |
+
}, 10, root)
|
330 |
+
}
|
331 |
+
})(window);
|
332 |
+
});
|
333 |
+
};
|
334 |
+
if (document.readyState != "loading") fn();
|
335 |
+
else document.addEventListener("DOMContentLoaded", fn);
|
336 |
+
})();
|
337 |
+
</script>
|
338 |
+
</body>
|
339 |
+
</html>
|
index.js
ADDED
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
importScripts("https://cdn.jsdelivr.net/pyodide/v0.24.1/pyc/pyodide.js");
|
2 |
+
|
3 |
+
function sendPatch(patch, buffers, msg_id) {
|
4 |
+
self.postMessage({
|
5 |
+
type: 'patch',
|
6 |
+
patch: patch,
|
7 |
+
buffers: buffers
|
8 |
+
})
|
9 |
+
}
|
10 |
+
|
11 |
+
async function startApplication() {
|
12 |
+
console.log("Loading pyodide!");
|
13 |
+
self.postMessage({type: 'status', msg: 'Loading pyodide'})
|
14 |
+
self.pyodide = await loadPyodide();
|
15 |
+
self.pyodide.globals.set("sendPatch", sendPatch);
|
16 |
+
console.log("Loaded!");
|
17 |
+
await self.pyodide.loadPackage("micropip");
|
18 |
+
const env_spec = ['https://cdn.holoviz.org/panel/wheels/bokeh-3.3.0-py3-none-any.whl', 'https://cdn.holoviz.org/panel/1.3.1/dist/wheels/panel-1.3.1-py3-none-any.whl', 'pyodide-http==0.2.1', 'numpy']
|
19 |
+
for (const pkg of env_spec) {
|
20 |
+
let pkg_name;
|
21 |
+
if (pkg.endsWith('.whl')) {
|
22 |
+
pkg_name = pkg.split('/').slice(-1)[0].split('-')[0]
|
23 |
+
} else {
|
24 |
+
pkg_name = pkg
|
25 |
+
}
|
26 |
+
self.postMessage({type: 'status', msg: `Installing ${pkg_name}`})
|
27 |
+
try {
|
28 |
+
await self.pyodide.runPythonAsync(`
|
29 |
+
import micropip
|
30 |
+
await micropip.install('${pkg}');
|
31 |
+
`);
|
32 |
+
} catch(e) {
|
33 |
+
console.log(e)
|
34 |
+
self.postMessage({
|
35 |
+
type: 'status',
|
36 |
+
msg: `Error while installing ${pkg_name}`
|
37 |
+
});
|
38 |
+
}
|
39 |
+
}
|
40 |
+
console.log("Packages loaded!");
|
41 |
+
self.postMessage({type: 'status', msg: 'Executing code'})
|
42 |
+
const code = `
|
43 |
+
|
44 |
+
import asyncio
|
45 |
+
|
46 |
+
from panel.io.pyodide import init_doc, write_doc
|
47 |
+
|
48 |
+
init_doc()
|
49 |
+
|
50 |
+
"""
|
51 |
+
Source: https://awesome-panel.org/resources/streaming_indicators/
|
52 |
+
"""
|
53 |
+
from asyncio import create_task, get_event_loop, sleep
|
54 |
+
|
55 |
+
import numpy as np
|
56 |
+
import panel as pn
|
57 |
+
|
58 |
+
ACCENT = "#00A170"
|
59 |
+
OK_COLOR=ACCENT
|
60 |
+
ERROR_COLOR = "#a10031"
|
61 |
+
ALERT = 80
|
62 |
+
COLORS = [(ALERT, OK_COLOR), (100, ERROR_COLOR)]
|
63 |
+
INITIAL_VALUE = ALERT-3
|
64 |
+
|
65 |
+
N=18 # Number of indicators
|
66 |
+
|
67 |
+
# Can be removed when https://github.com/holoviz/panel/pull/6194 is released
|
68 |
+
CSS_FIX = """
|
69 |
+
:host(.pn-loading) .pn-loading-msg,
|
70 |
+
.pn-loading .pn-loading-msg {
|
71 |
+
color: var(--panel-on-background-color, black) !important;
|
72 |
+
}
|
73 |
+
"""
|
74 |
+
if not CSS_FIX in pn.config.raw_css:
|
75 |
+
pn.config.raw_css.append(CSS_FIX)
|
76 |
+
|
77 |
+
async def update_values(values):
|
78 |
+
"""Some random updating of values."""
|
79 |
+
while True:
|
80 |
+
# Replace with your own code.
|
81 |
+
new_value = np.copy(values.rx.value)
|
82 |
+
|
83 |
+
new_value += np.random.randint(5, size=N) -2
|
84 |
+
new_value[new_value<0]=0
|
85 |
+
new_value[new_value>99]=99
|
86 |
+
|
87 |
+
values.rx.value = new_value
|
88 |
+
|
89 |
+
await sleep(1)
|
90 |
+
|
91 |
+
@pn.cache # We use caching to share values across all sessions
|
92 |
+
def get_values():
|
93 |
+
# We use Reactive Expressions https://param.holoviz.org/user_guide/Reactive_Expressions.html
|
94 |
+
return pn.rx([INITIAL_VALUE]*N)
|
95 |
+
|
96 |
+
@pn.cache # We use caching to only update values once across all sessions
|
97 |
+
def create_update_values_task():
|
98 |
+
values = get_values()
|
99 |
+
create_task(update_values(values))
|
100 |
+
|
101 |
+
def get_styles(value):
|
102 |
+
if value<=ALERT:
|
103 |
+
return {"border": f"1px solid {OK_COLOR}", "padding": "1em", "border-radius": "3px"}
|
104 |
+
return {"border": f"1px solid {ERROR_COLOR}", "padding": "1em", "border-radius": "3px"}
|
105 |
+
|
106 |
+
def create_indicator(index, values):
|
107 |
+
title =f"Sensor {index}"
|
108 |
+
value = values[index]
|
109 |
+
|
110 |
+
return pn.indicators.Number(
|
111 |
+
name=title,
|
112 |
+
value=value,
|
113 |
+
format="{value}%",
|
114 |
+
colors=COLORS,
|
115 |
+
margin=10,
|
116 |
+
styles=pn.rx(get_styles)(value),
|
117 |
+
width=165
|
118 |
+
)
|
119 |
+
|
120 |
+
def create_component():
|
121 |
+
values = get_values()
|
122 |
+
indicators = tuple(create_indicator(i, values) for i in range(len(values.rx.value)))
|
123 |
+
layout = pn.FlexBox(*indicators)
|
124 |
+
return layout
|
125 |
+
|
126 |
+
if pn.state.served or pn.state._is_pyodide:
|
127 |
+
pn.extension()
|
128 |
+
|
129 |
+
if get_event_loop().is_running():
|
130 |
+
# We can only start the stream if the event loop is running
|
131 |
+
create_update_values_task()
|
132 |
+
|
133 |
+
pn.template.FastListTemplate(
|
134 |
+
site="Awesome Panel",
|
135 |
+
site_url="https://awesome-panel.org",
|
136 |
+
title="Streaming Indicators",
|
137 |
+
accent=ACCENT,
|
138 |
+
theme="dark",
|
139 |
+
theme_toggle=False,
|
140 |
+
main=[create_component()],
|
141 |
+
main_layout=None,
|
142 |
+
).servable()
|
143 |
+
|
144 |
+
await write_doc()
|
145 |
+
`
|
146 |
+
|
147 |
+
try {
|
148 |
+
const [docs_json, render_items, root_ids] = await self.pyodide.runPythonAsync(code)
|
149 |
+
self.postMessage({
|
150 |
+
type: 'render',
|
151 |
+
docs_json: docs_json,
|
152 |
+
render_items: render_items,
|
153 |
+
root_ids: root_ids
|
154 |
+
})
|
155 |
+
} catch(e) {
|
156 |
+
const traceback = `${e}`
|
157 |
+
const tblines = traceback.split('\n')
|
158 |
+
self.postMessage({
|
159 |
+
type: 'status',
|
160 |
+
msg: tblines[tblines.length-2]
|
161 |
+
});
|
162 |
+
throw e
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
self.onmessage = async (event) => {
|
167 |
+
const msg = event.data
|
168 |
+
if (msg.type === 'rendered') {
|
169 |
+
self.pyodide.runPythonAsync(`
|
170 |
+
from panel.io.state import state
|
171 |
+
from panel.io.pyodide import _link_docs_worker
|
172 |
+
|
173 |
+
_link_docs_worker(state.curdoc, sendPatch, setter='js')
|
174 |
+
`)
|
175 |
+
} else if (msg.type === 'patch') {
|
176 |
+
self.pyodide.globals.set('patch', msg.patch)
|
177 |
+
self.pyodide.runPythonAsync(`
|
178 |
+
state.curdoc.apply_json_patch(patch.to_py(), setter='js')
|
179 |
+
`)
|
180 |
+
self.postMessage({type: 'idle'})
|
181 |
+
} else if (msg.type === 'location') {
|
182 |
+
self.pyodide.globals.set('location', msg.location)
|
183 |
+
self.pyodide.runPythonAsync(`
|
184 |
+
import json
|
185 |
+
from panel.io.state import state
|
186 |
+
from panel.util import edit_readonly
|
187 |
+
if state.location:
|
188 |
+
loc_data = json.loads(location)
|
189 |
+
with edit_readonly(state.location):
|
190 |
+
state.location.param.update({
|
191 |
+
k: v for k, v in loc_data.items() if k in state.location.param
|
192 |
+
})
|
193 |
+
`)
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
startApplication()
|
index.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Source: https://awesome-panel.org/resources/streaming_indicators/
|
3 |
+
"""
|
4 |
+
from asyncio import create_task, get_event_loop, sleep
|
5 |
+
|
6 |
+
import numpy as np
|
7 |
+
import panel as pn
|
8 |
+
|
9 |
+
ACCENT = "#00A170"
|
10 |
+
OK_COLOR=ACCENT
|
11 |
+
ERROR_COLOR = "#a10031"
|
12 |
+
ALERT = 80
|
13 |
+
COLORS = [(ALERT, OK_COLOR), (100, ERROR_COLOR)]
|
14 |
+
INITIAL_VALUE = ALERT-3
|
15 |
+
|
16 |
+
N=18 # Number of indicators
|
17 |
+
|
18 |
+
# Can be removed when https://github.com/holoviz/panel/pull/6194 is released
|
19 |
+
CSS_FIX = """
|
20 |
+
:host(.pn-loading) .pn-loading-msg,
|
21 |
+
.pn-loading .pn-loading-msg {
|
22 |
+
color: var(--panel-on-background-color, black) !important;
|
23 |
+
}
|
24 |
+
"""
|
25 |
+
if not CSS_FIX in pn.config.raw_css:
|
26 |
+
pn.config.raw_css.append(CSS_FIX)
|
27 |
+
|
28 |
+
async def update_values(values):
|
29 |
+
"""Some random updating of values."""
|
30 |
+
while True:
|
31 |
+
# Replace with your own code.
|
32 |
+
new_value = np.copy(values.rx.value)
|
33 |
+
|
34 |
+
new_value += np.random.randint(5, size=N) -2
|
35 |
+
new_value[new_value<0]=0
|
36 |
+
new_value[new_value>99]=99
|
37 |
+
|
38 |
+
values.rx.value = new_value
|
39 |
+
|
40 |
+
await sleep(1)
|
41 |
+
|
42 |
+
@pn.cache # We use caching to share values across all sessions
|
43 |
+
def get_values():
|
44 |
+
# We use Reactive Expressions https://param.holoviz.org/user_guide/Reactive_Expressions.html
|
45 |
+
return pn.rx([INITIAL_VALUE]*N)
|
46 |
+
|
47 |
+
@pn.cache # We use caching to only update values once across all sessions
|
48 |
+
def create_update_values_task():
|
49 |
+
values = get_values()
|
50 |
+
create_task(update_values(values))
|
51 |
+
|
52 |
+
def get_styles(value):
|
53 |
+
if value<=ALERT:
|
54 |
+
return {"border": f"1px solid {OK_COLOR}", "padding": "1em", "border-radius": "3px"}
|
55 |
+
return {"border": f"1px solid {ERROR_COLOR}", "padding": "1em", "border-radius": "3px"}
|
56 |
+
|
57 |
+
def create_indicator(index, values):
|
58 |
+
title =f"Sensor {index}"
|
59 |
+
value = values[index]
|
60 |
+
|
61 |
+
return pn.indicators.Number(
|
62 |
+
name=title,
|
63 |
+
value=value,
|
64 |
+
format="{value}%",
|
65 |
+
colors=COLORS,
|
66 |
+
margin=10,
|
67 |
+
styles=pn.rx(get_styles)(value),
|
68 |
+
width=165
|
69 |
+
)
|
70 |
+
|
71 |
+
def create_component():
|
72 |
+
values = get_values()
|
73 |
+
indicators = tuple(create_indicator(i, values) for i in range(len(values.rx.value)))
|
74 |
+
layout = pn.FlexBox(*indicators)
|
75 |
+
return layout
|
76 |
+
|
77 |
+
if pn.state.served or pn.state._is_pyodide:
|
78 |
+
pn.extension()
|
79 |
+
|
80 |
+
if get_event_loop().is_running():
|
81 |
+
# We can only start the stream if the event loop is running
|
82 |
+
create_update_values_task()
|
83 |
+
|
84 |
+
pn.template.FastListTemplate(
|
85 |
+
site="Awesome Panel",
|
86 |
+
site_url="https://awesome-panel.org",
|
87 |
+
title="Streaming Indicators",
|
88 |
+
accent=ACCENT,
|
89 |
+
theme="dark",
|
90 |
+
theme_toggle=False,
|
91 |
+
main=[create_component()],
|
92 |
+
main_layout=None,
|
93 |
+
).servable()
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
panel
|
2 |
+
numpy
|