fsprojects / IfSharp

F# for Jupyter Notebooks
Other
442 stars 71 forks source link

Javascript interop should provide element for js callbacks #223

Closed aprooks closed 5 years ago

aprooks commented 5 years ago

I've been trying to implement something like this https://gist.github.com/fabriziopandini/7e8efdd7063a518a2d2d#file-chartjs-ipython-py-L30. IPython provides element in JS callback which is an output cell. Which in turn allows better customization and improved workflow with some JS libraries

Browsing through issues I've found #126 to be very close to what I'd like to achieve.

cgravill commented 5 years ago

Have you seen the example in the feature notebook? It has an example of interop with D3 where it creates a new div and manipulates that. That seems a controlled way of interacting with JavaScript libraries.

aprooks commented 5 years ago

This approach only works with d3 because it registers itself as a global dependency, Modern libraries are using require it won't work as with d3.

cgravill commented 5 years ago

I'm a bit confused what you're after. Dependency resolution is different from having a magic element.

Separately it's not clear if the sort of magic IPython provide provides is a good idea. It would be risky for us to introduce as previously element hasn't been used in this.

aprooks commented 5 years ago

I think what I wanted was something like this:

// helper or util function
let runJavascript (js:string)  = 
    let id = System.Guid.NewGuid().ToString()
    sprintf """
        <div id='cell-%s'></div> 
        <script type='text/javascript'>
           var element = document.querySelector('#cell-%s'); 

           (function() {
               %s
           })();
        </script>""" id id js
    |> Util.Html |> Display

actual code in a cell

"""
var graph = new Rickshaw.Graph( {
    element: element,
    width: 300, 
    height: 200, 
    series: [{
        color: "steelblue",
        data: [ 
            { x: 0, y: 40 }, 
            { x: 1, y: 49 }, 
            { x: 2, y: 38 }, 
            { x: 3, y: 30 }, 
            { x: 4, y: 32 } ]
    }]
}); 
graph.render();
""" |> runJavascript

so it's just a way of running js code without bothering with fake html creation all the time. I will close this issue since this helper I've written is enough for me

cgravill commented 5 years ago

Great, glad you found a solution.

JavaScript/Jupyter interop is very powerful but a bit messy, not sure the best set of options to provide, but that might make sense for some people.