Skip to content

Commit 792ae5d

Browse files
committed
[jupyter] optimize jsroot loading
1. Use JavaScript `import()` function to load jsroot. Avoiding by-hand creation of script elements 2. Solves problem of multiple jsroot loading by different plots 3. Make code much more compact, produce the only global function per plot 4. Keep requirejs part to support Visual Studio Code 5. Tested both in `jupyter lab` and `jupyter notebook`
1 parent 4254e9d commit 792ae5d

File tree

1 file changed

+27
-50
lines changed
  • bindings/jupyroot/python/JupyROOT/helpers

1 file changed

+27
-50
lines changed

bindings/jupyroot/python/JupyROOT/helpers/utils.py

Lines changed: 27 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -49,60 +49,37 @@
4949

5050
_jsCanvasWidth = 800
5151
_jsCanvasHeight = 600
52-
_jsCode = """
5352

53+
_jsCode = """
5454
<div id="{jsDivId}" style="width: {jsCanvasWidth}px; height: {jsCanvasHeight}px; position: relative">
5555
</div>
56-
5756
<script>
58-
59-
function display_{jsDivId}(Core) {{
60-
let obj = Core.parse({jsonContent});
61-
Core.settings.HandleKeys = false;
62-
Core.draw("{jsDivId}", obj, "{jsDrawOptions}");
63-
}}
64-
65-
function script_load_{jsDivId}(src, on_error) {{
66-
let script = document.createElement('script');
67-
script.src = src;
68-
script.onload = function() {{ display_{jsDivId}(JSROOT); }};
69-
script.onerror = function() {{ script.remove(); on_error(); }};
70-
document.head.appendChild(script);
71-
}}
72-
73-
if (typeof requirejs !== 'undefined') {{
74-
75-
// We are in jupyter notebooks, use require.js which should be configured already
76-
requirejs.config({{
77-
paths: {{ 'JSRootCore' : [ 'build/jsroot', 'https://root.cern/js/7.7.4/build/jsroot', 'https://jsroot.gsi.de/7.7.4/build/jsroot' ] }}
78-
}})(['JSRootCore'], function(Core) {{
79-
display_{jsDivId}(Core);
80-
}});
81-
82-
}} else if (typeof JSROOT !== 'undefined') {{
83-
84-
// JSROOT already loaded, just use it
85-
display_{jsDivId}(JSROOT);
86-
87-
}} else {{
88-
89-
// We are in jupyterlab without require.js, directly loading jsroot
90-
// Jupyterlab might be installed in a different base_url so we need to know it.
91-
try {{
92-
var base_url = JSON.parse(document.getElementById('jupyter-config-data').innerHTML).baseUrl;
93-
}} catch(_) {{
94-
var base_url = '/';
95-
}}
96-
97-
// Try loading a local version of requirejs and fallback to cdn if not possible.
98-
script_load_{jsDivId}(base_url + 'static/build/jsroot.js', function(){{
99-
console.error('Fail to load JSROOT locally, please check your jupyter_notebook_config.py file');
100-
script_load_{jsDivId}('https://root.cern/js/7.7.4/build/jsroot.js', function(){{
101-
document.getElementById("{jsDivId}").innerHTML = "Failed to load JSROOT";
102-
}});
103-
}});
104-
}}
105-
57+
function process_{jsDivId}() {{
58+
function drawPlot(Core) {{
59+
Core.settings.HandleKeys = false;
60+
const obj = Core.parse({jsonContent});
61+
Core.draw("{jsDivId}", obj, "{jsDrawOptions}");
62+
}}
63+
const servers = ['/static/', 'https://root.cern/js/7.9.1/', 'https://jsroot.gsi.de/7.9.1/'],
64+
path = 'build/jsroot';
65+
if (typeof JSROOT !== 'undefined')
66+
drawPlot(JSROOT);
67+
else if (typeof requirejs !== 'undefined') {{
68+
servers.forEach((s,i) => {{ servers[i] = s + path; }});
69+
requirejs.config({{ paths: {{ 'jsroot' : servers }} }})(['jsroot'], drawPlot);
70+
}} else {{
71+
const config = document.getElementById('jupyter-config-data');
72+
if (config)
73+
servers[0] = (JSON.parse(config.innerHTML || '{{}}')?.baseUrl || '/') + 'static/';
74+
else
75+
servers.shift();
76+
function loadJsroot() {{
77+
return !servers.length ? 0 : import(servers.shift() + path + '.js').catch(loadJsroot).then(() => drawPlot(JSROOT));
78+
}}
79+
loadJsroot();
80+
}}
81+
}}
82+
process_{jsDivId}();
10683
</script>
10784
"""
10885

0 commit comments

Comments
 (0)