Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class based alternative to using outputs as inputs #975

Open
gshotwell opened this issue Jan 5, 2024 · 1 comment
Open

Class based alternative to using outputs as inputs #975

gshotwell opened this issue Jan 5, 2024 · 1 comment

Comments

@gshotwell
Copy link
Contributor

gshotwell commented Jan 5, 2024

We have a few cases where outputs can become inputs for example:

  • Clicking or brushing on a plot
  • Selecting the row of a data frame
  • Selecting the point on a map

In all of these cases we implicitly create a new input object by appending some text after the output id, and registering it as an input. So in this example we have an output id plot1 and the input becomes input_plot1_click().

ui.output_plot("plot1", click=True, dblclick=True, hover=True, brush=True),

@render.text()
def click_info():
      print(input.plot1_click())

This is a pretty confusing API because it's hard for the user to know that the input exists, and it takes a bit of thinking to see how the id that you assigned to the output turns into the new input method. You also can't inspect the object to see what type of interaction is available, and it's hard to document the ways that outputs can be used as inputs. For example we don't have anything on how to access row selection in https://shiny.posit.co/py/api/ui.output_data_frame.html.

With @schloerke's changes to the rendering classes it seems like we create a class-based interaction to solve this problem, where a plot output would produce a class with click, dbl_click, hover and brush methods. and would be called like this:

ui.output_plot("plot1", click=True, dblclick=True, hover=True, brush=True),

@render.text()
def click_info():
     print(plot1.click())

I think this is less magical and a lot easier to document. We could have a section of the output documentation which defines the reactive output class and show the user all of the methods. This will be particularly important with some of the datagrid work because we probably want to expose a lot of methods around data frame editing.

@cpsievert
Copy link
Collaborator

I'm pretty sure we'd want to provide the inputs as attributes on the function decorated by @render.*, which is essentially what I plan on doing for {shinywidgets} (posit-dev/py-shinywidgets#119). So, for example, the API would look something like:

@render.plot
def my_plot():
    # plotting code

@render.text
def click_info():
    return my_plot.click()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants