<commit_before><!DOCTYPE html>
<html>
<head>
    <title>psi-feature-burnup</title>

    <script type="text/javascript" src="/apps/2.0rc1/sdk.js"></script>

    <script type="text/javascript">
        Rally.onReady(function () {
                var peRecords=[],acceptedData=[];Ext.define("MyBurnCalculator",{extend:"Rally.data.lookback.calculator.TimeSeriesCalculator",getMetrics:function(){var metrics=[{field:"LeafStoryPlanEstimateTotal",as:"Planned Points",display:"line",f:"sum"},{field:"CalcPreliminaryEstimate",as:"PreliminaryEstimate",display:"line",f:"sum"},{field:"AcceptedLeafStoryPlanEstimateTotal",as:"Accepted Points",display:"line",f:"sum"},{field:"ObjectID",as:"Count",display:"column",f:"count"},{field:"Completed",as:"Completed",display:"column",f:"sum"}];return metrics},getDerivedFieldsOnInput:function(){return[{as:"CalcPreliminaryEstimate",f:function(row){var r=_.find(peRecords,function(rec){return rec.get("ObjectID")==row.PreliminaryEstimate});return void 0!=r?r.get("Value"):0}},{as:"Completed",f:function(row){return 1==row.PercentDoneByStoryCount?1:0}}]},getDerivedFieldsAfterSummary:function(){return[{as:"Projection",f:function(row,index,summaryMetrics,seriesData){if(0==index){datesData=_.pluck(seriesData,"label"),acceptedData=_.pluck(seriesData,"Accepted Points"),console.log("accepted date len",acceptedData.length);var today=new Date;acceptedData=_.filter(acceptedData,function(d,i){return today>new Date(Date.parse(datesData[i]))}),console.log("accepted date len",acceptedData.length)}var y=linearProject(acceptedData,index);return y}}]},defined:function(v){return!_.isUndefined(v)&&!_.isNull(v)}}),Ext.define("CustomApp",{scopeType:"release",extend:"Rally.app.App",componentCls:"app",launch:function(){console.log("launch");var timeboxScope=this.getContext().getTimeboxScope(),tbName=null;if(timeboxScope){var record=timeboxScope.getRecord();tbName=record.get("Name")}else tbName="";var peStore=Ext.create("Rally.data.WsapiDataStore",{autoLoad:!0,model:"PreliminaryEstimate",fetch:["Name","ObjectID","Value"],filters:[],listeners:{scope:this,load:function(store,data){peRecords=data,this.queryReleases(tbName)}}})},queryReleases:function(name){var releaseStore;return releaseStore=Ext.create("Rally.data.WsapiDataStore",{autoLoad:!0,model:"Release",fetch:["Name","ObjectID","Project","ReleaseStartDate","ReleaseDate"],filters:[],listeners:{load:function(store,releaseRecords){var releases=_.map(releaseRecords,function(rec){return{name:rec.get("Name"),objectid:rec.get("ObjectID")}});releases=_.uniq(releases,function(r){return r.name});var releasesStore=Ext.create("Ext.data.Store",{fields:["name","objectid"],data:releases}),cb=Ext.create("Ext.ux.CheckCombo",{fieldLabel:"Release",store:releasesStore,queryMode:"local",displayField:"name",valueField:"name",noData:!0,width:300,listeners:{scope:this,collapse:function(field,eOpts){var releases=[];_.each(field.getValue().split(","),function(rn){_.each(_.filter(releaseRecords,function(r){return rn==r.get("Name")}),function(rel){releases.push(rel)})}),this.querySnapshots(releases)}}});this.add(cb)},scope:this}})},querySnapshots:function(releases){var ids=_.pluck(releases,function(release){return release.get("ObjectID")});this.chartConfig.storeConfig.find.Release={$in:ids};var start=_.min(_.pluck(releases,function(r){return r.get("ReleaseStartDate")})),end=_.max(_.pluck(releases,function(r){return r.get("ReleaseDate")}));console.log("start",start),console.log("end",end),this.chartConfig.calculatorConfig.startDate=start,this.chartConfig.calculatorConfig.endDate=end;var chart=this.down("#myChart");null!=chart&&this.remove(chart),console.log(this.chartConfig),this.add(this.chartConfig)},chartConfig:{xtype:"rallychart",itemId:"myChart",chartColors:["Gray","Orange","Green","Blue","Green","LightGray"],storeConfig:{find:{_TypeHierarchy:{$in:["PortfolioItem/Feature"]}},autoLoad:!0,limit:1/0,fetch:["ObjectID","Name","_TypeHierarchy","PreliminaryEstimate","LeafStoryPlanEstimateTotal","AcceptedLeafStoryPlanEstimateTotal","PercentDoneByStoryCount"],hydrate:["_TypeHierarchy","PreliminaryEstimate"]},calculatorType:"MyBurnCalculator",calculatorConfig:{},chartConfig:{plotOptions:{series:{marker:{radius:2}}},chart:{colors:[],zoomType:"xy"},title:{text:"Feature Burnup"},xAxis:{tickInterval:7,labels:{formatter:function(){var d=new Date(this.value);return""+(d.getMonth()+1)+"/"+d.getDate()}},title:{text:"Days"}},yAxis:[{title:{text:"Points"}}]}}});
                Ext.define("Ext.ux.CheckCombo",{extend:"Ext.form.field.ComboBox",alias:"widget.checkcombo",multiSelect:!0,allSelector:!1,noData:!1,noDataText:"No combo data",addAllSelector:!1,allSelectorHidden:!1,enableKeyEvents:!0,afterExpandCheck:!1,allText:"All",oldValue:"",listeners:{focus:function(cpt){cpt.oldValue=cpt.getValue()},keydown:function(cpt,e,eOpts){var value=cpt.getRawValue(),oldValue=cpt.oldValue;value!=oldValue&&cpt.setValue("")}},createPicker:function(){var me=this,picker,menuCls=Ext.baseCSSPrefix+"menu",opts=Ext.apply({pickerField:me,selModel:{mode:me.multiSelect?"SIMPLE":"SINGLE"},floating:!0,hidden:!0,ownerCt:me.ownerCt,cls:me.el.up("."+menuCls)?menuCls:"",store:me.store,displayField:me.displayField,focusOnToFront:!1,pageSize:me.pageSize,tpl:['<ul><tpl for=".">','<li role="option" class="'+Ext.baseCSSPrefix+'boundlist-item"><span class="x-combo-checker">&nbsp;</span> {'+me.displayField+"}</li>","</tpl></ul>"]},me.listConfig,me.defaultListConfig);return picker=me.picker=Ext.create("Ext.view.BoundList",opts),me.pageSize&&picker.pagingToolbar.on("beforechange",me.onPageChange,me),me.mon(picker,{itemclick:me.onItemClick,refresh:me.onListRefresh,scope:me}),me.mon(picker.getSelectionModel(),{beforeselect:me.onBeforeSelect,beforedeselect:me.onBeforeDeselect,selectionchange:me.onListSelectionChange,scope:me}),me.store.on("load",function(store){0==store.getTotalCount()?(me.allSelectorHidden=!0,0!=me.allSelector&&me.allSelector.setStyle("display","none"),0!=me.noData&&me.noData.setStyle("display","block")):(me.allSelectorHidden=!1,0!=me.allSelector&&me.allSelector.setStyle("display","block"),0!=me.noData&&me.noData.setStyle("display","none"))}),picker},reset:function(){var me=this;me.setValue("")},setValue:function(value){if(this.value=value,!value)return 0!=this.allSelector&&this.allSelector.removeCls("x-boundlist-selected"),this.callParent(arguments);if("string"==typeof value){var me=this,records=[],vals=value.split(",");return""==value?0!=me.allSelector&&me.allSelector.removeCls("x-boundlist-selected"):vals.length==me.store.getCount()&&0!=vals.length&&(0!=me.allSelector?me.allSelector.addCls("x-boundlist-selected"):me.afterExpandCheck=!0),Ext.each(vals,function(val){var record=me.store.getById(parseInt(val));record&&records.push(record)}),me.setValue(records)}return this.callParent(arguments)},getValue:function(){return"object"==typeof this.value?this.value.join(","):this.value},getSubmitValue:function(){return this.getValue()},expand:function(){var me=this,bodyEl,picker,collapseIf;!me.rendered||me.isExpanded||me.isDestroyed?(me.fireEvent("expand",me),me.onExpand()):(bodyEl=me.bodyEl,picker=me.getPicker(),collapseIf=me.collapseIf,picker.show(),me.isExpanded=!0,me.alignPicker(),bodyEl.addCls(me.openCls),0==me.noData&&(me.noData=picker.getEl().down(".x-boundlist-list-ct").insertHtml("beforeBegin",'<div class="x-boundlist-item" role="option">'+me.noDataText+"</div>",!0)),1==me.addAllSelector&&0==me.allSelector&&(me.allSelector=picker.getEl().down(".x-boundlist-list-ct").insertHtml("beforeBegin",'<div class="x-boundlist-item" role="option"><span class="x-combo-checker">&nbsp;</span> '+me.allText+"</div>",!0),me.allSelector.on("click",function(e){if(me.allSelector.hasCls("x-boundlist-selected"))me.allSelector.removeCls("x-boundlist-selected"),me.setValue(""),me.fireEvent("select",me,[]);else{var records=[];me.store.each(function(record){records.push(record)}),me.allSelector.addCls("x-boundlist-selected"),me.select(records),me.fireEvent("select",me,records)}}),1==me.allSelectorHidden?me.allSelector.hide():me.allSelector.show(),1==me.afterExpandCheck&&(me.allSelector.addCls("x-boundlist-selected"),me.afterExpandCheck=!1)),me.mon(Ext.getDoc(),{mousewheel:collapseIf,mousedown:collapseIf,scope:me}),Ext.EventManager.onWindowResize(me.alignPicker,me),me.fireEvent("expand",me),me.onExpand())},alignPicker:function(){var me=this,picker=me.getPicker();if(me.callParent(),1==me.addAllSelector){var height=picker.getHeight();height=parseInt(height)+20,picker.setHeight(height),picker.getEl().setStyle("height",height+"px")}},onListSelectionChange:function(list,selectedRecords){var me=this,isMulti=me.multiSelect,hasRecords=selectedRecords.length>0;!me.ignoreSelection&&me.isExpanded&&(isMulti||Ext.defer(me.collapse,1,me),(isMulti||hasRecords)&&me.setValue(selectedRecords,!1),hasRecords&&me.fireEvent("select",me,selectedRecords),me.inputEl.focus(),1==me.addAllSelector&&0!=me.allSelector&&(selectedRecords.length==me.store.getTotalCount()?me.allSelector.addCls("x-boundlist-selected"):me.allSelector.removeCls("x-boundlist-selected")))}});
                function LineFitter(){this.count=0,this.sumX=0,this.sumX2=0,this.sumXY=0,this.sumY=0}function linearProject(data,x){for(var fitter=new LineFitter,i=0;data.length>i;i++)fitter.add(i,data[i]);return fitter.project(x)}function projectToZero(data,x){for(var start=x;linearProject(data,start)>0;)start+=1;return start}LineFitter.prototype={add:function(x,y){this.count++,this.sumX+=x,this.sumX2+=x*x,this.sumXY+=x*y,this.sumY+=y},project:function(x){var det=this.count*this.sumX2-this.sumX*this.sumX,offset=(this.sumX2*this.sumY-this.sumX*this.sumXY)/det,scale=(this.count*this.sumXY-this.sumX*this.sumY)/det;return offset+x*scale}};

            Rally.launchApp('CustomApp', {
                name:"psi-feature-burnup",
	            parentRepos:""
            });

        });
    </script>


    <style type="text/css">
        .app {
     /* Add app styles here */
}

/* check combo */ 
.x-combo-checker { background-position: 50% -2px; margin-left: 1px; background-color: transparent; background-image: url("https://rally1.rallydev.com/apps/2.0rc1/lib/ext/4.1.1a/resources/themes/images/default/grid/unchecked.gif"); background-position: -1px -1px; background-repeat: no-repeat; height: 14px; width: 14px; display: inline-block; } <commit_msg>handle more than 200 releases<commit_after><!DOCTYPE html>
<html>
<head>
    <title>psi-feature-burnup</title>

    <script type="text/javascript" src="/apps/2.0rc1/sdk.js"></script>

    <script type="text/javascript">
        Rally.onReady(function () {
                var peRecords=[],acceptedData=[];Ext.define("MyBurnCalculator",{extend:"Rally.data.lookback.calculator.TimeSeriesCalculator",getMetrics:function(){var metrics=[{field:"LeafStoryPlanEstimateTotal",as:"Planned Points",display:"line",f:"sum"},{field:"CalcPreliminaryEstimate",as:"PreliminaryEstimate",display:"line",f:"sum"},{field:"AcceptedLeafStoryPlanEstimateTotal",as:"Accepted Points",display:"line",f:"sum"},{field:"ObjectID",as:"Count",display:"column",f:"count"},{field:"Completed",as:"Completed",display:"column",f:"sum"}];return metrics},getDerivedFieldsOnInput:function(){return[{as:"CalcPreliminaryEstimate",f:function(row){var r=_.find(peRecords,function(rec){return rec.get("ObjectID")==row.PreliminaryEstimate});return void 0!=r?r.get("Value"):0}},{as:"Completed",f:function(row){return 1==row.PercentDoneByStoryCount?1:0}}]},getDerivedFieldsAfterSummary:function(){return[{as:"Projection",f:function(row,index,summaryMetrics,seriesData){if(0==index){datesData=_.pluck(seriesData,"label"),acceptedData=_.pluck(seriesData,"Accepted Points"),console.log("accepted date len",acceptedData.length);var today=new Date;acceptedData=_.filter(acceptedData,function(d,i){return today>new Date(Date.parse(datesData[i]))})}var y=linearProject(acceptedData,index);return Math.round(100*y)/100}}]},defined:function(v){return!_.isUndefined(v)&&!_.isNull(v)}}),Ext.define("CustomApp",{scopeType:"release",extend:"Rally.app.App",componentCls:"app",launch:function(){console.log("launch");var timeboxScope=this.getContext().getTimeboxScope(),tbName=null;if(timeboxScope){var record=timeboxScope.getRecord();tbName=record.get("Name")}else tbName="";var peStore=Ext.create("Rally.data.WsapiDataStore",{autoLoad:!0,model:"PreliminaryEstimate",fetch:["Name","ObjectID","Value"],filters:[],listeners:{scope:this,load:function(store,data){peRecords=data,this.queryReleases(tbName)}}})},queryReleases:function(name){var releaseStore;return releaseStore=Ext.create("Rally.data.WsapiDataStore",{autoLoad:!0,model:"Release",limit:"Infinity",fetch:["Name","ObjectID","Project","ReleaseStartDate","ReleaseDate"],filters:[],listeners:{load:function(store,releaseRecords){var releases=_.map(releaseRecords,function(rec){return{name:rec.get("Name"),objectid:rec.get("ObjectID"),releaseDate:new Date(Date.parse(rec.get("ReleaseDate")))}});releases=_.sortBy(releases,function(rec){return rec.releaseDate}).reverse(),releases=_.uniq(releases,function(r){return r.name});var releasesStore=Ext.create("Ext.data.Store",{fields:["name","objectid"],data:releases}),cb=Ext.create("Ext.ux.CheckCombo",{fieldLabel:"Release",store:releasesStore,queryMode:"local",displayField:"name",valueField:"name",noData:!0,width:300,listeners:{scope:this,collapse:function(field,eOpts){var releases=[];_.each(field.getValue().split(","),function(rn){_.each(_.filter(releaseRecords,function(r){return rn==r.get("Name")}),function(rel){releases.push(rel)})}),this.querySnapshots(releases)}}});this.add(cb)},scope:this}})},querySnapshots:function(releases){var ids=_.pluck(releases,function(release){return release.get("ObjectID")});this.chartConfig.storeConfig.find.Release={$in:ids};var start=_.min(_.pluck(releases,function(r){return r.get("ReleaseStartDate")})),end=_.max(_.pluck(releases,function(r){return r.get("ReleaseDate")}));console.log("start",start),console.log("end",end),this.chartConfig.calculatorConfig.startDate=start,this.chartConfig.calculatorConfig.endDate=end;var chart=this.down("#myChart");null!=chart&&this.remove(chart),console.log(this.chartConfig),this.add(this.chartConfig)},chartConfig:{xtype:"rallychart",itemId:"myChart",chartColors:["Gray","Orange","Green","Blue","Green","LightGray"],storeConfig:{find:{_TypeHierarchy:{$in:["PortfolioItem/Feature"]}},autoLoad:!0,limit:1/0,fetch:["ObjectID","Name","_TypeHierarchy","PreliminaryEstimate","LeafStoryPlanEstimateTotal","AcceptedLeafStoryPlanEstimateTotal","PercentDoneByStoryCount"],hydrate:["_TypeHierarchy","PreliminaryEstimate"]},calculatorType:"MyBurnCalculator",calculatorConfig:{},chartConfig:{plotOptions:{series:{marker:{radius:2}}},chart:{colors:[],zoomType:"xy"},title:{text:"Feature Burnup"},xAxis:{tickInterval:7,labels:{formatter:function(){var d=new Date(this.value);return""+(d.getMonth()+1)+"/"+d.getDate()}},title:{text:"Days"}},yAxis:[{title:{text:"Points"}}]}}});
                Ext.define("Ext.ux.CheckCombo",{extend:"Ext.form.field.ComboBox",alias:"widget.checkcombo",multiSelect:!0,allSelector:!1,noData:!1,noDataText:"No combo data",addAllSelector:!1,allSelectorHidden:!1,enableKeyEvents:!0,afterExpandCheck:!1,allText:"All",oldValue:"",listeners:{focus:function(cpt){cpt.oldValue=cpt.getValue()},keydown:function(cpt,e,eOpts){var value=cpt.getRawValue(),oldValue=cpt.oldValue;value!=oldValue&&cpt.setValue("")}},createPicker:function(){var me=this,picker,menuCls=Ext.baseCSSPrefix+"menu",opts=Ext.apply({pickerField:me,selModel:{mode:me.multiSelect?"SIMPLE":"SINGLE"},floating:!0,hidden:!0,ownerCt:me.ownerCt,cls:me.el.up("."+menuCls)?menuCls:"",store:me.store,displayField:me.displayField,focusOnToFront:!1,pageSize:me.pageSize,tpl:['<ul><tpl for=".">','<li role="option" class="'+Ext.baseCSSPrefix+'boundlist-item"><span class="x-combo-checker">&nbsp;</span> {'+me.displayField+"}</li>","</tpl></ul>"]},me.listConfig,me.defaultListConfig);return picker=me.picker=Ext.create("Ext.view.BoundList",opts),me.pageSize&&picker.pagingToolbar.on("beforechange",me.onPageChange,me),me.mon(picker,{itemclick:me.onItemClick,refresh:me.onListRefresh,scope:me}),me.mon(picker.getSelectionModel(),{beforeselect:me.onBeforeSelect,beforedeselect:me.onBeforeDeselect,selectionchange:me.onListSelectionChange,scope:me}),me.store.on("load",function(store){0==store.getTotalCount()?(me.allSelectorHidden=!0,0!=me.allSelector&&me.allSelector.setStyle("display","none"),0!=me.noData&&me.noData.setStyle("display","block")):(me.allSelectorHidden=!1,0!=me.allSelector&&me.allSelector.setStyle("display","block"),0!=me.noData&&me.noData.setStyle("display","none"))}),picker},reset:function(){var me=this;me.setValue("")},setValue:function(value){if(this.value=value,!value)return 0!=this.allSelector&&this.allSelector.removeCls("x-boundlist-selected"),this.callParent(arguments);if("string"==typeof value){var me=this,records=[],vals=value.split(",");return""==value?0!=me.allSelector&&me.allSelector.removeCls("x-boundlist-selected"):vals.length==me.store.getCount()&&0!=vals.length&&(0!=me.allSelector?me.allSelector.addCls("x-boundlist-selected"):me.afterExpandCheck=!0),Ext.each(vals,function(val){var record=me.store.getById(parseInt(val));record&&records.push(record)}),me.setValue(records)}return this.callParent(arguments)},getValue:function(){return"object"==typeof this.value?this.value.join(","):this.value},getSubmitValue:function(){return this.getValue()},expand:function(){var me=this,bodyEl,picker,collapseIf;!me.rendered||me.isExpanded||me.isDestroyed?(me.fireEvent("expand",me),me.onExpand()):(bodyEl=me.bodyEl,picker=me.getPicker(),collapseIf=me.collapseIf,picker.show(),me.isExpanded=!0,me.alignPicker(),bodyEl.addCls(me.openCls),0==me.noData&&(me.noData=picker.getEl().down(".x-boundlist-list-ct").insertHtml("beforeBegin",'<div class="x-boundlist-item" role="option">'+me.noDataText+"</div>",!0)),1==me.addAllSelector&&0==me.allSelector&&(me.allSelector=picker.getEl().down(".x-boundlist-list-ct").insertHtml("beforeBegin",'<div class="x-boundlist-item" role="option"><span class="x-combo-checker">&nbsp;</span> '+me.allText+"</div>",!0),me.allSelector.on("click",function(e){if(me.allSelector.hasCls("x-boundlist-selected"))me.allSelector.removeCls("x-boundlist-selected"),me.setValue(""),me.fireEvent("select",me,[]);else{var records=[];me.store.each(function(record){records.push(record)}),me.allSelector.addCls("x-boundlist-selected"),me.select(records),me.fireEvent("select",me,records)}}),1==me.allSelectorHidden?me.allSelector.hide():me.allSelector.show(),1==me.afterExpandCheck&&(me.allSelector.addCls("x-boundlist-selected"),me.afterExpandCheck=!1)),me.mon(Ext.getDoc(),{mousewheel:collapseIf,mousedown:collapseIf,scope:me}),Ext.EventManager.onWindowResize(me.alignPicker,me),me.fireEvent("expand",me),me.onExpand())},alignPicker:function(){var me=this,picker=me.getPicker();if(me.callParent(),1==me.addAllSelector){var height=picker.getHeight();height=parseInt(height)+20,picker.setHeight(height),picker.getEl().setStyle("height",height+"px")}},onListSelectionChange:function(list,selectedRecords){var me=this,isMulti=me.multiSelect,hasRecords=selectedRecords.length>0;!me.ignoreSelection&&me.isExpanded&&(isMulti||Ext.defer(me.collapse,1,me),(isMulti||hasRecords)&&me.setValue(selectedRecords,!1),hasRecords&&me.fireEvent("select",me,selectedRecords),me.inputEl.focus(),1==me.addAllSelector&&0!=me.allSelector&&(selectedRecords.length==me.store.getTotalCount()?me.allSelector.addCls("x-boundlist-selected"):me.allSelector.removeCls("x-boundlist-selected")))}});
                function LineFitter(){this.count=0,this.sumX=0,this.sumX2=0,this.sumXY=0,this.sumY=0}function linearProject(data,x){for(var fitter=new LineFitter,i=0;data.length>i;i++)fitter.add(i,data[i]);return fitter.project(x)}function projectToZero(data,x){for(var start=x;linearProject(data,start)>0;)start+=1;return start}LineFitter.prototype={add:function(x,y){this.count++,this.sumX+=x,this.sumX2+=x*x,this.sumXY+=x*y,this.sumY+=y},project:function(x){var det=this.count*this.sumX2-this.sumX*this.sumX,offset=(this.sumX2*this.sumY-this.sumX*this.sumXY)/det,scale=(this.count*this.sumXY-this.sumX*this.sumY)/det;return offset+x*scale}};

            Rally.launchApp('CustomApp', {
                name:"psi-feature-burnup",
	            parentRepos:""
            });

        });
    </script>


    <style type="text/css">
        .app {
     /* Add app styles here */
}

/* check combo */ 
.x-combo-checker { background-position: 50% -2px; margin-left: 1px; background-color: transparent; background-image: url("https://rally1.rallydev.com/apps/2.0rc1/lib/ext/4.1.1a/resources/themes/images/default/grid/unchecked.gif"); background-position: -1px -1px; background-repeat: no-repeat; height: 14px; width: 14px; display: inline-block; } 
{'fraction_non_alphanumeric': 0.21574105293579307, 'fraction_numerical': 0.00900727325273349, 'mean_word_length': 14.02315484804631, 'pattern_counts': {'":': 2, '<': 51, '<?xml version=': 0, '>': 59, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2705589', 'n_tokens_mistral': 7066, 'n_tokens_neox': 6929, 'n_words': 260}