[ANN] StippleMakie.jl - easy integration of Makie plots into GenieFramework

[ANN] StippleMakie

Having started off at the hackathon of JuliaCon 2024 we’re happy that we can finally release the first version of StippleMakie.
It brings together the best of two worlds - the completeness of the GenieFramework UI with the beauty and richness of Makie plots.

The figures resize with the html layout

Demo App

Here’s a small demo app.

using Stipple, Stipple.ReactiveTools, StippleUI
using StippleMakie

Stipple.enable_model_storage(false)

@app MakieDemo begin
    @out fig1 = MakieFigure()
    @out fig2 = MakieFigure()
    @in hello = false

    @onbutton hello begin
        @notify "Hello World!"
    end

    @onchange isready begin
        init_makiefigures(__model__)
        
        onready(fig1) do
            Makie.scatter(fig1.fig[1, 1], (0:4).^3)
            Makie.heatmap(fig2.fig[1, 1], rand(5, 5))
            Makie.lines(fig2.fig[1, 2], cos.(0:2π/100:2π))
        end
    end
end

UI::ParsedHTMLString = column(style = "height: 80vh; width: 100%", [
    h4("MakiePlot 1")
    cell(col = 4, class = "full-width", makie_figure(:fig1))
    h4("MakiePlot 2")
    cell(col = 5, class = "full-width", makie_figure(:fig2))
    (btn("Hello", @click(:hello), color = "primary"))
])

ui() = UI

route("/") do
    WGLMakie.Page()
    model = @init MakieDemo    
    html!(ui, layout = Stipple.ReactiveTools.DEFAULT_LAYOUT(head_content = [makie_dom(model)]), model = model, context = @__MODULE__)
end

up(open_browser = true)

Hosting

StippleMakie is running two websocket stacks in parallel. If your provider doesn’t allow two ports to be used you can configure a basepath for the Makie stack and a proxy server to separate the two. We have configure_makie_server!() and nginx_conf() to make this setup as easy as possible.

Kudos

  • to Simon Danisch who gave me a boost in understanding of Bonito’s websocket stack
  • to the organizers of the hackathon; without them this package would not have come into existence
  • to Adrian Salceanu for the coffee :wink:
18 Likes

That knowledge needs to be published somewhere. The existing docs on WebSockets in Genie.jl leaves a lot of details out.

  • The main source of confusion for me was how the docs used the word “channel” in two different but related ways.
    • A channel is a bidirectional medium through which WebSocket messages travel.
    • There’s also a server-side channel(route, handler) method that doesn’t create a channel. It creates a route handler for WebSocket messages.
  • The naming of channel route handlers has some rules that are not mentioned.
    • The first segment of the route has to be a channel name.
    • That’s why the built-in /____/subscribe and /____/unsubscribe channel routes are named that way.
    • ____ is the name of the channel they operate on.

A new version is out with a Julia proxy. So StippleMakie can live on a single port without any external software.

3 Likes