Phoenix에서 elm-vega - 자바 스크립트에서 포트로 헤드리스 Elm

얼마 전, elm-vega로 그래프 그리기 - 자바 스크립트에서 포트로 헤드리스 Elm - Qiita 에서 elm-vega 라이브러리를 소개했습니다. 이번에는 Phoenix에서이 라이브러리를 사용하고 싶습니다.

그럼 이제 프로젝트를 시작합시다.
mix phx.new phoenix_elm_vega --no-ecto
cd phoenix_elm_vega

Phoenix에서 Elm을 사용할 수 있도록 elm-brunch를 설치합니다.
cd assets/
npm install --save-dev elm-brunch

 설정 파일을 수정하여 (A)와 (B)를 추가합니다.

assets/brunch-config.js
#
  paths: {
    // Dependencies and current project directories to watch
//---------- (A)"elm"を追加
    watched: ["static", "css", "js", "elm",  "vendor"],
//----------
    // Where to compile files to
    public: "../priv/static"
  },

  // Configure your plugins
  plugins: {
    babel: {
      // Do not use ES6 compiler in vendor code
      ignore: [/vendor/]
    },
//---------- (B)elmBrunch項を追加
    elmBrunch: {
      elmFolder: "elm",
      mainModules: ["Walkthrough.elm"],
      outputFolder: "../vendor"
    }
//----------
  },
#

assets 아래에 elm 디렉토리를 작성하고 elm-vega 라이브러리를 설치합니다.
mkdir elm
cd elm
elm-package install gicentre/elm-vega

이번 프로그램은 공식 사이트 elm-vega - Declarative visualization for Elm의 example에서 HelloWorld.elm을 이용합니다.

helloWorld.html의 내용으로 app.html.eex를 바꿉니다. 변경 사항은 helloWorld.js를 명시적으로 로드하는 행을 삭제한 점과 Elm.HelloWorld.worker() 행을 삭제하고 app.js를 로드하는 행을 추가한 것입니다. Elm.HelloWorld.worker() 행은 app.js로 옮겨졌습니다. helloWorld.js는 brunch가 암시 적으로로드합니다.

lib/phoenix_elm_vega_web/templates/layout/app.html.eex
<!DOCTYPE html>

<head>
  <title>Hello World from Elm-Vega</title>
  <meta charset="utf-8">

  <!-- These scripts link to the Vega-Lite runtime -->
  <script src="https://cdn.jsdelivr.net/npm/vega@3"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-lite@2"></script>
  <script src="https://cdn.jsdelivr.net/npm/vega-embed@3"></script>

</head>

<body>
  <!-- The id indicates the container in which to embed the Vega-Lite output. -->
  <div id="vis"></div>

  <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
</body>

</html>

  다음에 app.js의 말미에 다음의 행을 삽입합니다. 이제 Elm의 헤드리스 프로그램을 작동시킵니다. Elm 코드의 HelloWorld.elm 컴파일 결과 helloWorld.js가 자동으로 로드됩니다. 그래서 여기에서는 Elm.HelloWorld는 이미 참조 가능한 변수입니다.

assets/js/app.js
#
    Elm.HelloWorld.worker().ports.elmToJS.subscribe(function(specs) {
      // Change actions to true to display links to source, editor and image.
      vegaEmbed("#vis", specs, {actions: false}).catch(console.warn);
    });
#

마지막으로 Elm 프로그램을 작성해 둡니다.

assets/elm/HelloWorld.elm
port module HelloWorld exposing (elmToJS)

import Platform
import VegaLite exposing (..)


myVis : Spec
myVis =
    toVegaLite
        [ title "Hello, World!"
        , dataFromColumns [] <| dataColumn "x" (Numbers [ 10, 20, 30 ]) []
        , mark Circle []
        , encoding <| position X [ PName "x", PmType Quantitative ] []
        ]



{- The code below is boilerplate for creating a headless Elm module that opens
   an outgoing port to JavaScript and sends the Vega-Lite spec (myVis) to it.
-}


main : Program Never Spec msg
main =
    Platform.program
        { init = ( myVis, elmToJS myVis )
        , update = \_ model -> ( model, Cmd.none )
        , subscriptions = always Sub.none
        }


port elmToJS : Spec -> Cmd msg

 이상으로 설정과 프로그램 작성을 종료합니다. phoenix를 시작해 봅시다.
mix phx.server

브라우저를 열면 다음과 같은 이미지가 표시됩니다.


음, 문제는 앞으로입니다. 이번에는 이전과 다른 example을 사용했습니다. 이전의 example의 vega-lite spec에 포함되는 "data":{"url":"data/seattle-weather.csv"},의 처리가 phoenix상에서 잘 동작하지 않았기 때문입니다. phoenix의 설정과 사용법을 바꾸면 잘 작동하지만 적어도 가장 간단한 정적 설정에서는 오류가 발생했습니다. 왜냐하면 지금은 알 수 없지만, elm-reactor에서도 같은 문제가 일어나고 있기 때문에, Vega-Lite 런타임의 문제일지도 모릅니다. 또 원인이 분명하면 보고하는 것으로, 이번은 이것으로 끝내고 싶습니다.

좋은 웹페이지 즐겨찾기