CRUD Lab. Tech Blog

ギークス株式会社の沖縄開発拠点CRUDLab. (クラッドラボ)のIT技術(テック)ブログ。kintoneやAngularJSによる開発を行っています。

【kintone】Highchartsを利用して他アプリのデータをグラフ化しよう

0. 目次

f:id:crud_lab:20160317162650p:plain

1. 概要

ギークス株式会社CRUD Lab.のKUNISADAです!

Highchartsというjavascriptのグラフライブラリを利用してkintoneをカスタマイズし、 他アプリデータをグラフ化してみます。

javascriptのグラフライブラリはchart.jsなど多数ありますが、 Highchartsには画像のexporting機能(画像としてダウンロードする機能)が備わっていたり、 二軸のグラフの作成がオプションから簡単に設定できたりと非常に便利なライブラリです。

※商用の場合は有料です。

もちろんkintone自体のグラフ機能もとても使いやすいので、 より高度なグラフ描画をしたい時だけHighchartsでカスタマイズするのがおすすめです。

今回は、気象庁が公表している

「沖縄県那覇市の年月別最高気温・最低気温・降水量」

のデータをグラフ化してみようと思います。

2. イメージ図

データアプリとグラフ描画アプリを作成し、グラフ描画アプリからデータをグラフ化します。

f:id:crud_lab:20160317155920g:plain

3. 準備

3-1 データアプリの作成

今回はcsvでデータを整理した後、csvからアプリ作成を行いました。 アプリ名はcsvのファイル名から生成されており、

naha_climate_2010.1-2016.3

となっています。 f:id:crud_lab:20160317153526p:plain

アプリ作成後、フィールド名を変更していきます。

アプリIDは「11」です。

フィールド名 フィールドコード 初期値 その他
year -- --
month -- --
降水量・合計(mm) sum_precipitation -- --
最高気温(℃) highest_temperature -- --
最低気温(℃) lowest_temperature -- --

3-2 グラフ描画アプリの作成

次にグラフを描画するためだけのアプリを作成します。

アプリ名は「sample_graph」としました。

フィールド名 フィールドコード 初期値 その他
年選択 selected_year -- --
[スペース] graphArea -- --

3-3 必要ファイルの読み込み

グラフ描画アプリ「sample_graph」に必要ファイルを読み込みます。

Highchartsに必要な

と最後にjavascriptカスタマイズする

  • sample.js

を読み込みます。

f:id:crud_lab:20160317155029p:plain

4. 実装

sample.js

(function() {
    "use strict";
    kintone.events.on(["app.record.edit.show", "app.record.create.show", "app.record.edit.change.selected_year", "app.record.create.change.selected_year"], function(event){

        var record = event.record,
            selectedYear = record['selected_year']['value'],
            //データ元のアプリIDとクエリの設定
            dataAppId = 11,
            url = kintone.api.url('/k/v1/records'),
            params = {
                'app'   : dataAppId,
                'query' : 'year = ' + selectedYear + 'order by month asc'
            },
            //取得データ用の配列を初期化。グラフ用の<div>をスペースの中に作成
            data = [],
            elGraph = kintone.app.record.getSpaceElement('graphArea'),
            elDiv = document.createElement('div');
            elDiv.setAttribute("id", "graph");
            elDiv.style.cssText ="width: 600px; height: 400px;";
            elGraph.appendChild(elDiv);

        kintone.api(url, 'GET', params,
            function(resp){
                var monthData = [],
                    highestPrecipitationData = [],
                    highestTemperatureData = [],
                    lowestTemperatureData = [];
                data = resp.records;

                //取得したデータからグラフ用の配列を作成
                for (var recordId in data) {
                    console.log(data[recordId]);
                    monthData.push(data[recordId]['month'].value);
                    highestPrecipitationData.push(parseInt(data[recordId]['sum_precipitation'].value));
                    highestTemperatureData.push(parseInt(data[recordId]['highest_temperature'].value));
                    lowestTemperatureData.push(parseInt(data[recordId]['lowest_temperature'].value));
                }

                //データからグラフを生成
                $(function () {
                    $('#graph').highcharts({
                        exporting: {
                            chartOptions: {
                                plotOptions: {
                                    series: {
                                        dataLabels: {
                                            enabled: true
                                        }
                                    }
                                }
                            },
                            scale: 3,
                            fallbackToExportServer: false
                        },
                        chart: {
                            zoomType: 'xy'
                        },
                        title: {
                            text: '那覇月別降水量・気温グラフ'
                        },
                        xAxis: [{
                            categories: monthData,
                            crosshair: true
                        }],
                        yAxis: [{ // Primary yAxis
                            labels: {
                                format: '{value}°C',
                                style: {
                                    color: Highcharts.getOptions().colors[1]
                                }
                            },
                            title: {
                                text: '気温',
                                style: {
                                    color: Highcharts.getOptions().colors[1]
                                }
                            }
                        }, { // Secondary yAxis
                            title: {
                                text: '降水量',
                                style: {
                                    color: Highcharts.getOptions().colors[0]
                                }
                            },
                            labels: {
                                format: '{value} mm',
                                style: {
                                    color: Highcharts.getOptions().colors[0]
                                }
                            },
                            opposite: true
                        }],
                        tooltip: {
                            shared: true
                        },
                        legend: {
                            layout: 'vertical',
                            align: 'left',
                            x: 60,
                            verticalAlign: 'top',
                            y: 30,
                            floating: true,
                            backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
                        },
                        series: [{
                            name: '降水量',
                            type: 'column',
                            yAxis: 1,
                            data: highestPrecipitationData,
                            tooltip: {
                                valueSuffix: ' mm'
                            }
                        },
                        {
                            name: '最高気温',
                            type: 'spline',
                            data: highestTemperatureData,
                            tooltip: {
                                valueSuffix: '°C'
                            }
                        },
                        {
                            name: '最低気温',
                            type: 'spline',
                            data: lowestTemperatureData,
                            tooltip: {
                                valueSuffix: '°C'
                            }
                        }]
                    });
                });
            }, function(resp) {
                alert('エラーが発生しました。管理者に問い合わせてください');
        });
    });

})();

5. まとめ

今回の実装ではサンプルということで、 kintone.events.on("app.record.create.change.selected_year")を利用し、毎度APIでの情報取得を行っています。

他アプリの情報を取得する際のAPIリクエスト上限が10000となっているため、

"app.record.create.show"と"app.record.edit.show"で情報を一括で取得し、

"app.record.create.change.selected_year"でselected_yearが変更された時グラフデータを変更する

という仕様に変えるとAPIリクエストの節約になります。

kintone上で、どうしてもグラフを画像としてダウンロードしたい、より高度なグラフをkintoneのデータを利用して作成したいというときの助けになれば幸いです。

6. 参考

www.highcharts.com

www.data.jma.go.jp