Adobe XD プラグインでCSVからテーブルを描画させる

# はじめに
このエントリは [Hamee Advent Calendar 2018](https://qiita.com/advent-calendar/2018/hamee) ④日目の投稿です。（ちょっと遅れました、、）
担当しますのはHamee株式会社、新卒2年目デザイナーのブライアン([@skinnybrian_tw](https://twitter.com/skinnybrian_tw))です！
昨年はQiita初投稿にして初アドカレ参加したりして、人生2回目のQiita投稿になります。
これを気に定期的にアウトプットしていくぞ・・・！

# ところで

みなさんはなにかアプリとかサービス作るときにプロトタイプツールを使っていますか？
なんか最近やたらとプロトタイプツール出てきた気がしてます。ざっと

- Sketch
- InVision Studio
- Prott
- Indigo.Design
- Origami

・
・
・

ありすぎ！！やっぱりUIデザインとかするのにプロトタイプツールで実装前に確認とかできると超便利だし開発効率も上がります。
何より完成イメージがすぐ湧くから作っては壊して・・・のサイクルでもっと良いプロダクトができるようになります。

そんな中でも僕は[Adobe XD](https://www.adobe.com/jp/products/xd.html)を使っています。
前々からAdobe製品つかってきてたので操作感も似てるし、[最近アップデートも活発](https://www.adobe.com/jp/products/xd/features.html)なので新機能が発表されるたびにわくわくしてます。
最近だと、ボタンにアニメーション加えたり、音声アクションで動かせるようになったり・・・！？

<img width="1392" alt="スクリーンショット 2018-12-05 10.17.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/46556/36401836-b0d9-356e-30a4-eb9a9291b887.png">


## Adobe XD、無料プランあるってよ。
もうこのQiitaを読んだそこのあなた。今から試してみるしかない、今すぐみなさまDLして触れてみてください。
インストールしてすぐにチュートリアルファイルをいじれるので、これ触っただけでもう、できる気しかしなくなります。体験してみてください。

👇👇👇👇👇👇👇👇👇👇
https://www.adobe.com/jp/products/xd.html


# そしてそんなAdobe XDがついにプラグイン使えるようになった！ :tada:
### 📖公式リファレンスはこちら
https://adobexdplatform.com/


大学時代からAdobeユーザな僕ですが、とくにAdobe XDはPhotoshopやIllustratorに比べるととにかく動きも早くて、
プロトタイプレベルのレイアウトの配置がめちゃめちゃすばやく出来てとても使いやすいのがもう最高です。
そしてそんなXDがプラグイン対応なんてさ…最&高かよ。。
でもそんな僕はあんまり最近コード書いてなかったので今回超久しぶりに頑張って書きました。

#### (※筆者はXD大好きですが、JSは初心者です。どうぞお手柔らかに・・・)

# Step1. まずはHello, World!
とりあえずAdobeさんがとても初心者にも優しいブログ投稿されてたのでこれを参考に出してみることにします
👉 https://blogs.adobe.com/japan/web-getting-started-with-xd-plugin-development/

どうもJS使ってChrome拡張みたいな感覚で作れるみたいです。必要なのは以下の2ファイルだけ。

- manifest.json
    - プラグインの基本的な情報を記述
- main.js
    - メインの処理を記述

### 結果
無事に出ました。
<img width="610" alt="スクリーンショット 2018-12-05 9.02.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/46556/9d0b4be0-0477-9a59-e1dc-753140e2ae74.png">

![スクリーンショット 2018-12-05 9.04.36.png](https://qiita-image-store.s3.amazonaws.com/0/46556/dc5d96cb-7b44-8f4f-d61b-d11d1379364b.png)
ちゃんとデバッグコンソールもついてる。いつの間に・・・。
**メニューからプラグイン→開発版→Developer Consoleで表示できます**

# Step2. 長方形を出そう！
文字が出せるのがわかったので次は長方形ですね！
世の中のデザインパーツは丸と四角と線でできてるのでもう四角が出せれば無敵になれる気がしてきた。

参考にしてまずは`manifest.json`ファイルをつくってみます。
最終的にはCSVファイルからテーブル描画させたいのでそれを見越して記述します。

```javascript:manifest.json
{
  "id": "DRAW_TABLE_FROM_CSV",
  "name": "draw table from csv",
  "description": "CSVからテーブル描画させる",
  "version": "1.0.0",
  "host": {
    "app": "XD",
    "minVersion": "13.0.0"
  },
  "uiEntryPoints": [
      {
        "type": "menu",
        "label": "Draw Table From CSV",
        "commandId": "drawTableFromCSVCommand"
      }
   ]
}
```
### ここでのポイント
- `id`のところは本当は公式からちゃんとID発行してもらわないといけないみたいですがローカルの開発環境上では別にかぶんなかったら大丈夫っぽい
- `uiEntryPoints`の`label`部分に、XDのメニューでどう表示されるかを書いて、それを押したらどの処理を実行させるかを`commandId`に書く

<img width="593" alt="label.png" src="https://qiita-image-store.s3.amazonaws.com/0/46556/fdb6f005-f1d6-3942-7cf2-19c2ef4ec3fd.png">

### 長方形だけ出す処理
```javascript:main.js
const { Rectangle, Text, Color} = require("scenegraph"); // 長方形を描画するのでRectangleを追加

function drawTableFromCSVHandler(selection) { // メインのファンクション
  console.log("my function is called!"); // Developer Consoleに出力

  // まずは長方形だけ描画してみる

  let rectangle = new Rectangle(); // Rectangleクラスからインスタンス生成

  // 大きさ
  rectangle.width = 400;  // 幅
  rectangle.height = 150; // 高さ

  // 塗りの色
  rectangle.fill = new Color("#262F6F");

  rectangle.strokeEnabled = false; // 線を無効にする
  selection.insertionParent.addChild(rectangle); // XDノードツリーにテキストオブジェクトを追加
  rectangle.moveInParentCoordinates(50,50); // テキストオブジェクトの表示位置を指定
}

module.exports = { // コマンドIDとファンクションの紐付け
  commands: {
    drawTableFromCSVCommand: drawTableFromCSVHandler
  }
};
```

### 結果
<img width="832" alt="スクリーンショット 2018-12-05 10.08.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/46556/d73d805d-a2ee-f20f-df4a-06af57b44bb3.png">

無事に出ました。
お、これ文字と合わせたらいけそうな気がしてきたぞ・・・！

# Step3. CSVをもとにテーブルをデザインさせる！！
いよいよ本題です。

## まずはこんなCSVファイルを用意

```test.csv
メニュー,価格
牛丼,380
ラーメン,680
チャーハン,1080
```
これをもとにテーブル描画させてみたいな・・・できるかな・・・お腹空いてきたな・・・
まずはCSVを読み込んで、それをいい感じに2次元配列で1つのセルをn×nで1つずつ描画してくれるとハッピー。
どうもファイルのI/OもできるみたいなのでこれでCSV読み込ませればいいのでは！

```javascript:main.js
const {Rectangle, Text, Color} = require("scenegraph");
const commands = require("commands");
const fs = require("uxp").storage.localFileSystem;

async function drawTableFromCSVHandler(selection) { // メインのファンクション
  console.log("start function"); // Developer Consoleに出力

  // CSVファイル読み込み
  const aFile = await fs.getFileForOpening({ types: ["csv"] });
  if (!aFile) return;
  const contents = await aFile.read();

  // CSVファイルから2次元配列に変換
  let array = [];
  let tmp = contents.split("\n");
  console.log(tmp);
  for( let i = 0; i < tmp.length; i++ ) {
    if( tmp[i] == '') break;
    array[i] = tmp[i].split(',');
  }

  // テーブル描画
  for( let i = 0; i < array.length; i++ ) {
    for ( let j = 0; j < array[i].length; j++ ) {
      let rectangle = new Rectangle(); // Rectangleクラスからインスタンス生成
      rectangle.width = 200;  // 幅
      rectangle.height = 60; // 高さ
      rectangle.fill = new Color("#262F6F"); // 四角の色を指定
      rectangle.strokeEnabled = false; // 線を無効にする
      selection.insertionParent.addChild(rectangle); // XDノードツリーにテキストオブジェクトを追加
      rectangle.moveInParentCoordinates(50+(rectangle.width*j),50+(rectangle.height*i)); // テキストオブジェクトの表示位置を指定
      // 指定しなかったら(0,0)に配置される

      let text = new Text(); // XDのTextクラスからインスタンスを生成
      text.text = array[i][j];
      text.styleRanges = [ // テキストのスタイルを設定
        {
          length: text.text.length,
          fill: new Color("#FFFFFF"),
          fontSize: 20
        }
      ];
      text.textAlign = Text.ALIGN_CENTER;  // テキストを中央揃えにする
      selection.insertionParent.addChild(text); // XDノードツリーにテキストオブジェクトを追加
      text.moveInParentCoordinates((rectangle.width/2)+(rectangle.width*j),(rectangle.height/2)+(rectangle.height*i)); // テキストオブジェクトの表示位置を指定

      selection.items = [ rectangle, text ];
      commands.alignVerticalCenter(); // オブジェクト中央揃え(垂直)
      commands.alignHorizontalCenter(); // オブジェクト中央揃え(水平)
      commands.group();　// グループ化
    }
  }


}

module.exports = { // コマンドIDとファンクションの紐付け
  commands: {
    drawTableFromCSVCommand: drawTableFromCSVHandler
  }
};

```

### 結果
![csv.gif](https://qiita-image-store.s3.amazonaws.com/0/46556/a11ffacb-cea6-8648-ef9e-158aefc0bf1a.gif)
動いたー！！やった〜〜〜〜〜！！
ついでに描画した1つひとつのセルを `commands.group();` を使ってグループ化もできました。
これでセルごとに動かせたり大きさ変えたりできるので便利そうです。

# おわりに
今回はセルのサイズも色も固定で出力してしまいましたが、
モーダルを表示させて、そこでサイズとかのパラメータを指定してそこから拾ってくるとかもできそうなので、まだまだプラグインいろいろ遊べそうです！
あとテーブルをデザインするのによくリピートグリッドという機能を使うのですが、リファレンスみててもそこよくわからなかったので調べてみようかなと思います！