【kintone】グラフ設定APIで分類する項目を変更する

前回はグラフ設定APIのPUTでグラフの種類変更やグラフの新規追加を試してみました。
今回は「分類する項目」の大、中、小項目を変更してみたいと思います。
（処理成功のアラートや、エラー処理等は適宜書いてください～。）

# アプリの準備

出来上がりのフォームはこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/4fce2637-3bd4-678b-487c-d10bebe316db.png)

## フォーム

文字列(1行)とスペースを図のように設置します。
ボタンやドロップダウンフィールドはスペースに設置していきます。

フィールドコードなどは表のとおり。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/7971d7de-063d-5dda-85f9-b1a7714ad2f0.png)

| フィールド種類 | フィールド名（コード） | 備考 |
|:-:|:-:|:-:|
| 文字列(1行)  | アプリID  |   |
| スペース  |  spGet | グラフ設定取得ボタン用  |
| スペース  | spDropDown  | グラフ選択ドロップダウン用  |
| スペース  | spGraphSettings  | 分類する項目（大、中、小）用  |
| スペース  | spPut  | グラフ設定更新ボタン用  |


## kintone UI Component v1

ドロップダウンやボタンを使いやすく＆ちょっと可愛くしたい！
というわけで**kintone UI Component v1**を使用します。

↓こちらを熟読して、CDNまたはダウンロードしたものを**JavaScript /CSS でカスタマイズ**に設定しておきましょう。

https://kintone-ui-component.netlify.app/docs/getting-started/quick-start.html

# JavaScript

というわけで、大きく分けて、下記4つの機能をプログラミングしていきます。

1. ボタンやドロップダウンを設置する
2. グラフの設定を取得する
3. グラフを選択したら、選択したグラフの設定を取得
3. グラフの設定を更新する


新規レコード追加や編集画面でうごくようにします。

```js
kintone.events.on(
  ["app.record.create.show", "app.record.edit.show"],
  (event) => {
    //コードを書いていくところ 
  });
```


## ボタンやドロップダウンを設置する

スペースフィールドにボタンやドロップダウンを設置していきます。

### ボタンの設置
```js
const spGet = kintone.app.record.getSpaceElement("spGet");
const spPut = kintone.app.record.getSpaceElement("spPut");
const btnGet = new Kuc.Button({
  text: "グラフの設定取得",
  type: "submit",
});

const btnPut = new Kuc.Button({
  text: "グラフの設定更新",
  type: "submit",
});
spGet.appendChild(btnGet);
spPut.appendChild(btnPut);
```

### グラフ選択ドロップダウン

itemsは後で入れるので空にしておきます。

```js
const spDropDown = kintone.app.record.getSpaceElement("spDropDown");
const drSelGraph = new Kuc.Dropdown({
  label: "グラフ",
  requiredIcon: true,
  items: [],
  visible: true,
  disabled: false,
});
spDropDown.appendChild(drSelGraph);
```

### 分類する項目（大、中、小）ドロップダウン
```js
//グラフ設定表示
const spGraphSettings = kintone.app.record.getSpaceElement(
  "spGraphSettings"
);
const drGroups = [
  new Kuc.Dropdown({
    label: "分類する項目（大）",
    requiredIcon: true,
    items: [],
    visible: true,
    disabled: false,
  }),
  new Kuc.Dropdown({
    label: "分類する項目（中）",
    requiredIcon: true,
    items: [],
    visible: true,
    disabled: false,
  }),
  new Kuc.Dropdown({
    label: "分類する項目（小）",
    requiredIcon: true,
    items: [],
    visible: true,
    disabled: false,
  }),
];

drGroups.forEach((d) => {
  spGraphSettings.appendChild(d);
});

```

## グラフの設定取得ボタン
アプリIDを入力して、グラフの設定を取得するボタンをクリックしたら、

1. グラフ選択用のドロップダウンの候補にグラフ情報をセット
2. 分類する項目（大、中、小）のドロップダウン選択候補にアプリのフィールドをセット

という動きをさせます。

```js
// グラフ情報
let graphSetting;

//グラフ設定取得ボタンクリック
btnGet.addEventListener("click", async () => {
  const obj = kintone.app.record.get();

  //グラフ選択用のドロップダウンにグラフ情報をセット
  const body = {
    app: obj.record.アプリID.value,
  };

  //APIでグラフの設定をゲット
  graphSetting = await kintone.api(
    kintone.api.url("/k/v1/app/reports", true),
    "GET",
    body
  );

  //グラフ一覧をグラフ選択用ドロップダウンにセット
  const gItems = [];
  Object.keys(graphSetting.reports).forEach((g) => {
    gItems.push({ label: g, value: g });
  });
  drSelGraph.items = gItems;

  // 分類する項目ドロップダウンにセットする、アプリのフィールドを取得
  const fields = await kintone.api(
    kintone.api.url("/k/v1/app/form/fields", true),
    "GET",
    body
  );
  const groupsItems = [{ label: "", value: "" }]; //空の設定を入れておく
  Object.keys(fields.properties).forEach((g) => {
    // カテゴリーやステータスは弾きましょう
    if (
      fields.properties[g].type === "CATEGORY" ||
      fields.properties[g].type === "STATUS"
    ) {
      return;
    }

    //サブテーブル内のフィールドも取得
    if (fields.properties[g].type === "SUBTABLE") {
      Object.keys(fields.properties[g].fields).forEach((tg) => {
        groupsItems.push({
          label: fields.properties[g].fields[tg].label,
          value: fields.properties[g].fields[tg].code,
        });
      });
    } else {
      groupsItems.push({
        label: fields.properties[g].label,
        value: fields.properties[g].code,
      });
    }
  });
  // 分類する項目大中小3つのドロップダウンにフィールドをセットする
  drGroups.forEach((d) => {
    d.items = groupsItems;
  });

});
```

## グラフ選択したとき
グラフ選択をした時は、分類する項目大中小のドロップダウンに設定のフィールドをセットします。
（日付、時刻等の「分類する項目の時間単位」は今回無視しています🙏）

```js
drSelGraph.addEventListener("change", (event) => {
  // 一旦全ドロップダウンをクリア
  drGroups.forEach((d) => {
    d.value = "";
  });
  // グラフ設定で呼び出した分類する項目のフィールドをセット
  graphSetting.reports[drSelGraph.value].groups.forEach((g, idx) => {
    drGroups[idx].value = g.code;
  });
});
```

## グラフ設定更新ボタンクリック

```js
//グラフ設定更新ボタンクリック
btnPut.addEventListener("click", async () => {
  const obj = kintone.app.record.get();
  const bodyGet = {
    app: obj.record.アプリID.value,
  };
  //グラフAPIでグラフの設定を呼び出す
  const graphSetting = await kintone.api(
    kintone.api.url("/k/v1/app/reports", true),
    "GET",
    bodyGet
  );

  // 分類する項目をupするグラフ設定にセット
  const groupsPut = [];
  drGroups.forEach((g, idx) => {
    if (!!g.value) {
      groupsPut.push({
        code: g.value,
      });
    }
  });
  graphSetting.reports[drSelGraph.value].groups = groupsPut;
  const bodyPut = {
    app: obj.record.アプリID.value,
    reports: graphSetting.reports,
  };

  // 後は前回と同じ
  const resp = await kintone.api(
    kintone.api.url("/k/v1/preview/app/reports", true),
    "PUT",
    bodyPut
  );
  await kintone.api(
    kintone.api.url("/k/v1/preview/app/deploy", true),
    "POST",
    {
      apps: [
        {
          app: obj.record.アプリID.value,
        },
      ],
    }
  );

});
```

全体的なコードは以下です。

https://gist.github.com/juridon/dca234fd121e37c80ffbac2ccebe08a6

# 動作確認とまとめ

分類する項目の中項目と小項目は必須じゃないほうがいいですね💦

![graphgetput.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/58d4d8c3-2008-5196-88f3-4ede92896595.gif)

分類する項目が日付や日時フィールドの場合の時間単位が選択できない（更新もできない）などあります。
集計方法やソートについても似たような方法で実装することはできると思いますので、ぜひチャレンジしてみてくださいっ！