대시보드도 만들 수 있는 Stipple.jl 소개

Stipple 소개



Julia의 웹 프레임 워크에는 Genie가 있습니다. Julia의 기능을 살리고 있어, 매우 사용감이 좋은 패키지입니다만, 영어/일본어 불문하고 아직 아직 샘플이 적은 상태입니다. 그런 가운데 Genie.jl 의 관련 정보를 알고 있으면 JuliaCon 2020 에서 Genie 의 작가인 Adrian Salceanu 씨가 Stipple 웹 서버 너머로 데이터 바인딩을 실현하고 있는 재미있는 패키지이므로, 간단하게 소개하고 싶습니다.

설치



Genie는 웹 서버용 프레임워크로, 그 위에 Stipple이라는 패키지가 있습니다. 이 두 가지를 설치합니다.
pkg> add Genie
pkg> add Stipple

실행



Julia REPL에서 다음 코드를 실행합니다.
using Genie, Genie.Router, Genie.Renderer.Html, Stipple

# define (reactive) model
Base.@kwdef mutable struct Name <: ReactiveModel
  name::R{String} = "World!"
end

# initialize the model
model = Stipple.init(Name)

# define UI
function ui()
  page(
    root(model), class="container", [
      h1([
        "Hello "
        span("", @text(:name); style="color:red")
      ])

      p([
        "What is your name? "
        input("", placeholder="Type your name", @bind(:name))
      ])
    ], title="Basic Stipple"
  ) |> html
end

# bind root "/" to ui
route("/", ui)

# start web server
up()
up() 를 실행하면 웹 서버가 시작됩니다. 환경에 따릅니다만, 예를 들면 아래와 같이 표시되므로, 브라우저로부터 액세스 해 봅니다.
``
Web Sockets server running at 127.0.0.1:8001

Web Server starting at htp://127.0.0.1:8000

Web Server running at htp://127.0.0.1:8000
Genie.AppServer.ServersCollection(Task (runnable) @0x0000000015eae850 , Task (runnable) @0x00000000356d2e10 )
``


이때 Julia REPL에 아래와 같은 에러가 나오는 경우가 있습니다만, 아마 favicon.ico가 없기 때문에 나와 있을 뿐이므로 무시해 ok입니다.
[ Info: / 200
[ Info: / 200
 Error: error handling request
   exception =
    IOError: stream is closed or unusable
    Stacktrace:
     [1] check_open at .\stream.jl:328 [inlined]
      ...
     [12] (::HTTP.Servers.var"#13#14"{HTTP.Handlers.var"#4#5"{HTTP.Handlers.RequestHandlerFunction{Genie.AppServer.var"#6#12"}},HTTP.ConnectionPool.Transaction{Sockets.TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}})() at .\task.jl:356
 @ HTTP.Servers C:\Users\dskkato\.julia\packages\HTTP\atT5q\src\Servers.jl:373
[ Info: /css/stipple/stipplecore.min.css 200
[ Info: /js/stipple/vue_filters.js 200
[ Info: /js/stipple/stipplecore.js 200
[ Info: /js/stipple/vue.js 200
[ Info: /js/stipple/underscore-min.js 200
[ Info: /__/channels.js?v=1.1.0 200

움직여 보자



Stipple의 UI 부분에는 Vue가 사용되고 있는 것 같고, 컴퍼넌트간의 데이터를 동기화해 줍니다. 또한 Julia-REPL과 양방향 데이터 바인딩을 제공 실현하고 있습니다. 하나씩 시도해 봅시다.

UI의 구성 요소 간 동기화



먼저 이전 화면의 텍스트 상자에 있는 World! 그러면 빨간색 문자 부분도 입력에 따라 자동으로 변경됩니다. Vue나 React등을 접한 적이 있는 분이라면 친숙한 조작인가라고 생각합니다.



Julia와의 양방향 데이터 바인딩



UI -> Julia



Stipple의 중심은 이것이라고 생각합니다. 방금 전 Julia!로 다시 쓴 상태에서 모델의 상태를 확인해 보겠습니다. 제대로 Julia! 에 갱신되고 있네요.
julia> model
Name(Observable{String} with 1 listeners. Value:
"Julia!")

Julia -> UI



다음으로 Julia 측에서 조작해 보겠습니다. 이때, 오리지날의 String 객체를 재작성한 것을 알 수 있도록(듯이) Julia! 로 참조를 취해 와 갱신할 필요가 있는 보고 싶습니다.
julia> model.name[] = "Julia-REPL"

아래와 같이 쓰면 Stipple이 객체의 업데이트를 추적할 수 없게 되고, 잘 움직이지 않게 되므로 주의가 필요합니다.
julia> model.name = "Julia-REPL"

곧 UI에도 반영됩니다.



카운트다운



마지막으로 간단한 카운트다운을 움직여보겠습니다.
for i in reverse(0:10)
  model.name[] = "$i"
  sleep(1)
end 

(화면은 그중 up합니다...)

Stipple의 잠재력



JuliaCon 2020에서의 발표 자료나 Discorse를 보고 있으면 대시보드를 만들 수 있는 정도에는 개발이 진행되고 있는 것 같습니다. 다소 HTML을 모르면 사용하기 어려울지도 모릅니다만, 간단한 GUI에도 사용할 수 있는 것 같은 인상을 받았습니다.

Julia REPL->UI의 플로우가 브로드캐스트되고 있는 것 같고, 멀티 클라이언트의 상태에서도 모든 상태가 갱신됩니다. 아쉽게는 UI에서의 작업이 다른 클라이언트에 반영되지 않았습니다. REPL로부터는 되어 있기 때문에, 큰 문제는 아닐지도 모릅니다만.

Demos (리포지토리에서 전재)


  • German Credits visualisation dashboard
  • Iris Flowers dataset k-Means clustering dashboard

  • 관련 정보



  • Stipple: Reactive data dashboards with Julia [WIP] in Discourse.

  • repo on the GitHub
  • Interactive data dashboards with Julia and Stipple in JuliaCon 2020
  • 좋은 웹페이지 즐겨찾기