11# __init__.py
22
3- from io import BytesIO
3+ from io import StringIO
44from pathlib import Path
55from typing import Optional , Literal
6+ import base64
7+
68import streamlit .components .v1 as components
7- import pyvista as pv
9+ from pyvista .plotting import Plotter
10+
811import panel as pn
912
1013from bokeh .resources import CDN , INLINE
1114
12- BOKEH_RESOURCES = {"CDN" : CDN , "INLINE" : INLINE }
13-
1415pn .extension ("vtk" , sizing_mode = "stretch_both" )
15-
16- # Tell streamlit that there is a component called stpyvista,
17- # and that the code to display that component is in the "frontend" folder
18- frontend_dir = (Path (__file__ ).parent / "frontend" ).absolute ()
19- _component_func = components .declare_component ("stpyvista" , path = str (frontend_dir ))
16+ BOKEH_RESOURCES = {"CDN" : CDN , "INLINE" : INLINE }
2017
2118
2219class stpyvistaTypeError (TypeError ):
@@ -27,19 +24,54 @@ class stpyvistaValueError(ValueError):
2724 pass
2825
2926
30- # Create the python function that will be called from the front end
27+ # Tell streamlit that there is a component called `experimental_vtkjs`,
28+ # and that the code to display that component is in the "vanilla_vtkjs" folder
29+ experimental_frontend_dir = (Path (__file__ ).parent / "vanilla_vtkjs" ).absolute ()
30+ _exp_component_func = components .declare_component (
31+ "experimental_vtkjs" , path = str (experimental_frontend_dir )
32+ )
33+
34+
35+ def experimental_vtkjs (vtksz_data : bytes , key : Optional [str ] = None ):
36+ """
37+ Renders an interactive Pyvista Plotter in streamlit.
38+
39+ Parameters
40+ ----------
41+ vtksz_data: bytes
42+ Data from a vtksz in zip format.
43+
44+ Returns
45+ -------
46+ str
47+ A stringified JSON with camera view properties.
48+ """
49+
50+ base64_str = base64 .b64encode (vtksz_data ).decode ().replace ("\n " , "" )
51+
52+ component_value = _exp_component_func (
53+ plotter_data = base64_str ,
54+ key = key ,
55+ default = 0 ,
56+ )
57+
58+ return component_value
59+
60+
61+ frontend_dir = (Path (__file__ ).parent / "panel_based" ).absolute ()
62+ _component_func = components .declare_component ("stpyvista" , path = str (frontend_dir ))
3163
3264
3365def stpyvista (
34- plotter : pv . Plotter ,
66+ plotter : Plotter ,
3567 use_container_width : bool = True ,
3668 horizontal_align : Literal ["center" , "left" , "right" ] = "center" ,
3769 panel_kwargs : Optional [dict ] = None ,
3870 bokeh_resources : Literal ["CDN" , "INLINE" ] = "INLINE" ,
3971 key : Optional [str ] = None ,
4072) -> None :
4173 """
42- Renders an interactive pyvisya Plotter in streamlit.
74+ Renders an interactive Pyvista Plotter in streamlit.
4375
4476 Parameters
4577 ----------
@@ -79,7 +111,7 @@ def stpyvista(
79111
80112 """
81113
82- if isinstance (plotter , pv . Plotter ):
114+ if isinstance (plotter , Plotter ):
83115 if panel_kwargs is None :
84116 panel_kwargs = dict ()
85117
@@ -95,10 +127,9 @@ def stpyvista(
95127 )
96128
97129 # Create HTML file
98- model_bytes = BytesIO ()
99- geo_pan_pv .save (model_bytes , resources = BOKEH_RESOURCES [bokeh_resources ])
100- panel_html = model_bytes .getvalue ().decode ("utf-8" )
101- model_bytes .close ()
130+ with StringIO () as model_bytes :
131+ geo_pan_pv .save (model_bytes , resources = BOKEH_RESOURCES [bokeh_resources ])
132+ panel_html = model_bytes .getvalue ()
102133
103134 component_value = _component_func (
104135 panel_html = panel_html ,
0 commit comments