Open6

Chart.js で時系列データを表示したときのメモ

Satoshi HasegawaSatoshi Hasegawa

Chart.js で時系列データを表示しようとして、2.x 系の情報をもとに作成すると、色々うまくいかなかったのでメモをする。

ググるとこんな感じのサンプルに出くわす。Chart.js は 2.4.0 を使用。

<!doctype html>
<html lang="ja">

<head>
    <meta charset="utf-8">
</head>

<body>

    <div>
        <canvas id="myChart"></canvas>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/ja.js"></script>

    <script>
        const myChart = new Chart((() => {
            return document.getElementById('myChart').getContext('2d');
        })(), {
            type: 'line',
            data: {
                labels: ['2021-08-02T09:30:22.710731+09:00',
                    '2021-08-02T11:10:22.710731+09:00',
                    '2021-08-02T13:00:22.710731+09:00',
                    '2021-08-02T15:00:22.710731+09:00',
                    '2021-08-02T18:30:22.710731+09:00',
                    '2021-08-02T19:50:22.710731+09:00'],

                datasets: [{
                    label: '気温',
                    data: [24.6, 26.8, 22.1, 28.5, 32.8, 29.0],
                    borderColor: 'rgba(255, 99, 132, 1)',
                    backgroundColor: 'rgba(255, 99, 132, 0.1)'
                }]
            },
            options: {
                legend: {
                    display: false
                },
                scales: {
                    xAxes: [{
                        type: 'time',
                        distribution: 'series'
                    }]
                }
            }
        });
    </script>
</body>

</html>

こんな感じで、期待通りにチャートが表示される。

Satoshi HasegawaSatoshi Hasegawa

Chart.js のバージョンを 3.5.0 にする。

<!doctype html>
<html lang="ja">

<head>
    <meta charset="utf-8">
</head>

<body>

    <div>
        <canvas id="myChart"></canvas>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.0/dist/chart.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/ja.js"></script>

    <script>
        const myChart = new Chart((() => {
            return document.getElementById('myChart').getContext('2d');
        })(), {
            type: 'line',
            data: {
                labels: ['2021-08-02T09:30:22.710731+09:00',
                    '2021-08-02T11:10:22.710731+09:00',
                    '2021-08-02T13:00:22.710731+09:00',
                    '2021-08-02T15:00:22.710731+09:00',
                    '2021-08-02T18:30:22.710731+09:00',
                    '2021-08-02T19:50:22.710731+09:00'],

                datasets: [{
                    label: '気温',
                    data: [24.6, 26.8, 22.1, 28.5, 32.8, 29.0],
                    borderColor: 'rgba(255, 99, 132, 1)',
                    backgroundColor: 'rgba(255, 99, 132, 0.1)'
                }]
            },
            options: {
                legend: {
                    display: false
                },
                scales: {
                    xAxes: [{
                        type: 'time',
                        distribution: 'series'
                    }]
                }
            }
        });
    </script>
</body>

</html>

X軸が時間として扱われず、ただのラベルとして扱われているようで、等間隔で点がプロットされいる。あと、凡例が消されていない。

Satoshi HasegawaSatoshi Hasegawa

option の設定方法が変わっているので、書き方を変える。

<!doctype html>
<html lang="ja">

<head>
    <meta charset="utf-8">
</head>

<body>

    <div>
        <canvas id="myChart"></canvas>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.0/dist/chart.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/ja.js"></script>

    <script>
        const myChart = new Chart((() => {
            return document.getElementById('myChart').getContext('2d');
        })(), {
            type: 'line',
            data: {
                labels: ['2021-08-02T09:30:22.710731+09:00',
                    '2021-08-02T11:10:22.710731+09:00',
                    '2021-08-02T13:00:22.710731+09:00',
                    '2021-08-02T15:00:22.710731+09:00',
                    '2021-08-02T18:30:22.710731+09:00',
                    '2021-08-02T19:50:22.710731+09:00'],

                datasets: [{
                    label: '気温',
                    data: [24.6, 26.8, 22.1, 28.5, 32.8, 29.0],
                    borderColor: 'rgba(255, 99, 132, 1)',
                    backgroundColor: 'rgba(255, 99, 132, 0.1)'
                }]
            },
            options: {
                legend: {
                    display: false
                },
                scales: {
                    x: {
                        scaleLabel: {
                            display: true,
                            labelString: '時間'
                        },
                        type: 'time',
                        time: {
                            parser: 'YYYY-MM-DDTHH:mm:ss.SSSSSSZ',
                            unit: 'hour',
                            stepSize: 1,
                            displayFormats: {
                                'hour': 'H時'
                            }
                        }
                    }
                }
            }
        });
    </script>
</body>

</html>

しかしながら、エラーが発生する。

chart.min.js:13 Uncaught Error: This method is not implemented: Check that a complete date adapter is provided.
    at ro (chart.min.js:13)
    at lo.formats (chart.min.js:13)
    at ca.init (chart.min.js:13)
    at chart.min.js:13
    at J (chart.min.js:13)
    at oo.buildOrUpdateScales (chart.min.js:13)
    at oo.update (chart.min.js:13)
    at new oo (chart.min.js:13)
    at chartjs_2.html:19

これは、 moment に直接依存していたコードが外れたことで、 adapter が必要になったためらしい。

https://ja.stackoverflow.com/questions/75271/chart-js-で-timescale-の使い方

Satoshi HasegawaSatoshi Hasegawa

chartjs-adapter-moment を追加。

<!doctype html>
<html lang="ja">

<head>
    <meta charset="utf-8">
</head>

<body>

    <div>
        <canvas id="myChart"></canvas>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.0/dist/chart.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/ja.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@1.0.0"></script>


    <script>
        const myChart = new Chart((() => {
            return document.getElementById('myChart').getContext('2d');
        })(), {
            type: 'line',
            data: {
                labels: ['2021-08-02T09:30:22.710731+09:00',
                    '2021-08-02T11:10:22.710731+09:00',
                    '2021-08-02T13:00:22.710731+09:00',
                    '2021-08-02T15:00:22.710731+09:00',
                    '2021-08-02T18:30:22.710731+09:00',
                    '2021-08-02T19:50:22.710731+09:00'],

                datasets: [{
                    label: '気温',
                    data: [24.6, 26.8, 22.1, 28.5, 32.8, 29.0],
                    borderColor: 'rgba(255, 99, 132, 1)',
                    backgroundColor: 'rgba(255, 99, 132, 0.1)'
                }]
            },
            options: {
                legend: {
                    display: false
                },
                scales: {
                    x: {
                        scaleLabel: {
                            display: true,
                            labelString: '時間'
                        },
                        type: 'time',
                        time: {
                            parser: 'YYYY-MM-DDTHH:mm:ss.SSSSSSZ',
                            unit: 'hour',
                            stepSize: 1,
                            displayFormats: {
                                'hour': 'H時'
                            }
                        }
                    }
                }
            }
        });
    </script>
</body>

</html>

期待通りのチャートが表示されたが、まだ、凡例が残っている。

Satoshi HasegawaSatoshi Hasegawa

これで凡例が消えた。

<!doctype html>
<html lang="ja">

<head>
    <meta charset="utf-8">
</head>

<body>

    <div>
        <canvas id="myChart"></canvas>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.0/dist/chart.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/ja.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@1.0.0"></script>


    <script>
        const myChart = new Chart((() => {
            return document.getElementById('myChart').getContext('2d');
        })(), {
            type: 'line',
            data: {
                labels: ['2021-08-02T09:30:22.710731+09:00',
                    '2021-08-02T11:10:22.710731+09:00',
                    '2021-08-02T13:00:22.710731+09:00',
                    '2021-08-02T15:00:22.710731+09:00',
                    '2021-08-02T18:30:22.710731+09:00',
                    '2021-08-02T19:50:22.710731+09:00'],

                datasets: [{
                    label: '気温',
                    data: [24.6, 26.8, 22.1, 28.5, 32.8, 29.0],
                    borderColor: 'rgba(255, 99, 132, 1)',
                    backgroundColor: 'rgba(255, 99, 132, 0.1)'
                }]
            },
            options: {
                plugins: {
                    legend: {
                        display: false
                    }
                },
                scales: {
                    x: {
                        scaleLabel: {
                            display: true,
                            labelString: '時間'
                        },
                        type: 'time',
                        time: {
                            parser: 'YYYY-MM-DDTHH:mm:ss.SSSSSSZ',
                            unit: 'hour',
                            stepSize: 1,
                            displayFormats: {
                                'hour': 'H時'
                            }
                        }
                    }
                }
            }
        });
    </script>
</body>

</html>