これはGo 4 Advent Calendar 2020 18日目の記事です
こんにちは株式会社カミナシのエンジニアの浦岡です。
個人的に、Goが一番輝きを放つのはworkflowの自動化だと思っています。 k8sなど自動化分野でGoはなくてはならない存在ですよね!
ただ、そのworkflow、テキストで記述するか、画面があってもフローチャートのような物が多く、どこか味けなくないでしょうか?
見た目大事!!
少しジャンルは違いますが、こちらIntegromatというiPaaSのworkflow画面です。なんとも個性的じゃないですか?幾何学的なデザインが自動化魂に火をつけてくれます🔥🔥
「よし、Workflow作るぞ!」と思い立ったユーザーを盛り立ててくれる演出があってもいいのではないでしょうか? 今回モックレベル(見た目だけ)ですが、それっぽい物ができるかチャレンジします!
※GoのAdvent Calendarですが、Goのソースは一切出てきません🙏
チャレンジ
workflowはブラウザ上で扱えるように、webアプリとして作成します。 フレームワークには、Goと同じくgoogle製のAngularを使ってみます。
具体的には以下のworkflowの構成要素を作ります。
ノードの作成
まず、以下の構成でノードとソケットを作ります。
ノードはドラッグ操作で移動できるように、Angular CDKのDrag and Dropを使用。
<div class="node" cdkDrag (cdkDragMoved)="handleDragMoved($event)" [cdkDragFreeDragPosition]="node.initialPosition" (cdkDragMoved)="handleDragMoved($event)"> <input-socket *ngIf="node.inputSocket"></input-socket> <div class="circle"> {{node.icon}} </div> <div class="title">{{node.title}}</div> <output-socket *ngIf="node.outputSocket"></output-socket> </div>
下のようなjsonを基にノードが描画されます。
パスの作成
次にノード間を連結するパスで、これはCSSではなくSVGでレイアウトするようにしました。 SVG要素として表現することで、後々アニメーションなども仕込みやすくなるはずです。
<div class="svg-area"> <svg class="full-screen"> <path *ngFor="let path of paths" class="svg-path" stroke-dasharray="7, 5" [attr.d]="getD(path)" /> </svg> </div> <node *ngFor="let node of nodes" [node]="node" (changePosition)="handleChangeNodePosition($event)"></node>
public static getD(startPosition: Position, endPosition: Position): string { const hx1 = startPosition.x + Math.abs(endPosition.x - startPosition.x) * 0.8; const hx2 = endPosition.x - Math.abs(endPosition.x - startPosition.x) * 0.8; return `M ${startPosition.x} ${startPosition.y} C ${hx1} ${ startPosition.y } ${hx2} ${endPosition.y} ${endPosition.x} ${endPosition.y}`; }
パスは下のようなfrom, toのノードのidだけ持たせたjsonです。
と、かなり中途半端なところでタイムアップしてしまいました、今回作ったソースはこちら stackblitz.com
今後について
- データ構造は見直す必要ありそうです(AWS Step Functionsあたりが参考になるかもしれません)
- monacoエディター組み込んでソース記述できるようになると便利そう
などなど
完成までの道のりは遠そうですが、まずはworkflowの定義情報をjsonファイルなりでインポート/エクスポートできるところを目指したいところです。(需要ありそうであれば、続き書きます)