Open twavv opened 5 years ago
Thank you for posting this here. I would be totally happy to define a global object and add my extra js routines there.
How about having a command registry that is global?
How about having a command registry that is global?
As in like window.CommandRegistry
? I don't think that's a great idea, personally, because global variables are bad™. I can think of a few cons.
plot
method; this is somewhat solved by having namespaces (à la CommandRegistry.Plotly
) but still an issue (at least in principle).window.CommandRegistry.PlotlyJS.scatter
is defined instead of having an immediate handle to the correct method).Additionally, this kind of thing can be hacked without using globals provided by WebIO (e.g. if you really want to, define window.PlotlyJSCommands
with all your commands on it; it still has most of the issues described above but at least it's not prescribed by library code).
In that case, how about allowing a mechanism to inject a bunch of functions as commands? We'll need some kind of way for PlotlyJS to expose a function that does that?
function PlotlyStuff(webioInstance) {
this.WebIOCommandSet = true;
...
webioInstance.command1 = function () {..} // etc
}
module.exports = PlotlyStuff
when we load a js asset, we check to see if the object it exports has this.WebIOCommandSet, if yes, we call it with the webIO instance... This will be per-scope however.
Or actually we can just have PlotlyJS tach on a bunch of commands, such as:
this.CommandSets.Plotly = {command1: ...}
inside onimport
I don't know implications of all the different options and am happy to defer to @travigd and @shashi expertise here.
lol in other words I am happy to do whatever I'm told, as long as I can access my functions!
This conversation should probably be had at https://github.com/JuliaGizmos/WebIO.jl/issues/229.
But since I'm here, I think (once that commit is fully implemented) the idiomatic way to do things would simply be
Plotly = JSAsset("...")
w = Scope(...)
onjs(w["image"], @js function(value)
$w["image"] = @await (@await Plotly).toImage(...)
end)
# equivalently
w = Scope(...)
onjs(w["image"], @js function(value)
@var Plotly = @await $Plotly
$w["image"] = @await Plotly.toImage(...)
end)
I'm still definitely not a fan of having global (either global across everything or just global with respect to a single WebIO instance) command sets.
In that case I guess we can just delete the CommandSets feature, and allow PlotlyJS.jl itself to simply load its own JS module and use it.
That might be easier than trying to inject/attach it. I could just have my few functions be another dependency like plotly.js
Now that JupyterLab 1.0 is out more people will want to switch from Jupyter notebook to lab (me included). Is there something new on this issue?
PlotlyJS tries to access the global WebIO object - but it can't since that's not defined in JupyterLab (because JupyterLab opens multiple notebooks in one Javascript context and doing so leads to "cross-talk").
This works (everywhere, but notably in JupyterLab):
This does NOT work (in JupyterLab):
There are two ways to fix this.
We've discussed the latter API (in part of a discussion about making RPC's from JS into Julia) here (second comment). I'm not sure what the timeframe is on that though; we (well mostly @shashi at this point) are currently trying to implement request-response messaging which would be a pre-req.