ANN: Custom Widget recipes for web apps and the new and improved Interact.jl package

This is to announce simultaneously two things:

  1. Widgets.jl: a package to create “UI recipes”

  2. The imminent release of the new and improved Interact.jl

Widget recipes

Full documentation is available here. This package provides the @widget macro to define and register custom widgets as well as the @output!, @display! and @layout! macro to set the output of a widget, the way it’s displayed and to reorganize the layout.

using Plots, DataFrames, Interact
@widget wdg function mywidget(df::DataFrame)
    :df = df
    :options = names(:df)
    :select = dropdown(:options)
    :btn = button("Plot histogram")
    @output! wdg ($(:btn); histogram(:df[:select[]])) # when button is pressed, plot the histogram
    @layout! wdg vbox(hbox(:select, :btn), _.output) # define custom layout
end

df = DataFrame(x = rand(1000), y = randn(1000), z = rand(1000).^ 2)
ui = mywidget(df)

Also note that with minimal effort this GUI can be improved to accept an Observable of a DataFrame (meaning when the DataFrame changes, it updates automatically the option list):

@widget wdg function mywidget(df::Observable{<:DataFrame})
    :df = df
    :options =names($(:df))
    :select = dropdown(:options)
    :btn = button("Plot histogram")
    @output! wdg ($(:btn); histogram($(:df)[:select[]])) # when button is pressed, plot the histogram
    @layout! wdg vbox(hbox(:select, :btn), _.output) # define custom layout
end
df = Observable(DataFrame(x = rand(1000), y = randn(1000), z = rand(1000).^ 2))
ui = mywidget(df)

And now if say df[] = DataFrame(xx = randn(150), yy = 1:150), both the plot and the dropdown options will update automatically.

Also note that, even though the above example depends on Interact, it is possible to define these recipes while depending only on the low-dependency Widgets, which is handy if you want to define an interactive recipe for your custom type or analysis function in your own package.

New and improved Interact

This is a heads up that a new release of Interact is about to get tagged and the new Interact will be quite different from the old version. If you’re afraid that the update will break your code you can pin it for the time being: Pkg.pin("Interact", v"0.7.2") (see this post for a comparison of the old Interact with the new framework). The most basic things (the @manipulate macro) will continue to work and have improved capabilites (like nesting @manipulate calls or custom layout) but most other things will need a new syntax.

Interact has been repurposed to become a metapackage containing the following:

  • InteractBase for interactive widgets in native HTML
  • InteractBulma and InteractUIkit that are two “CSS” backends to give some default style to the widgets
  • Observables to create Observables, that is references to values that can be updated and have callbacks when updated
  • CSSUtil for styling and layouting widgets
  • WebIO to create DOM elements in Julia
  • Knockout for two-way data binding between Julia and Javascript using the knockoutjs library
  • Widgets, a low dependency library to define recipes for custom widgets

The advantage of combining all of these packages (they are separate packages but Interact reexport all of them) is twofold:

  • users will only need to remember to load one package
  • documentation is now available in one single place

Hopefully, together these packages create a good toolkit for web app development in pure Julia.

Feedback is welcome!

18 Likes