Exemplo ExtJS 4 MVC: Complex DashBoard (Grid, Form e Gráficos)

14/05/2012 | By | 4 Comments

Mais um exemplo MVC de ExtJS 4 aqui no blog. Hoje vamos ver o código do exemplo Complex Dashboard.

extjs4 mvc complex dashboard loiane Exemplo ExtJS 4 MVC: Complex DashBoard (Grid, Form e Gráficos)

Vamos lá!

Estrutura do Projeto:

extjs4 mvc complex dashboard Exemplo ExtJS 4 MVC: Complex DashBoard (Grid, Form e Gráficos)

Model – Stock

Ext.define('ExtMVC.model.Stock', {
	extend: 'Ext.data.Model',
	fields: [
	    {name: 'company'},
        {name: 'price',   type: 'float'},
        {name: 'revenue %', type: 'float'},
        {name: 'growth %',  type: 'float'},
        {name: 'product %', type: 'float'},
        {name: 'market %',  type: 'float'}
    ]
});

Model – RadarDataSet

Ext.define('ExtMVC.model.RadarDataSet', {
	extend: 'Ext.data.Model',
	fields: ['Name', 'Data']
});

Store - Stock

Ext.define('ExtMVC.store.Stocks', {
    extend: 'Ext.data.ArrayStore',
    model: 'ExtMVC.model.Stock'
});

Store - RadarDataSet

Ext.define('ExtMVC.store.RadarDataSets', {
    extend: 'Ext.data.ArrayStore',
    model: 'ExtMVC.model.RadarDataSet',

    proxy: {
        type: 'memory',
        reader: {
            type: 'json'
        }
    },

    data: [
    {
        'Name': 'Price',
        'Data': 100
    }, {
        'Name': 'Revenue %',
        'Data': 100
    }, {
        'Name': 'Growth %',
        'Data': 100
    }, {
        'Name': 'Product %',
        'Data': 100
    }, {
        'Name': 'Market %',
        'Data': 100
    }]
});

View – chart – StockBar

Ext.define('ExtMVC.view.chart.StockBar', {
	extend: 'Ext.chart.Chart',
    alias : 'widget.stockbar',

	flex: 1,
    shadow: true,
    animate: true,
    store: 'Stocks',
    axes: [{
        type: 'Numeric',
        position: 'left',
        fields: ['price'],
        minimum: 0,
        hidden: true
    }, {
        type: 'Category',
        position: 'bottom',
        fields: ['company'],
        label: {
            renderer: function(v) {
                return Ext.String.ellipsis(v, 15, false);
            },
            font: '9px Arial',
            rotate: {
                degrees: 270
            }
        }
    }],
    series: [{
        type: 'column',
        axis: 'left',
        highlight: true,
        style: {
            fill: '#456d9f'
        },
        highlightCfg: {
            fill: '#a2b5ca'
        },
        label: {
            contrast: true,
            display: 'insideEnd',
            field: 'price',
            color: '#000',
            orientation: 'vertical',
            'text-anchor': 'middle'
        },
        xField: 'name',
        yField: ['price']
    }]
});

View – chart – StockRadar

Ext.define('ExtMVC.view.chart.StockRadar', {
	extend: 'Ext.chart.Chart',
    alias : 'widget.stockradar',

	margin: '0 0 0 0',
    insetPadding: 20,
    flex: 1.2,
    animate: true,
    store: 'RadarDataSets',
    theme: 'Blue',
    axes: [{
        steps: 5,
        type: 'Radial',
        position: 'radial',
        maximum: 100
    }],
    series: [{
        type: 'radar',
        xField: 'Name',
        yField: 'Data',
        showInLegend: false,
        showMarkers: true,
        markerConfig: {
            radius: 4,
            size: 4,
            fill: 'rgb(69,109,159)'
        },
        style: {
            fill: 'rgb(194,214,240)',
            opacity: 0.5,
            'stroke-width': 0.5
        }
    }]
});

View – stocks- StockGrid

Ext.define('ExtMVC.view.stocks.StockGrid', {
	extend: 'Ext.grid.Panel',
	alias : 'widget.stockgrid',

	id: 'company-form',
    flex: 0.60,
    store: 'Stocks',
    title:'Company Data',

    perc: function(v) {
        return v + '%';
    },

    initComponent: function() {

	    this.columns= [
	        {
	            id       :'company',
	            text   : 'Company',
	            flex: 1,
	            sortable : true,
	            dataIndex: 'company'
	        },
	        {
	            text   : 'Price',
	            width    : 75,
	            sortable : true,
	            dataIndex: 'price',
	            align: 'right',
	            renderer : 'usMoney'
	        },
	        {
	            text   : 'Revenue',
	            width    : 75,
	            sortable : true,
	            align: 'right',
	            dataIndex: 'revenue %',
	            renderer: this.perc
	        },
	        {
	            text   : 'Growth',
	            width    : 75,
	            sortable : true,
	            align: 'right',
	            dataIndex: 'growth %',
	            renderer: this.perc
	        },
	        {
	            text   : 'Product',
	            width    : 75,
	            sortable : true,
	            align: 'right',
	            dataIndex: 'product %',
	            renderer: this.perc
	        },
	        {
	            text   : 'Market',
	            width    : 75,
	            sortable : true,
	            align: 'right',
	            dataIndex: 'market %',
	            renderer: this.perc
	        }
	    ];

		this.callParent(arguments);
    }
});

View – stocks- StockForm

Ext.define('ExtMVC.view.stocks.StockForm', {
	extend: 'Ext.form.Panel',
	alias : 'widget.stockform',

	requires: [
		'ExtMVC.view.stocks.StockGrid',
		'ExtMVC.view.chart.StockBar',
		'ExtMVC.view.chart.StockRadar'
	],

	title: 'Company data',
    frame: true,
    bodyPadding: 5,
    //width: 870,
    //height: 720,

    fieldDefaults: {
        labelAlign: 'left',
        msgTarget: 'side'
    },

    layout: {
        type: 'vbox',
        align: 'stretch'
    },

    items: [
        {
            height: 200,
            layout: 'fit',
            margin: '0 0 3 0',
            items: [{ xtype: 'stockbar'}]
        },
        {

        layout: {type: 'hbox', align: 'stretch'},
        flex: 3,
        border: false,
        bodyStyle: 'background-color: transparent',

        items: [{
        	xtype: 'stockgrid'
        }, {
            flex: 0.4,
            layout: {
                type: 'vbox',
                align:'stretch'
            },
            margin: '0 0 0 5',
            title: 'Company Details',
            items: [{
                margin: '5',
                xtype: 'fieldset',
                flex: 1,
                title:'Company details',
                defaults: {
                    width: 240,
                    labelWidth: 90,
                    disabled: true
                },
                defaultType: 'numberfield',
                items: [{
                    fieldLabel: 'Name',
                    name: 'company',
                    xtype: 'textfield'
                },{
                    fieldLabel: 'Price',
                    name: 'price',
                    maxValue: 100,
                    minValue: 0,
                    enforceMaxLength: true,
                    maxLength: 5
                },{
                    fieldLabel: 'Revenue %',
                    name: 'revenue %',
                    maxValue: 100,
                    minValue: 0,
                    enforceMaxLength: true,
                    maxLength: 5
                },{
                    fieldLabel: 'Growth %',
                    name: 'growth %',
                    maxValue: 100,
                    minValue: 0,
                    enforceMaxLength: true,
                    maxLength: 5
                },{
                    fieldLabel: 'Product %',
                    name: 'product %',
                    maxValue: 100,
                    minValue: 0,
                    enforceMaxLength: true,
                    maxLength: 5
                },{
                    fieldLabel: 'Market %',
                    name: 'market %',
                    maxValue: 100,
                    minValue: 0,
                    enforceMaxLength: true,
                    maxLength: 5
                }]
            }, {xtype:'stockradar'}]
        }]
    }]
});

ViewPort

/**
 * The main application viewport, which displays the whole application
 * @extends Ext.Viewport
 */
Ext.define('ExtMVC.view.Viewport', {
    extend: 'Ext.Viewport',

    layout: 'fit',

    requires: [
        'ExtMVC.view.stocks.StockForm',
        'ExtMVC.view.stocks.StockGrid',
        'ExtMVC.view.chart.StockBar',
        'ExtMVC.view.chart.StockRadar'
    ],

    initComponent: function() {
        var me = this;

        Ext.apply(me, {
            items: [
                {
                    xtype: 'stockform'
                }
            ]
        });

        me.callParent(arguments);
    }
});

Controller

Ext.define('ExtMVC.controller.Stocks', {
    extend: 'Ext.app.Controller',

    models: ['Stock','RadarDataSet'],

   	stores: ['Stocks', 'RadarDataSets'],

    views: [
        'chart.StockRadar',
        'chart.StockBar',
        'stocks.StockGrid',
        'stocks.StockForm'
    ],

    refs: [{
        ref: 'stockForm',
        selector: 'form'
    },{
        ref: 'stockGrid',
        selector: 'grid'
    }],

    init: function() {

        this.loadStore();

        this.control({
        	'stockgrid': {
        		selectionchange: this.selectionchange
        	}/*,
            'textfield': {
                change: this.changeField
            }*/,
            'numberfield': {
                change: this.changeField
            },
            'stockbar': {
                afterrender: function (chart,o) {

                    var series = chart.series.getAt(0);
                    series.listeners = {
                        itemmouseup: function(item) {

                            var series = Ext.ComponentQuery.query('stockbar')[0].series.get(0);
                            var index = Ext.Array.indexOf(series.items, item);
                            var selectionModel = Ext.ComponentQuery.query('grid')[0].getSelectionModel();

                            var selectedStoreItem = item.storeItem;
                            selectionModel.select(index);
                        }
                    }
                },
                beforerefresh: this.beforerefresh
            }
        });
    },

    loadStore: function(){

        var store = this.getStocksStore();

        // sample static data for the store
        var myData = [
            ['3m Co'],
            ['Alcoa Inc'],
            ['Altria Group Inc'],
            ['American Express Company'],
            ['American International Group, Inc.'],
            ['AT&T Inc'],
            ['Boeing Co.'],
            ['Caterpillar Inc.'],
            ['Citigroup, Inc.'],
            ['E.I. du Pont de Nemours and Company'],
            ['Exxon Mobil Corp'],
            ['General Electric Company'],
            ['General Motors Corporation'],
            ['Hewlett-Packard Co'],
            ['Honeywell Intl Inc'],
            ['Intel Corporation'],
            ['International Business Machines'],
            ['Johnson & Johnson'],
            ['JP Morgan & Chase & Co'],
            ['McDonald\'s Corporation'],
            ['Merck & Co., Inc.'],
            ['Microsoft Corporation'],
            ['Pfizer Inc'],
            ['The Coca-Cola Company'],
            ['The Home Depot, Inc.'],
            ['The Procter & Gamble Company'],
            ['United Technologies Corporation'],
            ['Verizon Communications'],
            ['Wal-Mart Stores, Inc.']
        ];

        for (var i = 0, l = myData.length, rand = Math.random; i < l; i++) {
            var data = myData[i];
            data[1] = ((rand() * 10000) >> 0) / 100;
            data[2] = ((rand() * 10000) >> 0) / 100;
            data[3] = ((rand() * 10000) >> 0) / 100;
            data[4] = ((rand() * 10000) >> 0) / 100;
            data[5] = ((rand() * 10000) >> 0) / 100;
        }

        store.loadData(myData);
    },

    selectionchange: function(model, records){

        var json, name, i, l, items, series, fields;

        var form = this.getStockForm().getForm();

        if (records[0]) {
            rec = records[0];

            if (!form) {
                form = this.getStockForm().getForm();
                fields = form.getFields();
                fields.each(function(field){
                    if (field.name != 'company') {
                        field.setDisabled(false);
                    }
                });
            } else {
                fields = form.getFields();
            }

            // prevent change events from firing
            fields.each(function(field){
                field.suspendEvents();
                console.log('suspended');
            });
            form.loadRecord(rec);
            this.updateRecord(rec);

            fields.each(function(field){
                field.resumeEvents();
            });

            fields.each(function(field){
                if (field.name != 'company') {
                    field.setDisabled(false);
                }
            });
        }
    },

    updateRecord: function(rec) {
        var name, series, i, l, items, json = [{
            'Name': 'Price',
            'Data': rec.get('price')
        }, {
            'Name': 'Revenue %',
            'Data': rec.get('revenue %')
        }, {
            'Name': 'Growth %',
            'Data': rec.get('growth %')
        }, {
            'Name': 'Product %',
            'Data': rec.get('product %')
        }, {
            'Name': 'Market %',
            'Data': rec.get('market %')
        }];

        var store = this.getRadarDataSetsStore();
        store.loadData(json);
        this.selectItem(rec);
    },

    selectItem: function(storeItem) {

        var name = storeItem.data.company;//storeItem.get('company'),
        var series = Ext.ComponentQuery.query('stockbar')[0].series.get(0);
        var i, items, l;

        series.highlight = true;
        series.unHighlightItem();
        series.cleanHighlights();
        for (i = 0, items = series.items, l = items.length; i < l; i++) {
            if (name == items[i].storeItem.get('company')) {
                selectedStoreItem = items[i].storeItem;
                series.highlightItem(items[i]);
                break;
            }
        }
        series.highlight = false;
    },

    changeField: function(field, newValue, oldValue) {

        console.log('changeField');

        var form = this.getStockForm().getForm();
        var rec = this.getStockGrid().getSelectionModel().getSelection()[0];

        if (rec && form) {
            if (newValue > field.maxValue) {
                field.setValue(field.maxValue);
            } else {
                form.updateRecord(rec);
                this.updateRecord(rec);
            }
        }
    },

    beforerefresh: function() {
        var timer = false;

        return function() {
            clearTimeout(timer);

            var series = Ext.ComponentQuery.query('stockbar')[0].series.get(0);
            var index = Ext.Array.indexOf(series.items, item);
            var selectionModel = Ext.ComponentQuery.query('grid')[0].getSelectionModel();
            var selectedStoreItem = item.storeItem;

            if (selectedStoreItem) {
                timer = setTimeout(function() {
                    this.selectItem(selectedStoreItem);
                }, 900);
            }
        };
    }
});

App

Ext.Loader.setConfig({enabled: true});
Ext.Loader.setPath('Ext.ux', 'app/ux');

/*
 * BUG: suspentEvents not honoured in Ext.app.EventBus
 *
 * note: this fix does not queue events when asked.
 *
 * http://www.sencha.com/forum/showthread.php?171525
 */
Ext.syncRequire('Ext.app.EventBus');
Ext.override(Ext.app.EventBus, {
    constructor: function() {
        this.mixins.observable.constructor.call(this);

        this.bus = {};

        var me = this;
        Ext.override(Ext.Component, {
            fireEvent: function(ev) {
// [
// --
//              if (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false) {
// ++
                if (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false && !this.eventsSuspended) {
// ]
                    return me.dispatch.call(me, ev, this, arguments);
                }
                return false;
            }
        });
    }
});

Ext.application({
    name: 'ExtMVC',

    controllers: [
        'Stocks'
    ],

    autoCreateViewport: true
});

Página HTML

<html>
<head>
    <title>Ext JS 4 MVC Examples - loiane.com</title>
    <!-- Ext JS Files -->
    <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
    <script type="text/javascript" src="extjs/ext-all-debug.js"></script>
    
    <!-- App Files -->
    <script type="text/javascript" src="app.js"></script>
    
</head>
<body>
</body>
</html>

Download do Código Fonte:

Você pode fazer o download do código fonte completo no meu repositório do github: https://github.com/loiane/extjs4-mvc-complex-dashboard

Demo:

Exemplo funcionando: http://loiane.com/extjs/extjs4-mvc-complex-dashboard

Todos os exemplos ExtJS 4 MVC:

http://www.loiane.com/2012/03/exemplos-sencha-extjs-4-em-mvc/

Até o próximo exemplo! icon smile Exemplo ExtJS 4 MVC: Complex DashBoard (Grid, Form e Gráficos)

Filed in: Ext JS 4 | Tags: ,

Comments (4)

    • Oi Douglas,
      Meu blog foi hackeado tempos atrás e acabei tirando algumas coisas do ar.
      Quando tiver um tempinho coloco de novo o link!
      []‘s

  1. Carlos

    Pode fazer uma aplicacao assim como o Sencha Architect 2?

Leave a Reply

Trackback URL | RSS Feed for This Entry

VideoPokiesOnline.com is the leading Pokies - Online Casino Guide in Australia. Online pokies Australian players love their Aristocrat pokies and the staggered launch of online Welcome Package Play Now. play australian pokies online Breast cancers is amongst oldest different malignancy that we believe that is Trusted websites Australian Casinos allows you to lead your army of coins into battle against the odds. Free Online Pokies at Top Rated Australian Online Casinos.
Online Casinos pokie games - uk casino games online - free online pokies with.
Slots and enjoy: ?one of a kind VIP program ? $500 Welcome Package ? Online Pokies Australia online casinos and land parlors. Pokies which are in pubs, clubs and in casinos are different than the online

Online Slots Wild Jack.