初心者のためのExtJS入門

ExtJSを使うので、ついでにまとめていきます

チャート[classic] (3)

スタック形式の棒グラフ

Ext.chart.series.Barのstackedコンフィグをtrueにすると、積み上げた形状の棒グラフを表現できます。

これを使うとデータを比較しやすくなります。

モデル、ストア

車の販売台数のデータでモデル、ストアを作成しました。(データ元: http://www.jada.or.jp/contents/data/hanbai/maker.html)

/**
 * 車販売台数モデルクラス。
 *
 * @class Sample.model.CarSales
 * @extend Ext.data.Model
 */
Ext.define('Sample.model.CarSales', {
    extend: 'Ext.data.Model',

    fields: [
        {
            name: 'ym',
            type: 'string'
        },
        {
            name: 'data1',
            type: 'int'
        },
        {
            name: 'data2',
            type: 'int'
        },
        {
            name: 'data3',
            type: 'int'
        },
        {
            name: 'data4',
            type: 'int'
        },
        {
            name: 'data5',
            type: 'int'
        },
        {
            name: 'data6',
            type: 'int'
        },
        {
            name: 'data7',
            type: 'int'
        },
        {
            name: 'data8',
            type: 'int'
        },
        {
            name: 'data9',
            type: 'int'
        },
        {
            name: 'data10',
            type: 'int'
        },
        {
            name: 'data11',
            type: 'int'
        },
        {
            name: 'data12',
            type: 'int'
        },
        {
            name: 'data13',
            type: 'int'
        }
    ]
});

/**
 * 車販売台数ストアクラス。
 *
 * @class Sample.store.CarSales
 * @extend Ext.data.Store
 */
Ext.define('Sample.store.CarSales', {
    extend: 'Ext.data.Store',

    model: [
        'Sample.model.CarSales'
    ],

    model: 'Sample.model.CarSales',

    proxy: 'memory',

    data: [
        { ym: '2016/04', data1: 721, data2: 7885, data3: 3681, data4: 23993, data5: 4184, data6: 9441, data7: 1879, data8: 2620, data9: 19177, data8: 2620, data9: 19177, data10: 7871, data11: 111693, data12: 670, data13: 18898 },
        { ym: '2016/05', data1: 430, data2: 8243, data3: 4146, data4: 27949, data5: 4967, data6: 10484, data7: 1510, data8: 3082, data9: 24690, data8: 3082, data9: 24690, data10: 7353, data11: 105528, data12: 647, data13: 24724 },
        { ym: '2016/06', data1: 491, data2: 8870, data3: 5754, data4: 33944, data5: 6549, data6: 10478, data7: 1876, data8: 4897, data9: 30561, data8: 4897, data9: 30561, data10: 9239, data11: 138878, data12: 1034, data13: 35199 },
        { ym: '2016/07', data1: 676, data2: 8906, data3: 4622, data4: 31698, data5: 6716, data6: 13431, data7: 2279, data8: 3313, data9: 27747, data8: 3313, data9: 27747, data10: 8647, data11: 146536, data12: 844, data13: 26338 },
        { ym: '2016/08', data1: 854, data2: 8367, data3: 4623, data4: 22381, data5: 6481, data6: 12195, data7: 1295, data8: 3316, data9: 22466, data8: 3316, data9: 22466, data10: 6438, data11: 110527, data12: 799, data13: 23531 },
        { ym: '2016/09', data1: 657, data2: 11145, data3: 7168, data4: 38064, data5: 10833, data6: 18112, data7: 1505, data8: 4936, data9: 31573, data8: 4936, data9: 31573, data10: 8781, data11: 144012, data12: 1071, data13: 39191 },
        { ym: '2016/10', data1: 538, data2: 9249, data3: 4527, data4: 32629, data5: 5382, data6: 10227, data7: 2279, data8: 2913, data9: 25695, data8: 2913, data9: 25695, data10: 6457, data11: 118712, data12: 791, data13: 23470 },
        { ym: '2016/11', data1: 994, data2: 11832, data3: 5500, data4: 31681, data5: 6902, data6: 13537, data7: 2242, data8: 3426, data9: 34997, data8: 3426, data9: 34997, data10: 6892, data11: 126837, data12: 917, data13: 27285 },
        { ym: '2016/12', data1: 1106, data2: 10269, data3: 5688, data4: 28676, data5: 7501, data6: 8564, data7: 1954, data8: 4625, data9: 31751, data8: 4625, data9: 31751, data10: 5919, data11: 124348, data12: 1045, data13: 33492 },
        { ym: '2017/01', data1: 1123, data2: 12722, data3: 4380, data4: 30338, data5: 5103, data6: 13946, data7: 2301, data8: 2352, data9: 40324, data8: 2352, data9: 40324, data10: 8828, data11: 114916, data12: 577, data13: 21175 },
        { ym: '2017/02', data1: 975, data2: 13218, data3: 5284, data4: 34267, data5: 6824, data6: 16027, data7: 2596, data8: 3278, data9: 44952, data8: 3278, data9: 44952, data10: 9183, data11: 147714, data12: 699, data13: 27018 },
        { ym: '2017/03', data1: 1819, data2: 18496, data3: 11443, data4: 49847, data5: 13160, data6: 28751, data7: 5494, data8: 5878, data9: 64395, data8: 5878, data9: 64395, data10: 12834, data11: 200587, data12: 1366, data13: 46584 }
    ]

});

チャート

あとはExt.chart.series.Barを使って棒グラフを表示してみます。

積み上げる順番にyFieldに複数のフィールド名を指定します。

あとはstacked: trueを指定します。

/**
 * チャートクラス。
 *
 * @class Sample.views.main.chart.Panel
 * @extend Ext.chart.CartesianChart
 */
Ext.define('Sample.views.main.chart.Panel', {
    extend: 'Ext.chart.CartesianChart',
    xtype: 'chart_panel',

    requires: [
        'Ext.chart.axis.Numeric',
        'Ext.chart.axis.Category',
        'Ext.chart.series.Bar'
    ],

    store: 'CarSales',

    legend: {
        type: 'sprite',
        docked: 'bottom'
    },

    axes: [
        {
            type: 'numeric',
            position: 'left',
            minimum: 0,
            title: {
                text: '販売台数'
            }
        },
        {
            type: 'category',
            position: 'bottom',
            label: {
                rotate: {
                    degrees: -90
                }
            },
            title: {
                text: '年月'
            }
        }
    ],

    series: [
        {
            type: 'bar',
            xField: 'ym',
            yField: ['data1','data2','data3','data4','data5','data6','data7','data8','data9','data10','data11','data12','data13'],
            title: ['ダイハツ','富士重工','日野','ホンダ','いすゞ','マツダ','三菱','三菱ふそう','日産','スズキ','トヨタ','UDトラックス','輸入車'],
            stacked: true,
            style: {
                minGapWidth: 20
            }
        }
    ]
});

f:id:sham-memo:20170427203121p:plain

legendコンフィグで、Excelの凡例みたいなのを表示できます。複数のデータがあると、どの色が何を表しているのか分からないので、この形式だと必須ですね。

スタック形式の割合で表示

さらに自動的に各データの全体での割合のチャートにすることができます。

fullStack: trueを指定するだけです。

/**
 * チャートクラス。
 *
 * @class Sample.views.main.chart.Panel
 * @extend Ext.chart.CartesianChart
 */
Ext.define('Sample.views.main.chart.Panel', {
    extend: 'Ext.chart.CartesianChart',
    xtype: 'chart_panel',

    requires: [
        'Ext.chart.axis.Numeric',
        'Ext.chart.axis.Category',
        'Ext.chart.series.Bar'
    ],

    store: 'CarSales',

    legend: {
        type: 'sprite',
        docked: 'bottom'
    },

    axes: [
        {
            type: 'numeric',
            position: 'left',
            minimum: 0,
            title: {
                text: '販売台数の割合(%)'
            }
        },
        {
            type: 'category',
            position: 'bottom',
            label: {
                rotate: {
                    degrees: -90
                }
            },
            title: {
                text: '年月'
            }
        }
    ],

    series: [
        {
            type: 'bar',
            xField: 'ym',
            yField: ['data1','data2','data3','data4','data5','data6','data7','data8','data9','data10','data11','data12','data13'],
            title: ['ダイハツ','富士重工','日野','ホンダ','いすゞ','マツダ','三菱','三菱ふそう','日産','スズキ','トヨタ','UDトラックス','輸入車'],
            stacked: true,
            fullStack: true,
            style: {
                minGapWidth: 20
            }
        }
    ]
});

f:id:sham-memo:20170427203336p:plain

各年月で、全体を100%としたときの割合を表示しています。

データを横に並べる

データを横並びにして比べるなら、stack: falseを指定します(stackコンフィグの初期値はtrueなんですね。知らなかった)。

/**
 * チャートクラス。
 *
 * @class Sample.views.main.chart.Panel
 * @extend Ext.chart.CartesianChart
 */
Ext.define('Sample.views.main.chart.Panel', {
    extend: 'Ext.chart.CartesianChart',
    xtype: 'chart_panel',

    requires: [
        'Ext.chart.axis.Numeric',
        'Ext.chart.axis.Category',
        'Ext.chart.series.Bar'
    ],

    store: 'CarSales',

    legend: {
        type: 'sprite',
        docked: 'bottom'
    },

    axes: [
        {
            type: 'numeric',
            position: 'left',
            minimum: 0,
            title: {
                text: '販売台数'
            },
            grid: {
                odd: {
                    fillStyle: 'rgba(255, 255, 255, 0.06)'
                },
                even: {
                    fillStyle: 'rgba(0, 0, 0, 0.03)'
                }
            }
        },
        {
            type: 'category',
            position: 'bottom',
            label: {
                rotate: {
                    degrees: -90
                }
            },
            title: {
                text: '年月'
            }
        }
    ],

    series: [
        {
            type: 'bar',
            xField: 'ym',
            yField: ['data11', 'data4', 'data1'],
            stacked: false,
            style: {
                inGroupGapWidth: -7
            },
            title: ['トヨタ', 'ホンダ', 'ダイハツ']
        }
    ]
});

f:id:sham-memo:20170429151744p:plain

立体的な棒グラフ

軸、データ系列のクラス名が「~3D」となっているものを使用します。その他の設定は、これまでとほぼ同じです。

/**
 * チャートクラス。
 *
 * @class Sample.views.main.chart.Panel
 * @extend Ext.chart.CartesianChart
 */
Ext.define('Sample.views.main.chart.Panel', {
    extend: 'Ext.chart.CartesianChart',
    xtype: 'chart_panel',

    requires: [
        'Ext.chart.axis.Numeric3D',
        'Ext.chart.axis.Category3D',
        'Ext.chart.series.Bar3D',
        'Ext.chart.grid.HorizontalGrid3D'
    ],

    store: 'CarSales',

    legend: {
        type: 'sprite',
        docked: 'bottom'
    },

    axes: [
        {
            type: 'numeric3d',
            position: 'left',
            minimum: 0,
            title: {
                text: '販売台数'
            },
            grid: {
                odd: {
                    fillStyle: 'rgba(255, 255, 255, 0.06)'
                },
                even: {
                    fillStyle: 'rgba(0, 0, 0, 0.03)'
                }
            }
        },
        {
            type: 'category3d',
            position: 'bottom',
            label: {
                rotate: {
                    degrees: -90
                }
            },
            title: {
                text: '年月'
            }
        }
    ],

    series: [
        {
            type: 'bar3d',
            xField: 'ym',
            yField: ['data11', 'data4', 'data1'],
            stacked: false,
            style: {
                inGroupGapWidth: -7
            },
            title: ['トヨタ', 'ホンダ', 'ダイハツ']
        }
    ]
});

f:id:sham-memo:20170429152018p:plain