jupyter-js-notebook
jupyter-js-notebook copied to clipboard
Widgets
- [x] Checking the recent ipywidgets changes with the current hack in the notebook to make sure the framework still works well
- [x] Make an easy way to transform from backbone views to phosphor views that are displayed. Perhaps at the WidgetManager displaying logic level.
- [x] Minimally wrap widgets
- [x] Get it working in the new notebook
- [ ] Clean up each view, removing jquery and bootstrap dependencies
- [x] Rewrite tab widget with phosphor tabs
- [ ] accordion widget
- [ ] test controller view
- [x] all other cleanups
Widget output system
- [x] JASON email the list for comments on changing how widgets are displayed
- [x] JASON Fix widget python code to use ipython display system instead of comm messages
- [x] adding a widget renderer to the transformime code to be able to display widgets in the output area of a cell. This would take the widget data {'application/jupyter-widget': 'model-id-of-widget'}.
- [ ] Output area widget
- [x] ping Jon
- [x] Python side: capture output messages with a context manager and store them instead in the widget state
- [ ] javascript side: give the appropriate transformime instance to the output widget view so that it can render the outputs
- [x] Creating an output display class that takes in the widget mimetype and displays the correct model in the appropriate place in the output area.
ow1 = OutputWidget()
display(ow1) # send display_data message
with ow1.capture(): # or with ow1:
plot(x,y)
with ow2.capture()
plot(x2,y2)
ow1.clear_output()
x = IntSlider()
display(x)
display(plot(data, data*x.value))
def x_change(name, value):
clear_output()
plot(data, data*x.value)
x.on_trait_change(x_change)
CCing @jdfreder, @SylvainCorlay @sccolbert @dwillmer @blink1073 @afshin
Ref: https://github.com/jupyter/jupyter-js-plugins/pull/89, which demonstrated a functioning slider using [email protected]
.
@jdfreder, @SylvainCorlay - is that a current enough version of jupyter-js-widgets to build on? Or are there unreleased changes that we should test? Sylvain was mentioning that maybe we should bump the jupyter-js-widgets version to have the latest...
Sylvain pointed out that ipywidgets needs an update to deal with the most recent jupyter-js-services: https://github.com/ipython/ipywidgets/issues/381
Actually, that issue may not impact us, because we handle hooking the widget manager up to comm targets ourselves.
That may actually be closed by ipython/ipywidgets#382 . I pinged the author
/cc @lbustelo @jhpedemonte
please cc @fperez and myself on this stuff...
Also, I am concerned about "getting the notebook working in JupyterLab" becoming a much larger "completely redesign the notebook" that delays JupyterLab too much. I would prefer to first get the same (features, design, UX, etc) notebook (but refactored code) working in JupyterLab so users have full feature parity and then begin to evolve it in subsequent major releases.
Please keep in mind that these changes for widgets are to "refactor" the widget code to finally complete the separation we couldn't quite do because of hardcoded hacks in the current notebook. It also makes it work with the design we're doing here a lot better.
I also am trying to be conservative about the changes in this initial release. I think finally being able to clean out the widget code out of the main notebook is a good thing and will make things easier and better in the short and long run.
I think this work will also improve the lives of other people using widgets outside of the context of the notebook already, like our friends at IBM.
I just realized a big problem with having a global renderer for display_data messages that is supposed to render notebook-specific widgets - of course the global renderer does not have access to notebook-specific state, so you can't just say "render widget model id blah" and have it know what to do, because all it gets is the message and nothing else.
Some workarounds:
- put all widget state in the display_data message, a la react. Then the widget renderer doesn't ever need notebook state to render a widget. Widget state is automatically stored in the notebook format.
- We could have a notebook extension service. A plugin can register a callback with the notebook extension service. When a new notebook is created, the callback is called with extension points for the specific notebook (e.g., functions to register comm targets, notebook-specific mime renderers, etc.). The callback returns a disposable object. When the notebook is destroyed, it disposes the object.
CC @jdfreder, @blink1073
@jasongrout By "global renderer" and "notebook-specific widgets", do you mean that there is one display_data
function in the app container that handles rendering for multiple notebook document views? I ask because I'm curious what problem you hit that we haven't yet hit in the dashboard_server
where we have one display_data
function ...
Right - with the current design, there is one application-wide renderer, but to render widgets, they depend on state that is tied to a single notebook's state.
Got it. We haven't hit it in dashboard_server
because there's a 1:1 mapping there between dashboard-notebook and page (at the moment).
It seems like 1) is cleaner and provides a straight path to serialization/deserialization.
Agreed, 1 makes more sense. It's a little awkward to think that the widget state for redisplayed items will be duplicated across cells, but apart from having document level state in nbformat I see no way around that.
I think 2 makes more sense given our current architecture. Sounds like a good discussion for next week!
On Fri, Mar 25, 2016, 11:16 Jonathan Frederic [email protected] wrote:
Agreed, 1 makes more sense. It's a little awkward to think that the widget state for redisplayed items will be duplicated across cells, but apart from having document level state I see no way around that.
— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/jupyter/jupyter-js-notebook/issues/34#issuecomment-201328438
Interested in hearing you out, see you Monday!
@dwillmer, @sccolbert, and I had a long conversation today about the output area widget. Here are some takeaways from our discussion:
- It's very tricky and we have a lot of not very nice smelling alternatives for rendering arbitrary output in a widget container.
- The basic idea is to let the user create UIs with widgets, but also provid the full power of the IPython display protocol/ecosystem.
- One way to do this is to set up a generic output redirection mechanism on the browser side. When an output is rendered, there is a way to redirect the output to some other DOM node. This is effectively what is done by the current ProxyWidget in ipywidgets, and is similar to how the Sage cell server provided addressable output. A nice thing is that all output messages still go through the same pipeline to the browser.
- If instead we redirect output messages on the kernel-side, another way to do have an output widget is for the widget manager to provide to the output widget some contextual rendermime. The output widget uses this rendermime as a black box. One question is what this rendermime would return. If we insist that it must return a DOM node, then the widget manager could adapt the notebook-level rendermime to return a DOM node. For example, it could take a rendermime returning a phosphor widget and rip the DOM node out (ugly and bad). The widget manager could also take the notebook-level rendermime and attach its output to a DOM node (better, but leads to having a phosphor widget inside of a DOM node inside of a Backbone view inside of a phosphor widget, since the current widgets are built on Backbone Views). Also, should the widget manager provide this rendermime to all widgets, or just some with certain metadata?
- More generically, the widget manager could provide widgets (some or all) with just the render callback function that would take a mimebundle and return (a DOM node?).
Edit: We're letting the ideas simmer for a day, since no option seemed like a really good clear way forward. @sccolbert, @dwillmer - feel free to comment more.
CC @ellisonbg, @jdfreder, @SylvainCorlay for comments. I'm also interested in hearing how you think these sorts of ideas can work in other contexts like a static page, nteract, or the current notebook.
Another idea on the output widget: perhaps a minimal stub implementation can be defined in ipywidgets (perhaps that just displays plain/text or something), but the widget manager can override that stub implementation to define a richer output widget based on the environment rendermime. Then the widget manager can pass the environment information (i.e., the environment rendermime) through a closure, rather than making it available to all plugins.
We still have the issue that the environment rendermime's output needs to be converted to a backbone view. Presumably the widget manager knows how to do this since it knows what kind of rendermime it is registering for.
@SylvainCorlay - how hard would it be for a widget manager to override an existing javascript widget implementation with a new one?
It seems weird that output-area is tied to widgets. Isn't the output-area a general purpose location for all cell output?
@lbustelo There's a bit of overlapping terminology here. The "output area" is the output portion of a cell which renders the arbitrary mime bundle content, some of which may be ipy widgets. The "output widget" is an ipy widget that can render the content of an arbitrary "output area" by intercepting the output messages for that area. The use case for this is assembling app-like interfaces which contain sliders and buttons and what-not, but also the content for selected output messages. This is naturally a recursive relationship since those output messages may themselves render widgets. It is definitely a bit wonky, and we haven't yet come up with a good pattern for expressing this.
It is definitely a bit wonky, and we haven't yet come up with a good pattern for expressing this.
Facing similar issues in dashboard server.
@parente - can you elaborate on the relevant issues you've faced in the dashboard server?
Much simpler than what you're facing with the output widget for sure: https://github.com/jupyter-incubator/dashboards_server/issues/188