获取用户故事的计数并以网格显示

时间:2015-02-18 13:17:35

标签: javascript rally

此代码将显示总故事数,已接受的故事数和已完成的故事数以及故事点,项目连续完成的故事点

但是如何在后续行中为所有子项目显示相同的值。我的问题是"我如何根据项目对值进行分组,以及如何访问不同的项目以获取数据



Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
fieldLabel: 'Select iteration:',
labelWidth: 100,
width: 300
},
onScopeChange: function() {
Ext.create('Rally.data.wsapi.Store',{
model: 'User Story',
fetch: ['FormattedID','Name','PlanEstimate','ScheduleState'],
limit: Infinity,
autoLoad: true,
filters: [this.getContext().getTimeboxScope().getQueryFilter()],
sorters: [
{
property: 'DragAndDropRank',
direction: 'DESC'
}
],
listeners: {
load: this._onStoriesLoaded,
scope: this
}
});
},
_onStoriesLoaded: function(store,records){
var myData = [];
//in case we want to track them separately:
var estimatedStories = [];
var unestimatedStories = [];
var acceptedStories = [];
var completedStories = [];
var totalPlanEstimate = 0;
var acceptedPlanEstimate = 0;
var completedPlanEstimate = 0;
//var unestimatedStories = [];
console.log(records.length);
var estimated = false;
_.each(records, function(record){
if (record.get('PlanEstimate')) {
	totalPlanEstimate = record.get('PlanEstimate') + totalPlanEstimate;
	console.log("totalPlanEstimate",totalPlanEstimate);
	estimatedStories.push(record);
}
else{
 unestimatedStories.push(record);
}
},this);
_.each(records, function(record){
if (record.get('ScheduleState') === 'Accepted') {
	acceptedPlanEstimate = record.get('PlanEstimate') + acceptedPlanEstimate;
	console.log("acceptedPlanEstimate",acceptedPlanEstimate);
	console.log("record.getScheduleState",record.get('ScheduleState'));
	acceptedStories.push(record);
}
else if(record.get('ScheduleState') === 'Completed') {
	completedPlanEstimate = record.get('PlanEstimate') + completedPlanEstimate;
	console.log("completedPlanEstimate",completedPlanEstimate);
	console.log("record.getScheduleState",record.get('ScheduleState'));
	completedStories.push(record);
}
},this);

completedPercentage = (completedStories.length)/(records.length)*100;
completedStoryPointsPercentage = (completedPlanEstimate/totalPlanEstimate*100);

var list = {
tous : records.length,
es : estimatedStories.length,
//unes : unestimatedStories.length,
acus : acceptedStories.length,
cous : completedPercentage,
tosp : totalPlanEstimate,
acsp : acceptedPlanEstimate,
cosp : completedPlanEstimate,
cospp : completedStoryPointsPercentage
};
myData.push(list);
console.log("mydata",myData);
//console.log(estimatedStories.length, unestimatedStories.length);
this._makeGrid(myData);
},
_makeGrid:function(myData){
if(this.down('#storyGrid')){
this.down('#storyGrid').destroy();
}
var gridStore = Ext.create('Rally.data.custom.Store', {
data: myData,
limit:Infinity
//groupField: 'projectname'
});
this.add({
xtype: 'rallygrid',
itemId: 'storyGrid',
store: gridStore,
showRowActionsColumn: false,
width: 800,
columnCfgs:[
{
text: 'TOTAL USER STORY', dataIndex: 'tous'
},
{
text: 'ESTIMATED', dataIndex: 'es'
},
//{
//text: 'UNESTIMATED', dataIndex: 'unes'
//},
{
text: 'ACCEPTED', dataIndex: 'acus'
},
{
text: 'COMPLETED', dataIndex: 'cous'
},
{
text: 'TOTAL STORY POINTS', dataIndex: 'tosp'
},
{
text: 'ACCEPTED STORY POINTS', dataIndex: 'acsp'
},
{
text: 'COMPLETED STORY POINTS', dataIndex: 'cosp'
},
{
text: 'COMPLETED STORY PERCENTAGE', dataIndex: 'cospp'
}
]
});
}
});




1 个答案:

答案 0 :(得分:1)

我修改了你的代码现在你可以看到带有用户故事的网格,现在你可以指定你想要显示的字段,如团队/项目,总故事数,未估计的故事数,接受的故事数

         Ext.define('CustomApp', {
            extend: 'Rally.app.App',
            componentCls: 'app',
            launch: function() {
                console.log("My First App Mypie");
                //this._loadData();
                this._loadIterations();
            },


            _loadIterations: function() {

                var iterComboBox = Ext.create('Ext.Container', {
                    items: [{
                        xtype: 'rallyiterationcombobox',
                        storeConfig: {
                            listeners: {
                                 load: function(store, records){
                                    console.log(records);
                                }
                            }
                        },
                        listeners: {
                            select: function(combobox) {
                                var selectedIterRef = combobox.getRecord().get('_ref');
                                this._loadData(selectedIterRef);
                            },  
                            scope: this
                        }    
                    }],
                    renderTo: Ext.getBody().dom
                }, this);               

                this.add(iterComboBox);
                },
            //Get Data from Rally
          _loadData: function(selectedIterRef) {
            //var selectedIterRef = this.down('#priorityComboBox').getValue().get('_ref');
            console.log("selected iter", selectedIterRef);
            var myStore = Ext.create('Rally.data.wsapi.Store',{
                model: 'HierarchicalRequirement',
                autoLoad: true,
                    filters: [
                            {
                                property: 'Iteration',
                                operator: '=',
                                value: selectedIterRef
                            }
                        ],
                listeners: {
                    load: function(myStore,mydata, success) {
                    var storeLength = mydata.length;
                    this._loadGrid(myStore);
                },
                scope: this
                },
            fetch: ['FormattedID']
            });
          },
           //Create and show a grid for given stories
          _loadGrid: function(myStoreStore) {
            var myGrid = Ext.getCmp('myGrid');
            if (myGrid) {
                myGrid.destroy();
            };                    
            var mygrid = Ext.create('Rally.ui.grid.Grid',{
            store: myStoreStore,
            id: 'myGrid',
            columnCfgs: [
                'FormattedID','length'
            ]
           });
            this.add(mygrid);
            console.log("What is this", this);
            console.log("defectCount",length);
          }
        });

我的网格应用代码

            prepareChart: function(iteration_data) {

                //console.log("iteration_data", iteration_data);
                rootParent = this.getContext().getProject().Name;
                records = [];
                recordHash = {};    
                summaryHash = {};
                removable_teams = [];
                for ( var i=0; i<this.teams.length; i++ ) {
                    team_name = null;
                    var count = 0;
                    //console.log("count, data", this.teams[i], iteration_data[i]);
                    Ext.Array.each(iteration_data, function(data) {
                        if (this.teams[i] == data.Name && data.defectstory == 0 || null || undefined && data.Rework == 0 || null || undefined) {
                            count += 1;
                            team_name = data.Name;
                        }
                    }, this);
                    if (count == this.sprints.length) {
                        removable_teams.push(team_name);
                    }
                }   
                removable_teams = Ext.Array.unique(removable_teams);            
                Ext.Array.each(iteration_data, function(iter) {
                        //for (i=0; i < this.teams.length; i++){
                    if (!recordHash[iter.Name]) {
                        recordHash[iter.Name] = {
                            Team: iter.Name
                            //DefectStory: iter.defectstory
                            //Id: record.get('ObjectID')
                        };
                    }
                    if (!Ext.Array.contains(removable_teams, iter.Name)) {
                        recordHash[iter.Name]["DefectStory-" + iter.Sprint] = iter.defectstory;
                        recordHash[iter.Name]["Rework-" + iter.Sprint] = iter.Rework;                           
                        //recordHash[team.ProjectName] = {Summary: 0};
                    } else {
                        recordHash[iter.Name]["DefectStory-" + iter.Sprint] = -1;       
                        recordHash[iter.Name]["Rework-" + iter.Sprint] = -1;                            
                    }   
                }, this);
                Ext.Object.each(recordHash, function(key, value) {
                    //value["Summary"] = summaryHash[key].Total;
                    records.push(value);
                });
                //console.log("records values", records);
                var cfgsValues = [];
                cfgsValues.push({text: 'Team', style:"background-color: #99CCFF", dataIndex: 'Team', width: 170, renderer: function(value, meta_data, record, row, col) {
                    if (Ext.Array.contains(parents, value)) {
                        meta_data.style = 'background-color:#99CCFF';
                        return Ext.String.format("<div style='font-weight:bold;text-align:center'>{0}</div>", value);
                    } else if (rootParent == value){
                        //value = record.get('Team')
                        meta_data.style = 'background-color:#CC6699';
                        return Ext.String.format("<div style='font-weight:bold;text-align:center'>{0}</div>", value);                           
                    } else {
                        return Ext.String.format("<div style='font-weight:normal;text-align:center'>{0}</div>", value);
                    };
                }});
                Ext.Array.each(this.sprints, function(sprint) {
                    cfgsValues.push(
                        {text: sprint, style:'background-color:#99CCFF;text-align:center;font-weight:bold;', defaults: {enableColumnHide:false}, columns:[
                            {text: "Rework", dataIndex: 'Rework-'+sprint, width: 50, renderer: function(value, meta_data) {
                                var color = null;
                                //console.log("value value", value);
                                if (value == -1) {
                                    color = "#9B9B9B";
                                }                                   
                                else if (value < 0.05) {
                                    color = "#92D050";
                                }
                                else if (value >= 0.05 && value <= 0.5) {
                                    color = "#FFEB66";
                                }   
                                else if (value > 0.5) {
                                    color = "#C00000";
                                }   
                                meta_data.style = "background-color:"+color+"";
                                if ( value == -1) {
                                    return "";  
                                } else if (value){
                                    return Ext.String.format("<div style='font-weight:normal;text-align:center'>{0}</div>", Ext.Number.toFixed(value, 2));
                                } else {
                                    return 0;
                                }   
                            }},
                            {text: "D/Story", dataIndex: 'DefectStory-'+sprint, width: 50, renderer: function(value, meta_data) {
                                var color = null;
                                if (value == -1 || undefined) {
                                    color = "#9B9B9B";
                                }                                       
                                else if (value < 0.05) {
                                    color = "#92D050";
                                }   
                                else if (value > 0.05 && value <= 0.5) {
                                    color = "#FFEB66";
                                }   
                                else if (value > 0.5) {
                                    color = "#C00000";
                                }                                       
                                //meta_data.style = "background-color: "+color+"";
                                meta_data.style = "background-color:"+color+"";
                                //meta_data.style = "border:1px";
                                if ( value == -1) {
                                    return "";  
                                } else if (value){
                                    return Ext.String.format("<div style='font-weight:normal;text-align:center'>{0}</div>", Ext.Number.toFixed(value, 2));
                                } else {
                                    return 0;
                                }   
                            }}
                            /*{text: "%", dataIndex: 'DefectStory', width: 50, renderer: function(value, meta_data, record) {
                            }}*/
                        ]}  
                    );
                });
                var chart = Ext.getCmp('mychart');
                if (chart) {
                    chart.destroy();
                };
                Ext.Array.each(this.sprints, function(sprint) {
                    Ext.Array.each(records, function(record) {
                        if (record["DefectStory-" + sprint] == undefined) {
                            record["DefectStory-" + sprint] = undefined;
                        }
                        if (record["Rework-" + sprint] == undefined) {  
                            record["Rework-" + sprint] = undefined;
                        }                               
                    });
                });         
                this.add({
                    xtype: 'rallygrid',
                    id: 'mychart',  
                    store: Ext.create('Rally.data.custom.Store', {
                        data: records,
                        pageSize: 100
                    }),
                    /*features: [{
                        ftype: 'groupingsummary',
                        groupHeaderTpl: '{Name} ({rows.length})'
                    }],*/
                    viewConfig: { 
                        stripeRows: false, 
                        getRowClass: function(record) { 
                            if (record.ProjectName == rootParent) {
                                return 'purple-row';
                            };
                        } 
                    },                  
                    columnCfgs: cfgsValues,
                    //bodyBorder: true,
                    //border: true,
                    storeConfig: {
                        getGroupString: function(record) {
                            var Team = record.get('Name');
                            return Team || 'No Team';
                        },
                    },                      
                    columnLines: true
                }); 
                this.globalStore = Ext.getCmp('mychart');
                this.down('#grid_box').add(this.globalStore);
                //this.setLoading(false);
            },