Hi,
I have created an app where the user fetch data from a blob storage.
On the blob storage there is an index.html file which I would like to embed in the app. It is an interactive visualisation from a Ansys solver. Beside the index.html file there are some required folders that needs to be used.
If I copy the folders and the index.html to the assets folder, then it is straightforward to make an Iframe which works as wanted. But if the user select another result then I need to update the index.html file.
First go was to simple just make a callback that download the new index file into the assets folder. This doesnt work, because everytime I copy to the assets folder the dash app reloads and the user would then again have to select the data.
Of course the best solution would be just to use blob storage directly instead of copy, I have read about it here javascript - set a Blob as the “src” of an iframe - Stack Overflow but dont know how to implement that in a Dash app.
The second solution is what I have been trying i.e. copy the index.html file to the assets folder. Maybe I can copy to another folder and then do something clever?
Any help much appreciated
edit:
I look a little more in the details what it is I am trying to do. In the index.html file the only thing I am changing is the variable shown below (proxy_img = VARIABLE. Maybe I dont need an Iframe at all? Can I just create an object which is rendered if there is a variable?
<!DOCTYPE html>
<html data-color-mode="light" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Report - ADR</title>
<script src="./ansys/nexus/utils/js-unzip.js"></script>
<script src="./ansys/nexus/utils/js-inflate.js"></script>
<script src="./ansys/nexus/ANSYSViewer_min.js"></script>
<script src="./ansys/nexus/viewer-loader.js"></script>
</head>
<div class="col justify-content-center"><div class="col-md-auto"><div class='avz-viewer' id='avz_viewer_319ffe596954461e910340b21d034b45' style='display:inline-block;top:0px;left:0px;width:960px;height:720px;margin:0;border:0;padding:0;fixed:absolute;background:white;'>
<ansys-nexus-viewer src_ext="AVZ" proxy_img= VARIABLE
</div>
</div></div>
</html>
edit2
So the java function I need to get is located in viewer-load.js called AnsysNexusViewer so I need to parse the string into this function. Is this is were Clientside Callbacks | Dash for Python Documentation | Plotly has to be used?
Next step:
from dash import Dash, dcc, html, Input, Output, callback, clientside_callback
import pandas as pd
def read_first_line(filename):
with open(filename, 'r') as f:
first_line = f.readline()
return first_line
filename = 'pictest.txt'
first_line = read_first_line(filename)
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Div(id='test'),
html.Button('Button', id='button'),
])
clientside_callback(
"""
function() {
return AnsysNexusViewer(src_ext="AVZ",proxy_img=first_line);
}
""",
Output('test', 'children'),
Input('button', 'n_clicks')
)
if __name__ == '__main__':
app.run(debug=True)
from the viewer_load.js I have this Class:
class AnsysNexusViewer extends HTMLElement {
// Called at object creation
constructor() {
super();
this._guid = this.generateUID();
this._renderer = "webgl"; // 'webgl' or 'envnc'
this._renderer_options = null; // pass-thru to the renderer
this._src = null; // 3D data source URL
this._src_ext = null; // 3D data source extension (type) used with data URI src values
this._proxy_img = null; // proxy image URL
this._proxy_size = [0, 0]; // The size of the proxy image
this._observer = null; // resizing observer
this._perspective = false; // perspective mode
this._aspect_ratio = null; // aspect_ratio override
this._render_instance = null; // The specific instance for the target renderer
this._proxy_only = null; // if not null, proxy hover message. No activation possible.
this._ui = ""; // 'envnc' renderer uses this to selected a UI. 'none' or 'simple'
}
The files are located in the assets folder. So I assume Dash knows about the different java scripts.
So I would assume that I need to activate this class which return a html element. I am ativated the clientside callback by pressing the button. The function does not take any inputs. But the function inside does. But it doesnt really works, get this error
TypeError: Cannot read properties of undefined (reading ‘children’)
at _callee3$ (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:577:58)
at tryCatch (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:411:2404)
at Generator._invoke (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:411:1964)
at Generator.next (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:411:3255)
at asyncGeneratorStep (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:415:103)
at _next (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:416:194)
at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:416:364
at new Promise (<anonymous>)
at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:416:97
at handleClientside (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_9_0m1685019644.dev.js:529:28)
So am I getting closer or further away from a solution?