nova-trame 1.0.0rc2__py3-none-any.whl → 1.0.0rc4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nova/trame/view/components/visualization/matplotlib_figure.py +31 -5
- nova/trame/view/layouts/grid.py +8 -1
- nova/trame/view/layouts/hbox.py +2 -0
- nova/trame/view/layouts/vbox.py +2 -0
- nova/trame/view/theme/theme.py +3 -3
- {nova_trame-1.0.0rc2.dist-info → nova_trame-1.0.0rc4.dist-info}/METADATA +1 -1
- {nova_trame-1.0.0rc2.dist-info → nova_trame-1.0.0rc4.dist-info}/RECORD +10 -10
- {nova_trame-1.0.0rc2.dist-info → nova_trame-1.0.0rc4.dist-info}/WHEEL +0 -0
- {nova_trame-1.0.0rc2.dist-info → nova_trame-1.0.0rc4.dist-info}/entry_points.txt +0 -0
- {nova_trame-1.0.0rc2.dist-info → nova_trame-1.0.0rc4.dist-info}/licenses/LICENSE +0 -0
@@ -70,6 +70,13 @@ class _MPLApplication(tornado.web.Application):
|
|
70
70
|
data_uri = "data:image/png;base64," + blob.encode("base64").replace("\n", "")
|
71
71
|
self.write_message(data_uri)
|
72
72
|
|
73
|
+
def write_message(self, *args: Any, **kwargs: Any) -> Any:
|
74
|
+
# We need the websocket to remain alive if a message fails to write.
|
75
|
+
try:
|
76
|
+
super().write_message(*args, **kwargs)
|
77
|
+
except Exception:
|
78
|
+
pass
|
79
|
+
|
73
80
|
def __init__(self, figure: Figure) -> None:
|
74
81
|
self.figure = figure
|
75
82
|
self.manager = new_figure_manager_given_figure(id(figure), figure)
|
@@ -218,9 +225,9 @@ class MatplotlibFigure(matplotlib.Figure):
|
|
218
225
|
self._server = get_server(None, client_type="vue3")
|
219
226
|
self._webagg = webagg
|
220
227
|
if "classes" in kwargs:
|
221
|
-
kwargs["classes"] += "
|
228
|
+
kwargs["classes"] += " flex-1-1"
|
222
229
|
else:
|
223
|
-
kwargs["classes"] = "
|
230
|
+
kwargs["classes"] = "flex-1-1"
|
224
231
|
if webagg:
|
225
232
|
self._initial_resize = True
|
226
233
|
if "id" in kwargs:
|
@@ -247,17 +254,28 @@ class MatplotlibFigure(matplotlib.Figure):
|
|
247
254
|
|
248
255
|
self._query_selector = f"window.document.querySelector('#{self._id}')"
|
249
256
|
self._trigger = (
|
257
|
+
f"if ({self._query_selector} === null) {{ return; }}"
|
258
|
+
# webagg figures receive a fixed width and height. This blocks the flexbox scaling, so I temporarily hide
|
259
|
+
# the figure to allow the container to grow/shrink naturally in flexbox.
|
260
|
+
f"window.document.querySelectorAll('.nova-mpl').forEach((item) => {{ item.style.display = 'none'; }});"
|
261
|
+
f"const height = {self._query_selector}.parentNode.offsetHeight;"
|
262
|
+
f"const width = {self._query_selector}.parentNode.offsetWidth;"
|
263
|
+
# Revert the display value to allow the figure to render again.
|
264
|
+
f"window.document.querySelectorAll('.nova-mpl').forEach((item) => {{ item.style.display = ''; }});"
|
250
265
|
"window.trame.trigger("
|
251
266
|
f" '{self._id}_resize',"
|
252
|
-
f" [
|
267
|
+
f" [height, width, window.devicePixelRatio]"
|
253
268
|
");"
|
254
269
|
)
|
255
270
|
self._resize_figure = client.JSEval(exec=self._trigger).exec
|
256
271
|
self._resize_listener = client.JSEval(
|
257
272
|
exec=(
|
258
|
-
|
273
|
+
# ResizeObserver is necessary to detect changes in size unrelated to the viewport size such as when
|
274
|
+
# content is conditionally rendered that changes the size of the figure's container.
|
275
|
+
"const resizeObserver = new window.ResizeObserver(() => {"
|
259
276
|
f" window.delay_manager.debounce('{self._id}', function() {{ {self._trigger} }}, 500);"
|
260
277
|
"});"
|
278
|
+
f"resizeObserver.observe({self._query_selector}.parentNode);"
|
261
279
|
)
|
262
280
|
).exec
|
263
281
|
|
@@ -278,10 +296,18 @@ class MatplotlibFigure(matplotlib.Figure):
|
|
278
296
|
height = int(height * device_pixel_ratio)
|
279
297
|
width = int(width * device_pixel_ratio)
|
280
298
|
|
299
|
+
if height <= 0 or width <= 0:
|
300
|
+
return
|
301
|
+
|
302
|
+
if self._webagg:
|
281
303
|
self._initial_resize = False
|
282
304
|
|
283
305
|
self._figure.set_dpi(dpi)
|
284
|
-
|
306
|
+
new_width = width / dpi
|
307
|
+
new_height = height / dpi
|
308
|
+
current_size = self._figure.get_size_inches()
|
309
|
+
if current_size[0] != new_width or current_size[1] != new_height:
|
310
|
+
self._figure.set_size_inches(new_width, new_height)
|
285
311
|
|
286
312
|
self.update(skip_resize=True)
|
287
313
|
|
nova/trame/view/layouts/grid.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""Trame implementation of the GridLayout class."""
|
2
2
|
|
3
3
|
from typing import Any, Optional, Union
|
4
|
+
from warnings import warn
|
4
5
|
|
5
6
|
from trame.widgets import html
|
6
7
|
from trame_client.widgets.core import AbstractElement
|
@@ -39,7 +40,8 @@ class GridLayout(html.Div):
|
|
39
40
|
<https://developer.mozilla.org/en-US/docs/Web/CSS/justify-items>`__ for available options.
|
40
41
|
valign : optional[str]
|
41
42
|
The vertical alignment of items in the grid. See `MDN
|
42
|
-
<https://developer.mozilla.org/en-US/docs/Web/CSS/align-items>`__ for available options.
|
43
|
+
<https://developer.mozilla.org/en-US/docs/Web/CSS/align-items>`__ for available options. Note that this
|
44
|
+
parameter is ignored when stretch=True.
|
43
45
|
gap : optional[str]
|
44
46
|
The gap to place between items (works both horizontally and vertically). Can be any CSS gap value (e.g.
|
45
47
|
"4px" or "0.25em"). Defaults to no gap between items.
|
@@ -74,7 +76,12 @@ class GridLayout(html.Div):
|
|
74
76
|
classes = " ".join(classes)
|
75
77
|
classes += " d-grid"
|
76
78
|
if stretch:
|
79
|
+
if valign:
|
80
|
+
warn("Ignoring valign parameter to GridLayout since stretch=True.", stacklevel=1)
|
81
|
+
valign = "stretch"
|
77
82
|
classes += " flex-1-1 overflow-y-auto"
|
83
|
+
else:
|
84
|
+
classes += " flex-0-1"
|
78
85
|
|
79
86
|
widget_style = self.get_root_styles(columns, height, width, halign, valign, gap)
|
80
87
|
user_style = kwargs.pop("style", {})
|
nova/trame/view/layouts/hbox.py
CHANGED
@@ -66,6 +66,8 @@ class HBoxLayout(html.Div):
|
|
66
66
|
classes += " d-flex flex-row"
|
67
67
|
if stretch:
|
68
68
|
classes += " flex-1-1 overflow-y-auto"
|
69
|
+
else:
|
70
|
+
classes += " flex-0-1"
|
69
71
|
|
70
72
|
widget_style = self.get_root_styles(height, width, halign, valign, gap, vspace)
|
71
73
|
user_style = kwargs.pop("style", {})
|
nova/trame/view/layouts/vbox.py
CHANGED
@@ -66,6 +66,8 @@ class VBoxLayout(html.Div):
|
|
66
66
|
classes += " d-flex flex-column"
|
67
67
|
if stretch:
|
68
68
|
classes += " flex-1-1 overflow-y-auto"
|
69
|
+
else:
|
70
|
+
classes += " flex-0-1"
|
69
71
|
|
70
72
|
widget_style = self.get_root_styles(height, width, halign, valign, gap, vspace)
|
71
73
|
user_style = kwargs.pop("style", {})
|
nova/trame/view/theme/theme.py
CHANGED
@@ -259,13 +259,13 @@ class ThemedApp:
|
|
259
259
|
|
260
260
|
with vuetify.VMain(classes="align-stretch d-flex flex-column h-screen"):
|
261
261
|
# [slot override example]
|
262
|
-
layout.pre_content = vuetify.VSheet(classes="bg-background flex-0-1
|
262
|
+
layout.pre_content = vuetify.VSheet(classes="bg-background flex-0-1 mt-1 ")
|
263
263
|
# [slot override example complete]
|
264
264
|
with vuetify.VContainer(classes="flex-1-1 overflow-hidden pt-0 pb-2", fluid=True):
|
265
265
|
layout.content = vuetify.VCard(
|
266
|
-
classes="d-flex flex-column flex-1-1 h-100
|
266
|
+
classes="d-flex flex-column flex-1-1 h-100 overflow-y-auto pa-1 "
|
267
267
|
)
|
268
|
-
layout.post_content = vuetify.VSheet(classes="bg-background flex-0-1
|
268
|
+
layout.post_content = vuetify.VSheet(classes="bg-background flex-0-1 mb-1 ")
|
269
269
|
|
270
270
|
with vuetify.VFooter(
|
271
271
|
app=True,
|
@@ -18,12 +18,12 @@ nova/trame/view/components/remote_file_input.py,sha256=mcz_bmI2rD8gdmIOKLhlzfj-X
|
|
18
18
|
nova/trame/view/components/tool_outputs.py,sha256=IbYV4VjrkWAE354Bh5KH76SPsxGLIkOXChijS4-ce_Y,2408
|
19
19
|
nova/trame/view/components/visualization/__init__.py,sha256=reqkkbhD5uSksHHlhVMy1qNUCwSekS5HlXk6wCREYxU,152
|
20
20
|
nova/trame/view/components/visualization/interactive_2d_plot.py,sha256=z2s1janxAclpMEdDJk3z-CQ6r3KPNoR_SXPx9ppWnuQ,3481
|
21
|
-
nova/trame/view/components/visualization/matplotlib_figure.py,sha256=
|
21
|
+
nova/trame/view/components/visualization/matplotlib_figure.py,sha256=GYfX7hlEWQ4Dghk8Z1dmUQr6jgktWirhOYb0drtonM4,16297
|
22
22
|
nova/trame/view/layouts/__init__.py,sha256=cMrlB5YMUoK8EGB83b34UU0kPTVrH8AxsYvKRtpUNEc,141
|
23
|
-
nova/trame/view/layouts/grid.py,sha256=
|
24
|
-
nova/trame/view/layouts/hbox.py,sha256=
|
23
|
+
nova/trame/view/layouts/grid.py,sha256=DU5u5JTE0ulzCaJsEWyTenBH9lOQD7mtoC6RZXxDTPE,6110
|
24
|
+
nova/trame/view/layouts/hbox.py,sha256=w6ow7Qzmq4slODz_9f7kEigCVPE2PhUmPODedYH34f4,3850
|
25
25
|
nova/trame/view/layouts/utils.py,sha256=Hg34VQWTG3yHBsgNvmfatR4J-uL3cko7UxSJpT-h3JI,376
|
26
|
-
nova/trame/view/layouts/vbox.py,sha256=
|
26
|
+
nova/trame/view/layouts/vbox.py,sha256=Kkci79zDKF6qNH4HeDPYquJcixXx3BS63NVmS3FlOiw,3851
|
27
27
|
nova/trame/view/theme/__init__.py,sha256=70_marDlTigIcPEOGiJb2JTs-8b2sGM5SlY7XBPtBDM,54
|
28
28
|
nova/trame/view/theme/assets/core_style.scss,sha256=lZK8zghy4ExmNuFI-rfq7qt2S7bqObzM_MBviOlWP5c,4481
|
29
29
|
nova/trame/view/theme/assets/favicon.png,sha256=Xbp1nUmhcBDeObjsebEbEAraPDZ_M163M_ZLtm5AbQc,1927
|
@@ -32,7 +32,7 @@ nova/trame/view/theme/assets/js/lodash.min.js,sha256=KCyAYJ-fsqtp_HMwbjhy6IKjlA5
|
|
32
32
|
nova/trame/view/theme/assets/js/revo_grid.js,sha256=fbuEWO8etw-xgo9tjJGjJXdd5wL8qpgabPmrnU6Jp8k,4081
|
33
33
|
nova/trame/view/theme/assets/vuetify_config.json,sha256=a0FSgpLYWGFlRGSMhMq61MyDFBEBwvz55G4qjkM08cs,5627
|
34
34
|
nova/trame/view/theme/exit_button.py,sha256=Kqv1GVJZGrSsj6_JFjGU3vm3iNuMolLC2T1x2IsdmV0,3094
|
35
|
-
nova/trame/view/theme/theme.py,sha256=
|
35
|
+
nova/trame/view/theme/theme.py,sha256=Jeoi-qrokSO-dDYpEvicbqfwzalhhbG-4HplD8NFj6s,13269
|
36
36
|
nova/trame/view/utilities/local_storage.py,sha256=vD8f2VZIpxhIKjZwEaD7siiPCTZO4cw9AfhwdawwYLY,3218
|
37
37
|
nova/trame/view_model/data_selector.py,sha256=jAtq5hpohQ6YiLBbgLJfNUzWZBpN2bjCG_c_FCJu2ns,3186
|
38
38
|
nova/trame/view_model/execution_buttons.py,sha256=MfKSp95D92EqpD48C15cBo6dLO0Yld4FeRZMJNxJf7Y,3551
|
@@ -40,8 +40,8 @@ nova/trame/view_model/ornl/neutron_data_selector.py,sha256=PIKQyzcHpwu81DNk3d8Af
|
|
40
40
|
nova/trame/view_model/progress_bar.py,sha256=6AUKHF3hfzbdsHqNEnmHRgDcBKY5TT8ywDx9S6ovnsc,2854
|
41
41
|
nova/trame/view_model/remote_file_input.py,sha256=zWOflmCDJYYR_pacHphwzricV667GSRokh-mlxpBAOo,3646
|
42
42
|
nova/trame/view_model/tool_outputs.py,sha256=ev6LY7fJ0H2xAJn9f5ww28c8Kpom2SYc2FbvFcoN4zg,829
|
43
|
-
nova_trame-1.0.
|
44
|
-
nova_trame-1.0.
|
45
|
-
nova_trame-1.0.
|
46
|
-
nova_trame-1.0.
|
47
|
-
nova_trame-1.0.
|
43
|
+
nova_trame-1.0.0rc4.dist-info/METADATA,sha256=ullsD538VJU9i_HleHEUd0U5NytxWHl7gKY8hk7XIYI,1798
|
44
|
+
nova_trame-1.0.0rc4.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
45
|
+
nova_trame-1.0.0rc4.dist-info/entry_points.txt,sha256=J2AmeSwiTYZ4ZqHHp9HO6v4MaYQTTBPbNh6WtoqOT58,42
|
46
|
+
nova_trame-1.0.0rc4.dist-info/licenses/LICENSE,sha256=Iu5QiDbwNbREg75iYaxIJ_V-zppuv4QFuBhAW-qiAlM,1061
|
47
|
+
nova_trame-1.0.0rc4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|