MSB
MSB

Reputation: 884

How to make an Extjs4.2 Chart filtered by a list

I'm pretty new to web development and ExtJS, I've looked around for tutorials on more complex concepts but they are hard to find (Yes I've found the Sencha documentation but the only provide simple concepts)

I'm trying to make a dashboard for my application, in this dashboard I want a chart that gives a detailed overview of my statistics. In order to accomplish this I am trying to add a custom filter for the chart by making a seperate list with that holds all the instances of the key, when selecting said instances from a list I want the chart to only display those selected instances.

The chart I made:

Ext.define('view.chart.LocationStatisticsPerMonth', {
    extend: 'Ext.chart.Chart',
    alias: 'widget.LocationStatisticsPerMonthChart',
    requires: [
        'store.LocationStatisticsStore',
        'store.TemplateStore',
        'view.TitleToolbar'
    ],

    constructor: function () {
        this.store = Ext.create('store.LocationStatisticsStore', {
            autoLoad: true, sorters: [{
                property: 'YearMonth',
                direction: 'ASC'
            }]
        });
        this.store.getProxy().api.read = ServerControllers.Dashboard.LocationStatisticsPerMonth;
        this.callParent(arguments);
    },
    animate: true,
    shadow: true,
    border: true,

    legend: {
        position: 'right'
    },

    axes: [{
        type: 'Numeric',
        position: 'left',
        fields: ['TotalCount'],
        title: false,
        grid: true,
        label: {
            renderer: function (v) {
                return String(v);
            }
        }
    }, {
        type: 'Category',
        position: 'bottom',
        fields: ['Location_Id'],
        title: false,
        label: {
            rotate: {
                degrees: 315
            }


        }


    }],


    series: [{
        type: 'column',
        axis: 'left',
        gutter: 80,
        xField: ['Location_Id'],
        yField: ['TotalCount'],

        tips: {
            trackMouse: true,
            width: 125,
            height: 28,
            renderer: function(storeItem, item) {
                this.setTitle(String('Visitors: '+item.value[1]));
            }
        }
    }]
});

My Store

Ext.define('store.LocationStatisticsStore', {
    extend: 'Ext.data.Store',
    requires: ['model.LocationStatistics'],
    model: 'model.LocationStatistics',
    autoLoad: false,
    remoteSort: false,
    remoteFilter: false,
    filterOnLoad: true,
    sorters: [{
        property: ['YearMonth' , 'Location_Id'],
        direction: 'DESC'
    }],
    proxy: {
        type: 'direct',
        paramOrder: [],
        api: {
            read: ServerControllers.Reports.GetLocationStatisticsPerMonth
        },
        reader: {
            type: 'json',
            root: 'data',
            totalProperty: 'totalRecords',
            successProperty: 'success',
            messageProperty: 'msg'
        }
    }
});

My Model:

Ext.define('model.LocationStatistics', {
    extend: 'Ext.data.Model',
    idProperty: ['Location_Id'],
    fields: [
        { name: 'YearMonth', type: 'string' },
        { name: 'Location_Id', type: 'int' },
    { name: 'Year', type: 'int' },
        { name: 'Month', type: 'int' },
        { name: 'TotalCount', type: 'int' },
        { name: 'AverageCountPerDay', type: 'int' }
    ]

});

Would anyone be so kind as to explain this concept to me, link a tutorial or provide me an example of how to go about doing this?

Help is greatly appreciated.

EDIT: the panel that this is contained in:

 Ext.define('view.panel.DashboardStatisticsPanel', {
    extend    : 'Ext.panel.Panel',
    alias    : 'widget.DashboardStatisticsPanel',
    requires : [
        'Ext.layout.container.Column',
        'view.chart.LocationStatisticsPerMonth'
    ],
    plain: true,
    border: false,
    layout: {
        type: 'hbox',
        padding: '10 10 10 10'
    },



    items: [{
        xtype: 'panel',
        layout: 'fit',
        border: true,
        flex: 1,
        items: [{
            xtype: 'panel',
            layout: 'anchor',
            border: true,
            overflowX: 'scroll',
            height: 400,


            dockedItems: [{
            xtype: 'toolbar',
            dock: 'top',
            items: [{
                xtype: 'label',
                text: 'Select Date',
                padding: '0 0 0 10'
            },


                {
                xtype: 'combobox',
                displayField: 'YearMonth',
                emptyText: 'Select Date ',
                queryMode: 'local',
                padding: '0 0 0 10',
                store: function (btn) {
                    btn.up('panel').down('LocationStatisticsPerMonthChart').getStore();
                },
                valueField: 'YearMonth',

            }]
        }]
            /*tbar: [{


                text: 'September Only',
                handler: function (btn) {
                    var store = btn.up('panel').down('LocationStatisticsPerMonthChart').getStore();
                    store.clearFilter();
                    Ext.defer(function (btn) {
                        store.filter("Month", 9);
                    }, 300);
                }





            }]*/,
            items: [{
                xtype: 'LocationStatisticsPerMonthChart',
                itemId: 'LocationStatisticsPerMonthChart',
                anchor: '2000, -10',
                //height: 400,
               // width: 2000,
            }]

        }],
        dockedItems: [{
            xtype: 'TitleToolbar',
            dock: 'top',
            title: Resources.t('RegistrationsPerUnit'),
            items: ['->', {
                iconCls: 'iconRefresh',
                itemId: 'refresh',
                scope: this,
                handler: function (btn) {
                    var store = btn.up('panel').down('LocationStatisticsPerMonthChart').getStore();
                    //store.removeAll();
                    store.load();
                }
            }]
        }]


    }] 


});

Upvotes: 0

Views: 670

Answers (2)

undeclared
undeclared

Reputation: 26

The best way is to use a function, I'll give you an example:

We have a store, let's call it StoreA, and another store StoreB

var storeA = something.getStore();
var storeB = somethingElse.getStore();

storeA.filterBy(function(record) {
    return storeB.find("name", record.data.name) != -1; 
});

So basicly in this example, if the name is in storeB (find returns an index), it will filter it out from storeA's contents.

Unfortunately, you will have to re-do the exact same filter every time a new record is added or updated... so what I do is bind a function that does this to the load, update, delete, etc.. events.

Upvotes: 1

overlordhammer
overlordhammer

Reputation: 1333

You only need to filter the related data store. To accomplish this use the filter method as follows:

chart.store.filter("Month", 10);

You can always remove the filtering on the store by calling clearFilter store's method,

chart.store.clearFilter();

Take into account that you need to remove previous filters when applying new ones otherwise the each new applied filter will stack with the current ones

You can see a small example based on your code here. Hope it helps you to solve your problem.

Upvotes: 0

Related Questions