Search code examples
extjsextjs4rally

Want to call a function when chart is loaded rally


Want to call a function when chart is loaded, written that function in listeners, but its getting called before the chart is displayed, any idea which event should I listen to chartRendered or any other

            getChartConfig: function(project_oid) {
                that = this;
                var chart = Ext.getCmp('mychart');
                if (chart) {
                    chart.destroy();
                }   
                return {
                    xtype:'rallychart',
                    id: 'mychart',
                    storeConfig: {
                        find: {
                                '_ProjectHierarchy': project_oid,
                                "$or": [
                                    {"_TypeHierarchy": "HierarchicalRequirement"},
                                    {"_TypeHierarchy": "Defect"}
                                ],
                                'Children': null
                            },
                            fetch: ['PlanEstimate','_TypeHierarchy','ObjectID', 'ScheduleState', '_ValidFrom', '_ValidTo', '_PreviousValues'],
                            hydrate: ['ScheduleState', '_TypeHierarchy'],
                            sort: { '_ValidFrom': 1 }
                        ,
                        /*find: {
                            '_ProjectHierarchy': project_oid,
                            "_TypeHierarchy": {
                                "$in": ['HierarchicalRequirement', 'Defect']
                            },
                            'Children': null
                        },
                        fetch: ['PlanEstimate','_TypeHierarchy','ObjectID', 'ScheduleState', '_ValidFrom', '_ValidTo', '_PreviousValues'],
                        hydrate: ['ScheduleState', '_TypeHierarchy'],
                        sort: { '_ValidFrom': 1 }*/
                    },
                    calculatorType: 'CycleCalculator',
                    chartColors: [ "#6AB17D", "#F47168", "#000000"],
                    calculatorConfig: {
                        startDate: Rally.util.DateTime.format(new Date(this._startDate), 'Y-m-d'),
                        endDate: Rally.util.DateTime.format(new Date(this._endDate), 'Y-m-d'),
                        startState: this._startState,
                        endState: this._endState
                        //granularity: 'week'
                    },
                    chartConfig: {
                        chart: {
                            type: 'line',
                        },
                        title: { text: 'Cycle/Lead Time' },
                        border: 1,
                        plotOptions: {
                            series: {                       
                                connectNulls: true,
                                marker: {
                                    enabled:false
                                }
                            }
                        },
                        xAxis: {
                            //tickmarkPlacement: 'on',
                            tickInterval: 10,
                            title: {
                                text: 'Months'
                            }
                        },
                        yAxis: [
                            {
                                title: {
                                    text: 'Average Days'
                                }
                            }
                        ]           
                    },  
                    listeners: {
                        snapshotsAggregated: this.showStats,
                        scope: this
                    }                       
                }
            },  

below the is function I want to call And in showStats() function I want use chart object,,,,please help..thanks in advance

            showStats: function(chart) {
                console.log("chart values", chart);
                var average = Ext.Array.mean(chart.calculator.globalVar);
                var average = Ext.Number.toFixed(average, 2);
                var min = Ext.Array.min(chart.calculator.globalVar);
                var max = Ext.Array.max(chart.calculator.globalVar);
                var count = Ext.Array.sum(chart.calculator.globalVar);
                console.log("field value", average, min, max, count);
                //field.fieldLabel = average;
                var stdDev = this.standardDeviation(average, chart.calculator.globalVar);
                var stdDev = Ext.Number.toFixed(stdDev, 2);
                this.down('#averageId').setText("Average  " + average); 
                this.down('#countId').setText("Count  " + count);   
                this.down('#minId').setText("Minimum  " + min); 
                this.down('#maxId').setText("Maximum  " + max); 
                this.down('#stdDevId').setText("Std Deviation  " + stdDev);                 
            },  

Solution

  • Your choice of chartRendered is correct- that is the last one to fire.

    If it is fires before the chart is fully rendered, it is a bug, but from my tests it looks like it fires at the right time. I do not know what data is stored in your globalVar and how you arrive at it. Perhaps the problem is somewhere else other then the timing of the chartRendered event.

    When I modify this example by adding chartRendered event listener, visually the console.log may log a little faster than the chart animation entirely completes, but the chart data is already fully loaded by then, and all the data is complete. I verified that by building a table with a few stats that you use. Here is the full code:

    Ext.define('Rally.example.BurnCalculator', {
        extend: 'Rally.data.lookback.calculator.TimeSeriesCalculator',
        config: {
            completedScheduleStateNames: ['Accepted']
        },
    
        constructor: function(config) {
            this.initConfig(config);
            this.callParent(arguments);
        },
    
        getDerivedFieldsOnInput: function() {
            var completedScheduleStateNames = this.getCompletedScheduleStateNames();
            return [
                {
                    "as": "Planned",
                    "f": function(snapshot) {
                        if (snapshot.PlanEstimate) {
                            return snapshot.PlanEstimate;
                        }
    
                        return 0;
                    }
                },
                {
                    "as": "PlannedCompleted",
                    "f": function(snapshot) {
                        if (_.contains(completedScheduleStateNames, snapshot.ScheduleState) && snapshot.PlanEstimate) {
                            return snapshot.PlanEstimate;
                        }
    
                        return 0;
                    }
                }
            ];
        },
    
        getMetrics: function() {
            return [
                {
                    "field": "Planned",
                    "as": "Planned",
                    "display": "line",
                    "f": "sum"
                },
                {
                    "field": "PlannedCompleted",
                    "as": "Completed",
                    "f": "sum",
                    "display": "column"
                }
            ];
        }
    });
    
    var PI_OID = 12483739639; //The ObjectID of the PI on which to burn
    
        Ext.define('Rally.example.BurnChart', {
            extend: 'Rally.app.App',
    
            requires: [
                'Rally.example.BurnCalculator'
            ],
    
            launch: function() {
                this.add({
                    xtype: 'rallychart',
                    storeType: 'Rally.data.lookback.SnapshotStore',
                    storeConfig: this._getStoreConfig(),
                    calculatorType: 'Rally.example.BurnCalculator',
                    calculatorConfig: {
                        completedScheduleStateNames: ['Accepted', 'Released']
                    },
                    chartConfig: this._getChartConfig(),
                    listeners:{
                            chartRendered: this._getStats,
                            scope:  this
                        }
                });
            },
    
        /**
         * Generate the store config to retrieve all snapshots for all leaf child stories of the specified PI
         */
        _getStoreConfig: function() {
            return {
                find: {
                    _ItemHierarchy: PI_OID,
                    _TypeHierarchy: 'HierarchicalRequirement',
                    Children: null
                },
                fetch: ['ScheduleState', 'PlanEstimate'],
                hydrate: ['ScheduleState'],
                sort: {
                    _ValidFrom: 1
                },
                context: this.getContext().getDataContext(),
                limit: Infinity
            };
        },
    
        /**
         * Generate a valid Highcharts configuration object to specify the chart
         */
        _getChartConfig: function() {
            return {
                chart: {
                    defaultSeriesType: 'area',
                    zoomType: 'xy'
                },
                title: {
                    text: 'PI Burnup'
                },
                xAxis: {
                    categories: [],
                    tickmarkPlacement: 'on',
                    tickInterval: 5,
                    title: {
                        text: 'Date',
                        margin: 10
                    }
                },
                yAxis: [
                    {
                        title: {
                            text: 'Points'
                        }
                    }
                ],
                tooltip: {
                    formatter: function() {
                        return '' + this.x + '<br />' + this.series.name + ': ' + this.y;
                    }
                },
                plotOptions: {
                    series: {
                        marker: {
                            enabled: false,
                            states: {
                                hover: {
                                    enabled: true
                                }
                            }
                        },
                        groupPadding: 0.01
                    },
                    column: {
                        stacking: null,
                        shadow: false
                    }
                }
            };
        },
        _getStats:function(chart){
            var stats = [];
            console.log(chart);
            var series = chart.chartData.series;
            _.each(series, function(s){
                stats.push({
                    name    : s.name,
                    average : Ext.Number.toFixed(Ext.Array.mean(s.data), 2),
                    min     : Ext.Array.min(s.data),
                    max     : Ext.Array.max(s.data),
                    count   : Ext.Array.sum(s.data)
                });
            });
            this._showStats(stats);
        },
    
        _showStats: function(stats) {
            console.log(stats);
            this.add({
                xtype: 'rallygrid',
                store: Ext.create('Rally.data.custom.Store', {
                    data: stats
                }),
                columnCfgs: [
                    {
                        text: 'Name',
                        dataIndex: 'name'
                    },
                    {
                        text: 'Average',
                        dataIndex: 'average'
                    },
                    {
                        text: 'Min',
                        dataIndex: 'min'
                    },
                    {
                        text: 'Max',
                        dataIndex: 'max'
                    },
                    {
                        text: 'Count',
                        dataIndex: 'count'
                    }
                ]
            });
        }
    });
    

    enter image description here