jupyter-js-notebook icon indicating copy to clipboard operation
jupyter-js-notebook copied to clipboard

Widgets

Open jasongrout opened this issue 9 years ago • 26 comments

  • [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)

jasongrout avatar Feb 22 '16 18:02 jasongrout

CCing @jdfreder, @SylvainCorlay @sccolbert @dwillmer @blink1073 @afshin

jasongrout avatar Feb 22 '16 19:02 jasongrout

Ref: https://github.com/jupyter/jupyter-js-plugins/pull/89, which demonstrated a functioning slider using [email protected].

blink1073 avatar Feb 22 '16 19:02 blink1073

@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...

jasongrout avatar Feb 22 '16 19:02 jasongrout

Sylvain pointed out that ipywidgets needs an update to deal with the most recent jupyter-js-services: https://github.com/ipython/ipywidgets/issues/381

jasongrout avatar Feb 22 '16 19:02 jasongrout

Actually, that issue may not impact us, because we handle hooking the widget manager up to comm targets ourselves.

jasongrout avatar Feb 22 '16 20:02 jasongrout

That may actually be closed by ipython/ipywidgets#382 . I pinged the author

jdfreder avatar Feb 22 '16 20:02 jdfreder

/cc @lbustelo @jhpedemonte

parente avatar Feb 25 '16 13:02 parente

please cc @fperez and myself on this stuff...

ellisonbg avatar Feb 25 '16 18:02 ellisonbg

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.

ellisonbg avatar Feb 25 '16 18:02 ellisonbg

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.

jasongrout avatar Feb 25 '16 19:02 jasongrout

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.

jdfreder avatar Feb 25 '16 21:02 jdfreder

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:

  1. 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.
  2. 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 avatar Mar 25 '16 05:03 jasongrout

@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 ...

parente avatar Mar 25 '16 12:03 parente

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.

jasongrout avatar Mar 25 '16 12:03 jasongrout

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).

parente avatar Mar 25 '16 13:03 parente

It seems like 1) is cleaner and provides a straight path to serialization/deserialization.

blink1073 avatar Mar 25 '16 13:03 blink1073

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.

jdfreder avatar Mar 25 '16 15:03 jdfreder

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

jasongrout avatar Mar 25 '16 17:03 jasongrout

Interested in hearing you out, see you Monday!

jdfreder avatar Mar 25 '16 20:03 jdfreder

@dwillmer, @sccolbert, and I had a long conversation today about the output area widget. Here are some takeaways from our discussion:

  1. It's very tricky and we have a lot of not very nice smelling alternatives for rendering arbitrary output in a widget container.
  2. The basic idea is to let the user create UIs with widgets, but also provid the full power of the IPython display protocol/ecosystem.
  3. 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.
  4. 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?
  5. 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.

jasongrout avatar Apr 19 '16 21:04 jasongrout

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?

jasongrout avatar Apr 20 '16 16:04 jasongrout

It seems weird that output-area is tied to widgets. Isn't the output-area a general purpose location for all cell output?

lbustelo avatar Apr 20 '16 16:04 lbustelo

@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.

sccolbert avatar Apr 20 '16 17:04 sccolbert

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 avatar Apr 20 '16 17:04 parente

@parente - can you elaborate on the relevant issues you've faced in the dashboard server?

jasongrout avatar Apr 20 '16 18:04 jasongrout

Much simpler than what you're facing with the output widget for sure: https://github.com/jupyter-incubator/dashboards_server/issues/188

parente avatar Apr 20 '16 18:04 parente