[CreateJS] アニメーション付きグラフを作成する 

## はじめに

CreateJSを使った折れ線グラフサンプルです。
実用的で表現の自由度が高いグラフを書きたいと思いCreateJSで作成しました。
Chart.jsのようにデータセットを読み込んでグラフを描画します。
自作でグラフを作成したい方は参考にどうぞ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/324018/02577f22-7d01-2261-b6f3-c89516580ca9.png)
[[ソースコード]](https://codepen.io/a3impala/pen/jXNVba)

CreateJSを触ったことがない方はまずは公式から
https://www.createjs.com/

## 使用したグラフデータ

Chart.jsのサンプルデータを元にした、
このような形式のデータを読み込んでグラフ描画させています。

```javascript
// データ設定
var config = {
    data: {
        labels: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'],
        datasets: [{
            label: 'dataset1',
            backgroundColor: "DarkRed",
            borderColor: "chocolate",
            data: [
                10, 15, 20, 25, 30, 45, 60
            ],
        }, {
            label: 'dataset2',
            fill: false,
            backgroundColor: "olive",
            borderColor: "olivedrab",
            data: [
                10, 40, 80, 160, 160, 240, 280
            ],
        }, {
            label: 'dataset3',
            fill: false,
            backgroundColor: "DarkBlue",
            borderColor: "steelblue",
            data: [
                50, 100, 250, 300, 320, 360, 400
            ],
        }]
    },
};
```

## 構築ポイント

ここからはグラフを作成する際のポイントをいくつか説明します。

### 縦軸、横軸の描画

```javascript
    // パディングサイズ 10%
    var padding = 0.1;

    // 軸の基準
    var baseX = stage.canvas.width * padding;
    var baseY = stage.canvas.height * (1.0 - padding);

    // 横軸の描画
    var horizontalLine = new createjs.Shape();
    horizontalLine.x = baseX;
    horizontalLine.y = baseY;
    horizontalLine.graphics
        .beginStroke("gray")
        .moveTo(0, 0)
        .lineTo(stage.canvas.width * (1 - (padding * 2)), 0)
        .endStroke();
    stage.addChild(horizontalLine);
```

グラフのX軸、Y軸の原点を決めます。
領域の左下が原点になるようにpaddingを考慮して計算します。
軸は、横軸であれば左から右に向かってlineToで線を引きます。

```javascript
.lineTo(stage.canvas.width * (1 - (padding * 2)), 0)
```

canvasの幅から左右のpadding量を引いた値が線を引く長さになります。


### データ点

```javascript
    // データ点
    for (var key in config.data.datasets) {
        for (var i = 0; i < horizontalLength; i++) {
            // （省略）
            // 点の描画
            var dot = new createjs.Shape();
            dot.graphics.beginFill(config.data.datasets[key].backgroundColor);
            dot.graphics.drawCircle(0, 0, 5);
            dot.x = baseX + (horizontalStep * i);
            dot.y = baseY - (config.data.datasets[key].data[i] * verticalStep / 100);
            dot.dataVal = config.data.datasets[key].data[i];
            stage.addChild(dot);
            // （省略）
        }
    }
```

データをループさせながら点を描画しています。
X軸は、canvasの幅をデータ数で割った値だけずらします。
Y軸は、canvasの高さを縦軸のラベル数で割った値だけずらします。

### データ点を線で繋ぐ

```javascript
            // 線の描画
            var stroke = new createjs.Shape();
            stroke.graphics
                .beginStroke(config.data.datasets[key].borderColor)
                .moveTo(0, 0)
                .lineTo(dot.x - prevX, dot.y - prevY)
                .endStroke();
            stroke.x = prevX;
            stroke.y = prevY;
            stage.addChildAt(stroke, 0);
```

データ点同士を線でつなぐには、
ひとつ前のループで描画したデータ点の位置を保持しておき、
その差を計算するとできます。

### Tweenでアニメーション

ここは味付け次第でいろいろアニメーションさせられると思います。
サンプルでは描画開始タイミングをずらして
流れるように線を引く動きを行っています。

## まとめ

サイト内にグラフを載せる時の選択肢としては、
既成のライブラリを使うのも良いですが自由に書こうとするとどうしても制約が出てきてしまいます。
その際にCreateJSを使うのも一つの選択肢としてアリかと思います。