Анализатор расходов



Структура проекта:

Таблица:
Ext.define('EA.view.main.List', {
    extend: 'Ext.grid.Panel',
    xtype: 'mainlist',
    maxHeight: 400,
    requires: ['EA.store.Expense'],
    title: 'Year to date expense by category',
    store: {
        type: 'expense'
    },
    columns: {
        defaults: {
            flex: 1
        },
        items: [{
            text: 'Category',
            dataIndex: 'cat'
        }, {
            formatter: "date('F')",
            text: 'Month',
            dataIndex: 'date'
        }, {
            text: 'Spent',
            dataIndex: 'spent'
        }]
    }
});

Хранилище:

Ext.define('EA.store.Expense', {
    extend: 'Ext.data.Store',
    alias: 'store.expense',
    storeId: 'expense',
    fields: [{
        name: 'date',
        type: 'date'
    }, 'cat', 'spent'],
    data: {
        items: [{
            "date": "1/1/2015",
            "cat": "Restaurant",
            "spent": 100
        }, {
            "date": "1/1/2015",
            "cat": "Travel",
            "spent": 22
        }, {
            "date": "1/1/2015",
            "cat": "Insurance",
            "spent": 343
        },
        // Truncated code]
    },
    proxy: {
        type: 'memory',
        reader: {
            type: 'json',
            rootProperty: 'items'
        }
    }
});

3D bar chart:

Ext.define('EA.view.main.Bar', {
    extend: 'Ext.chart.CartesianChart',

    requires: ['Ext.chart.axis.Category', 'Ext.chart.series.Bar3D', 'Ext.chart.axis.Numeric', 'Ext.chart.interactions.ItemHighlight'],

    xtype: 'mainbar',
    height: 500,
    padding: {
        top: 50,
        bottom: 20,
        left: 100,
        right: 100
    },
    legend: {
        docked: 'bottom'
    },
    insetPadding: {
        top: 100,
        bottom: 20,
        left: 20,
        right: 40
    },
    store: {
        type: 'expensebyMonthStore'
    },
    axes: [{
        type: 'numeric',
        position: 'left',
        grid: true,
        minimum: 0,
        title: {
            text: 'Spendings in $',
            fontSize: 16
        },
    }, {
        type: 'category',
        position: 'bottom',
        title: {
            text: 'Month',
            fontSize: 16
        },
        label: {
            font: 'bold Arial',
            rotate: {
                degrees: 300
            }
        },
        renderer: function(date) {
            return ["Jan", "Feb", "Mar", "Apr", "May"][date.getMonth()];
        }
    }],
    series: [{
        type: 'bar3d',
        xField: 'date',
        stacked: false,
        title: ['Total'],
        yField: ['total']
    }],
    sprites: [{
        type: 'text',
        text: 'Expense by Month',
        font: '20px Helvetica',
        width: 120,
        height: 35,
        x: 60,
        y: 40
    }]
});

Хранилище для 3D bar диаграммы:

Ext.define('MyApp.model.ExpensebyMonth', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'date',
        type: 'date'
    }, 'total']
});

Ext.define('MyApp.store.ExpensebyMonth', {
    extend: 'Ext.data.Store',

    alias: 'store.expensebyMonthStore',
    model: 'MyApp.model.ExpensebyMonth',

    data: (function() {
        var data = [];

        var expense = Ext.createByAlias('store.expense');
        expense.group('date');
        var groups = expense.getGroups();

        groups.each(function(group) {
            data.push({
                date: group.config.groupKey,
                total: group.sum('spent')
            });
        });
        return data;
    })()
});

Диаграмма-пирог:
Ext.define('EA.view.main.Pie', {
    extend: 'Ext.chart.PolarChart',
    requires: ['Ext.chart.series.Pie3D'],
    xtype: 'mainpie',
    height: 800,
    legend: {
        docked: 'bottom'
    },
    insetPadding: {
        top: 100,
        bottom: 20,
        left: 80,
        right: 80
    },
    listeners: {
        beforerender: function() {
            var dateFiter = new Ext.util.Filter({
                filterFn: function(item) {
                    return item.data.date.getMonth() == 0;
                }
            });
            Ext.getStore('expense').addFilter(dateFiter);
        }
    },
    store: {
        type: 'expense'
    },
    series: [{
        type: 'pie3d',
        donut: 50,
        thickness: 70,
        distortion: 0.5,
        angleField: 'spent',
        label: {
            field: 'cat',
        }
    }]
});

Главный связывающий вид:

Ext.define('EA.view.main.Main', {
    extend: 'Ext.tab.Panel',
    xtype: 'app-main',

    requires: ['Ext.plugin.Viewport', 'Ext.window.MessageBox', 'EA.view.main.MainController', 'EA.view.main.List', 'EA.view.main.Bar', 'EA.view.main.Pie'],

    controller: 'main',
    autoScroll: true,
    ui: 'navigation',
    // Truncated code

    items: [{
        title: 'Year to Date',
        iconCls: 'fa-bar-chart',
        items: [{
            html: '<h3>Your average expense per month is: ' + Ext.createByAlias('store.expensebyMonthStore').average('total') + '</h3>',
            height: 70,
        }, {
            xtype: 'mainlist'
        }, {
            xtype: 'mainbar'
        }]
    }, {
        title: 'By Month',
        iconCls: 'fa-pie-chart',
        items: [{
            xtype: 'combo',
            value: 'Jan',
            fieldLabel: 'Select Month',
            store: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
            listeners: {
                select: 'onMonthSelect'
            }
        }, {
            xtype: 'mainpie'
        }]
    }]
});