ExtJS4.2 carousel not working with ExtJS5 - extjs

I have a requirement to use carousel in one of my project. Recently we migrated from ExtJS4.2.1 to ExtJS5 The example shown here is working absolutely fine with ExtJS4.2.1 but when I use it with ExtJS5 it gives the error: "Ext.util.Observable#addEvents" is deprecated."
Can someone update the code or point out the error? Here is the code:
Ext.onReady(function () {
Ext.define('carouselContainer', {
extend: 'Ext.container.Container'
, alias: 'widget.carousel'
, layout: {
type: 'hbox'
, align: 'stretch'
}
, defaults: { flex: 1 }
, style: {
background: 'url(http://3.bp.blogspot.com/-kanvyoXSOSs/Tsi0W496bzI/AAAAAAAAAG8/-Bq53wJqaqM/s320/carbonfibre.png)'
}
, initComponent: function () {
var me = this;
me.addEvents('carouselchange');
me.callParent(arguments);
}
, onDocMouseup: function () {
var me = this;
me.drag = false;
var children = me.items.items;
var parentLeft = me.ownerCt.el.getLeft();
var rule = 1000000;
var target;
Ext.each(children, function (div, i) {
l = Math.abs(div.el.getLeft() - parentLeft);
if (l < rule) {
rule = l;
target = div;
};
});
me.showChild(target);
}
, onMousedown: function (e) {
e.stopEvent(); // prevents selecting the underlying text and whatnot
var me = this;
me.drag = true;
me.startX = e.getX();
var par = me.el.first();
par.on({
mousemove: function (e) {
e.stopEvent(); // prevents selecting the underlying text and whatnot
if (me.drag) {
var rate = 1;
if (par.getLeft() > me.ownerCt.el.getLeft() || par.getRight() < me.ownerCt.el.getRight()) {
rate = 2;
}
par.move('l', (me.startX - e.getX()) / rate, false);
me.startX = e.getX();
}
}
});
}
, syncSizeToOwner: function () {
var me = this;
if (me.ownerCt) {
me.setSize(me.ownerCt.el.getWidth() * me.items.items.length, me.ownerCt.el.getHeight());
}
}
, showChild: function (item) {
var me = this
, left = item.el.getLeft() - me.el.getLeft();
me.el.first().move('l', left, true);
me.currentItem = item;
me.fireEvent('carouselchange', me, item);
}
, nextChild: function () {
var me = this;
var next = me.currentItem.nextSibling();
me.showChild(next || me.items.items[0]);
}
, previousChild: function () {
var me = this;
var next = me.currentItem.previousSibling();
me.showChild(next || me.items.items[me.items.items.length - 1]);
}
, onRender: function () {
var me = this;
me.currentItem = me.items.items[0];
if (me.ownerCt) {
me.relayEvents(me.ownerCt, ['resize'], 'owner');
me.on({
ownerresize: me.syncSizeToOwner
});
}
me.mon(Ext.getBody(), 'mouseup', me.onDocMouseup, me);
me.mon(Ext.fly(me.el.dom), 'mousedown', me.onMousedown, me);
me.callParent(arguments);
}
});
Ext.define('carouselTb', {
extend: 'Ext.toolbar.Toolbar'
, alias: 'widget.carouseltb'
, directionals: true
, initComponent: function () {
var me = this;
me.items = [{
xtype: 'tbfill'
}, {
xtype: 'tbfill'
}]
me.callParent(arguments);
}
, handleCarouselEvents: function (carousel) {
var me = this;
me.relayEvents(carousel, ['carouselchange']);
me.on('carouselchange', me.onCarouselChange, me, {buffer: 20});
}
, onCarouselChange: function (carousel, item) {
var me = this;
console.log(me);
var navSprites = me.down('draw').surface.getGroup('carousel');
navSprites.setAttributes({opacity: 0.2}, true);
var i = carousel.items.indexOf(item);
navSprites.each(function (s) {
if (s.index == i) {
s.animate({
to: {
opacity: 0.7
}
});
}
});
}
, onRender: function () {
var me = this;
var prev = {
text: '<'
, handler: function () {
me.ownerCt.down('carousel').previousChild();
}
};
var next = {
text: '>'
, handler: function () {
me.ownerCt.down('carousel').nextChild();
}
};
Ext.suspendLayouts();
if (me.directionals) {
me.insert(0, prev);
me.insert(me.items.items.length, next);
}
var index = me.items.indexOf(me.down('tbfill'));
var circles = [];
var x = 0;
var i = 0;
Ext.each(me.ownerCt.down('carousel').items.items, function (item) {
var config = {
type: 'circle'
, x: x
, y: 0
, index: i
, radius: 1
, fill: 'black'
, opacity: i == 0 ? 0.7 : 0.2
, group: 'carousel'
}
circles.push(config);
x += 3;
i++;
});
me.insert(index + 1, {
xtype: 'draw'
, height: 12
, items: circles
});
Ext.resumeLayouts();
Ext.defer(function () {
var c = me.down('draw').surface.getGroup('carousel');
c.each(function (s) {
s.on({
click: function (s) {
c.setAttributes({opacity: 0.2}, true);
var carousel = me.ownerCt.down('carousel');
carousel.showChild(carousel.items.items[s.index]);
}
});
});
}, 2);
var carousel = me.ownerCt.down('carousel');
if (carousel) {
me.handleCarouselEvents(carousel);
}
me.callParent(arguments);
}
});
Ext.widget('viewport', {
layout: 'fit'
, items: [{
xtype: 'panel'
, items: [{
xtype: 'carousel'
, items: [{
xtype: 'panel'
, title: '1'
, html: 'testing'
}, {
xtype: 'gridpanel'
, title: '2'
, columns: [{
text: 'Label'
, dataIndex: 'label'
}]
, store: {
fields: ['label']
, data: [{
label: 'a'
}, {
label: 'b'
}, {
label: 'c'
}, {
label: 'd'
}, {
label: 'e'
}, {
label: 'f'
}, {
label: 'g'
}, {
label: 'h'
}, {
label: 'i'
}, {
label: 'j'
}, {
label: 'k'
}, {
label: 'l'
}, {
label: 'm'
}, {
label: 'n'
}, {
label: 'o'
}, {
label: 'p'
}, {
label: 'q'
}, {
label: 'r'
}, {
label: 's'
}, {
label: 't'
}, {
label: 'u'
}, {
label: 'v'
}, {
label: 'w'
}, {
label: 'x'
}, {
label: 'y'
}, {
label: 'z'
}, {
label: 'a'
}, {
label: 'b'
}, {
label: 'c'
}, {
label: 'd'
}, {
label: 'e'
}, {
label: 'f'
}, {
label: 'g'
}, {
label: 'h'
}, {
label: 'i'
}, {
label: 'j'
}, {
label: 'k'
}, {
label: 'l'
}, {
label: 'm'
}, {
label: 'n'
}, {
label: 'o'
}, {
label: 'p'
}, {
label: 'q'
}, {
label: 'r'
}, {
label: 's'
}, {
label: 't'
}, {
label: 'u'
}, {
label: 'v'
}, {
label: 'w'
}, {
label: 'x'
}, {
label: 'y'
}, {
label: 'z'
}]
}
}, {
xtype: 'panel'
, title: '3'
, html: 'One last panel'
}]
}]
, dockedItems: [{
xtype: 'carouseltb'
, dock: 'top'
}]
}]
});
});

Remove this line:
me.addEvents('carouselchange');
addEvents has been deprecated in Ext JS 5.0 and will raise an error when used. Don't use it.

Related

How to drilldown to third level when its data is determined by second's click event?

So, I have been trying to use drill down to multiple levels, problem I am facing is that I couldn't drill down to the third level because the data will be fetched by ajax upon second drilldown's selection.
for example, refer to this link:
https://codepen.io/ajaymalhotra15/pen/aZpxXq
drilldown example
Here, the third level is possible because he has the data already, but mine will be depended on seconds selection.
So, how to make this happen, where am I supposed to call the ajax request and set the drill down series data dynamically?
EDIT:
Highcharts.chart("energy_chart", {
chart: {
type: "column",
spacingBottom: 15,
spacingTop: 10,
spacingLeft: 10,
spacingRight: 10,
backgroundColor: "#f2f2f2",
events: {
load: function() {
var fin = new Date();
var finDate = fin.getDate();
var finMonth = fin.getMonth();
var finYear = fin.getFullYear();
var ini = new Date();
ini.setFullYear(ini.getFullYear() - 1);
var iniDate = ini.getDate();
var iniMonth = ini.getMonth();
var iniYear = ini.getFullYear();
if (this.yAxis[0].dataMax == 0) {
this.yAxis[0].setExtremes(null, 1);
}
//this.yAxis.set
this.xAxis[0].setExtremes(
Date.UTC(iniYear, iniMonth, iniDate),
Date.UTC(finYear, finMonth, finDate)
);
},
drilldown: function(e) {
var charts_this = this;
var inidrillDate = new Date(e.point.x);
setTimeout(function() {
inidrillDate.setDate(0);
inidrillDate.setMonth(inidrillDate.getMonth());
var DateinidrillDate = inidrillDate.getDate();
var MonthinidrillDate = inidrillDate.getMonth();
var YearinidrillDate = inidrillDate.getFullYear();
var findrillDate = inidrillDate;
findrillDate.setMonth(findrillDate.getMonth() + 1);
findrillDate.setDate(findrillDate.getDate() - 1);
var DatefindrillDate = findrillDate.getDate();
var MonthfindrillDate = findrillDate.getMonth();
var YearfindrillDate = findrillDate.getFullYear();
charts_this.xAxis[0].setExtremes(
Date.UTC(
YearinidrillDate,
MonthinidrillDate,
DateinidrillDate
),
Date.UTC(
YearfindrillDate,
MonthfindrillDate,
DatefindrillDate
)
);
if (charts_this.yAxis[0].dataMax === 0) {
charts_this.yAxis[0].setExtremes(null, 1);
}
}, 0);
}
}
},
title: {
text: '<p className="energy_gen">Energy Generated</p>'
},
exporting: { enabled: false },
xAxis: {
type: "datetime",
labels: {
step: 1
},
dateTimeLabelFormats: {
day: "%e"
}
},
yAxis: {
title: {
text: "kWh"
}
},
credits: {
enabled: false
},
plotOptions: {
series: {
cursor: "pointer",
dataLabels: {
enabled: true,
format: "{point.y}"
},
color: "#fcd562",
point:{
events:{
click:function(event){
if(this.options!=null){
var dayOfYear=new Date(this.x).getFullYear() +"-"+(new Date(this.x).getMonth()+1)+"-"+new Date(this.x).getDate();
var formatted_date = new Date(this.x).getDate() + " " + months[(new Date(this.x).getMonth())] +" "+ new Date(this.x).getFullYear();
// document.getElementById('chart_date_id').innerHTML = formatted_date; //setting modal title with current date
$('#container').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
var sync_charts = $('.chart');
for (i = 0; i < sync_charts.length; i = i + 1) {
var chart_1 = sync_charts[i];
var chart_2 = chart_1.getAttribute('data-highcharts-chart');
chart=Highcharts.charts[chart_2];
event = chart.pointer.normalize(e.originalEvent);
point = chart.series[0].searchPoint(event, true);
if (point) {
point.highlight(e);
}
}
});
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
Highcharts.Point.prototype.highlight = function (event) {
event = this.series.chart.pointer.normalize(event);
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function (chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(
e.min,
e.max,
undefined,
false,
{ trigger: 'syncExtremes' }
);
}
}
});
}
}
axios({
url: config.fvcstat,
method: "POST",
data: {
"customerId":self.props.location.state.detail.customerId,"rmsVendorId":self.props.location.state.detail.rmsVendorId,
"date":dayOfYear,
"powerType":self.props.location.state.detail.powerType
},
headers: {
"Content-Type": "application/json"
}
}).then((res)=>{
let activity = fvc.data;
if($('.chart')){
$('.chart').remove();
}
$.each(activity.datasets, function (i, dataset) {
console.log(1)
var chartDiv = document.createElement('div');
chartDiv.className = 'chart';
document.getElementById('container').appendChild(chartDiv);
Highcharts.chart(chartDiv,{
chart: {
},
plotOptions: {
series: {
marker:{
enabled:false
}
}
},
exporting: { enabled: false },
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
crosshair:{ width: 3},
events: {
setExtremes: syncExtremes
},
labels: {
format: '{value}'
},categories: activity.xData
},
yAxis: {
title: {
text: null
}
},
series: [{
data: dataset
}],
tooltip: {
positioner: function () {
return {
x: this.chart.chartWidth - this.label.width,
y: 10 // align to title
};
},
borderWidth: 0,
backgroundColor: 'none',
pointFormat: '{point.y}',
headerFormat: '',
shadow: false,
style: {
fontSize: '18px'
},
valueDecimals: dataset.valueDecimals
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
})
}
}
}
}
}
},
tooltip: {
formatter: function() {
if (this.point.options.drilldown) {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%b %Y", new Date(this.x))
);
} else {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%e %b %Y", new Date(this.x))
);
}
}
},
series: [{'data':obj.data,'name':obj.name,"color":"#4848d3"}],
drilldown: {
series: obj.data
}
});
So, here if you notice in plotoptions i am trying to create a whole new chart which is a synced line charts showing frquency, voltage and current.
But, i am guessing my approach is not correct as i am plotting a new highchart.
So, how do i make this synced line chart part of my drilldown.
let me know if you require any help in understanding.
I will suggest first minimize the plotoption. Then expand for further fuck up :P
Thanks.
You can put all your logic to get the third level data and to create a drilldown series in drilldown event:
chart: {
type: 'column',
events: {
drilldown: function(e) {
if (!thirdLevel.length) {
// get data
}
if (!e.seriesOptions) {
var chart = this,
drilldowns = {
'Animals': {
name: 'Animals',
data: [
['Cows', 2],
['Sheep', 3]
]
},
'Fruits': {
name: 'Fruits',
data: [
['Apples', 5],
['Oranges', 7],
['Bananas', 2]
]
},
'Cars': {
name: 'Cars',
data: [
['Toyota', 1],
['Volkswagen', 2],
['Opel', 5]
]
}
},
series = drilldowns[e.point.name];
chart.addSingleSeriesAsDrilldown(e.point, series);
chart.applyDrilldown();
}
}
}
}
Live demo : http://jsfiddle.net/BlackLabel/86v3L4ft/
API Reference: https://api.highcharts.com/highcharts/chart.events.drilldown

why add newRecord[] is empty

I have a problem when adding a newRecord, the console always outputs [].
Please help me.
_storePR2.add(_key.data);
_storePR2.commitChanges();
var newRecord = _storePR2.getNewRecords();
console.log('newRecord',newRecord);
Output: newRecord []
enter image description here
this my store code and model :
Ext.define('Sasmita.store.vending.purchase.Purchasegoodrec', {
extend: 'Ext.data.Store',
requires: [
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json',
'Ext.data.Field'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
storeId: 'vending.purchase.Purchasegoodrec',
proxy: {
type: 'ajax',
url: 'jsonresult/Sasmita_Vending_Purchase/getPurchaseGoodrec',
reader: {
type: 'json',
root: 'data',
idProperty: 'sitecode2'
}
},
fields: [
{
name: 'purchase_id_tr'
},
{
name: 'parent_id'
},
{
name: 'file_ext'
},
{
name: 'file_name'
},
{
name: 'file_size'
},
{
name: 'description'
},
{
name: 'id'
},
{
name: 'id_file'
},
{
name: 'id_po'
},
{
name: 'qty_hasil'
},
{
name: 'no_pr'
},
{
dateFormat: 'Ymd',
name: 'date_pr',
type: 'date'
},
{
name: 'warehouse'
},
{
name: 'warehouse_name'
},
{
name: 'row_created_by'
},
{
name: 'row_created_datetime'
},
{
name: 'row_changed_by'
},
{
name: 'row_changed_datetime'
},
{
name: 'title'
},
{
name: 'notes'
},
{
name: 'qty_order'
},
{
name: 'no_po'
},
{
name: 'date_po'
},
{
name: 'supplier'
},
{
name: 'package'
},
{
name: 'qty_approve'
},
{
name: 'purchase_product_name'
},
{
name: 'unit'
},
{
name: 'unit_price'
},
{
name: 'total_price'
},
{
name: 'total_price_head'
},
{
name: 'vat'
},
{
name: 'net_price'
},
{
name: 'sum_total'
}
]
}, cfg)]);
}
});
and this my controller action button choose :
var me = this;
var _panel = me.getMainPanel();
var _tabpanel = _panel.down('#tabmaintain');
var _activetab = _tabpanel.getActiveTab();
var _window = button.up('window');
var _grid = _window.down('grid');
//var _girdd = this.getPanelSearch();
//var _grids = _girdd.down('grid');
var _gridSelected = _grid.getSelectionModel().getSelection();
//var row = _grid.store.indexOf(_gridSelected);
//console.log(row);
console.log(_gridSelected);
console.log(_grid);
//console.log(_girdd.down('grid'));
//selected=[];
//Check selected product
if(_gridSelected.length===0){
Ext.Msg.alert('Warning','Please select product');
return;
}
//Submit Product
var _gridPR = _activetab.down('#detailProduct');
var _storePR2 = _gridPR.getStore();
//console.log(_storePR2.data);
Ext.Array.each(_gridSelected,function(_key,_value,item){
//console.log(selected.push(item));
_validate = true;
_storePR2.each(function(_storeData,_storeIndex){
console.log(_key.data);
if(_storeData.data.no_po === _key.data.no_po){
_validate = false;
Ext.Msg.alert('Warning','The Product had been picked');
return;
}
});
if(_validate){
// Add record to the store by data
_storePR2.add(_key.data);
// Get array of new records from the store
var newRecords = _storePR2.getNewRecords();
console.log('newRecord',newRecords);
// Commit changes after getting new records
_storePR2.commitChanges();
_window.close();
}
});
That is because you committed the changes, so there are no longer any 'new records'.
Try to get the new records before committing the changes:
// Add record to the store by data
_storePR2.add(_key.data);
// Get array of new records from the store
var newRecords = _storePR2.getNewRecords();
console.log('newRecord',newRecords);
// Commit changes after getting new records
_storePR2.commitChanges();
Here is a fiddle.
First you need to add records to store and commit changes,then get new records.
grid_store.add({'Name':"ab",'dob':"099"})
grid_store.commitChanges();
var newRecord = grid_store.getNewRecords()
console.log('newRecord',newRecord);
});
Here is a fiddle: http://jsfiddle.net/2p78md5t/3/

Highcharts: Stacked Bar Chart

I have 2 doubts in following graph:
First: my x axis is skipping one label
Second: I want my Feb data bar to start from Feb15 (and so on for all the months), as you can see it is starting from Jan15 currently.
Following is my code:
chartType.strikeRateFrquency=function(chartObject){
return{
chart: {
type: 'bar',
renderTo: chartObject.element,
inverted:false,
//rotation:'180',
width:550
},
title: {
text: ''
},
credits:{
enabled:false
},
xAxis: [
{
tickInterval : 1,
gridLineColor: 'transparent',
lineColor:'transparent',
tickColor:'transparent',
labels: {
formatter: function() {
var value = chartObject.cumalative[this.value] ;
//console.log(value);
return value !== 'undefined' ? value : this.value ;
}
},
title: {
align:'high',
text: 'Cumalative'+'<br>'+ 'Score S/R',
rotation:0,
x:-10,
y:-20
},
},
{
tickInterval : 1,
gridLineColor: 'transparent',
lineColor:'transparent',
tickColor:'transparent',
labels: {
formatter: function() {
var value = chartObject.monthsx[this.value];
//console.log(value);
return value !== 'undefined' ? value : this.value;
}
},
}
],
yAxis: [{
//reversed:true,
opposite:true,
max:72,
min:0,
gridLineColor: 'transparent',
tickInterval: 12,
title:{
text:''
},
labels: {
formatter: function() {
var value = chartObject.monthsy[this.value];
return value !== 'undefined' ? value : this.value;
}
},
}],
plotOptions: {
series: {
stacking: 'normal',
}
},
legend:{
enabled:false
},
series: [{
xAxis:1,
name: 'Quarter 2',
data: [35, 15, 35, 11, 2,10],
}, {
name: 'Quarter 1',
data: [25,15,20,10,15,22],
}]
}
}
Directive code:
function strikeRateFrequency($rootScope, chartTypesFactory) {
return {
restrict: "EA",
scope: {
graphData: '='
},
template: '<div></div>',
link: function (scope, element, attrs) {
scope.$watch('graphData', function () {
var chartoptions = {};
chartoptions.element = element[0];
chartoptions.monthsy={
0: 'Jan15',
12: 'Feb15',
24: 'Mar15',
36: 'Apr15',
48: 'May15',
60: 'Jun15'}
chartoptions.monthsx={
0: 'Jan15',
1: 'Feb15',
2: 'Mar15',
3: 'Apr15',
4: 'May15',
5: 'Jun15'}
chartoptions.cumalative=['10%','30%','40%','25%','60%','43%'];
var chart = new Highcharts.Chart(chartTypesFactory.strikeRateFrquency(chartoptions));
});
}
}
}

I wrote CardBoard Rally sdk 2 app to which I added filter but I want to add two different filter, one for releases and one for backlog

I wrote CardBoard Rally sdk 2 app to which I added filter which apply to Backlog and Releases too. But I want to add two different filters, one for releases and one for backlog
See in image attached, u can see one column for Backlog and other for releases
So I should be able to say Now filter Backlog features, and Now filter Releases features
Below is my some of code snippet
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
autoScroll: true,
all_releases: [],
items:[{ xtype: 'container', itemId: 'filter_box', padding: 5},{xtype:'container',itemId:'button_box', padding: 5}],
logger: new Rally.technicalservices.logger(),
launch: function() {
//var allReleases = this._getReleases();
this._drawCardBoard(this, filters= null);
this.down('#button_box').add({
xtype: 'rallybutton',
text: 'Filter Criteria',
itemId: 'run-button',
scope: this,
handler: this._run,
margin: '0 0 0 10'
});
this.down('#button_box').add({
xtype: 'rallybutton',
text: 'Prev',
itemId: 'prev-button',
scope: this,
handler: this._setPrevReleaseDate,
margin: '0 0 0 100'
});
this.down('#button_box').add({
xtype: 'rallybutton',
text: 'Next',
itemId: 'next-button',
scope: this,
handler: this._setNextReleaseDate,
margin: '0 0 0 650'
});
},
_setPrevReleaseDate: function() {
if (this.globalVar == undefined) {
this.globalVar = new Date();
} else {
this.globalVar = new Date(this.globalVar);
};
this.globalVar = Rally.util.DateTime.formatWithDefault(Ext.Date.subtract(this.globalVar, Ext.Date.DAY, 224));
this._drawCardBoard(this, filters= null);
},
_setNextReleaseDate: function() {
if (this.globalVar == undefined) {
this.globalVar = new Date();
} else {
this.globalVar = new Date(this.globalVar);
};
this.globalVar = Rally.util.DateTime.formatWithDefault(Ext.Date.add(this.globalVar, Ext.Date.DAY, 224));
this._drawCardBoard(this, filters= null);
},
_getFilters: function(records) {
var filters = null;
if (records.length >= 1) {
if (records[0].data.PortfolioItemTypeName == "MMF") {
filters = Ext.create('Rally.data.QueryFilter',{
property: 'Parent',
operator: '=',
value: records[0].get("_ref")
});
} else if (records[0].data.PortfolioItemTypeName == "Epic") {
filters = Ext.create('Rally.data.QueryFilter',{
property: 'Parent.Parent',
operator: '=',
value: records[0].get("_ref")
});
} else if (records[0].data.PortfolioItemTypeName == "Program") {
filters = Ext.create('Rally.data.QueryFilter',{
property: 'Parent.Parent.Parent',
operator: '=',
value: records[0].get("_ref")
});
}
for ( var i=1;i<records.length;i++ ) {
if (records[i].data.PortfolioItemTypeName == "MMF") {
filters = filters.or(Ext.create('Rally.data.QueryFilter',{
property: 'Parent',
operator: '=',
value: records[i].get("_ref")
}));
} else if (records[i].data.PortfolioItemTypeName == "Epic") {
filters = filters.or(Ext.create('Rally.data.QueryFilter',{
property: 'Parent.Parent',
operator: '=',
value: records[i].get("_ref")
}));
} else if (records[i].data.PortfolioItemTypeName == "Program") {
filters = filters.or(Ext.create('Rally.data.QueryFilter',{
property: 'Parent.Parent.Parent',
operator: '=',
value: records[i].get("_ref")
}));
}
}
}
return filters;
},
_drawCardBoard: function(that, filters){
if (that.cardboard) {
that.cardboard.destroy();
};
var me = that;
if (filters == null) {
filters = [];
}
me.cardboard = Ext.create('Rally.ui.cardboard.CardBoard',{
types: ['PortfolioItem/Feature'],
attribute: 'Release',
config: {globalVar: this.globalVar},
columnConfig: {
xtype: 'rallycardboardcolumn',
displayField: 'Name',
valueField: '_ref',
plugins: [
{ptype:'rallycolumndropcontroller'},
{ptype:'rallycardboardcardrecordprocessor'},
{ptype:'tscolumnheaderupdater'} /*,
{ptype:'tscolumnheaderupdater', field_to_aggregate: 'LeafStoryPlanEstimateTotal'}*/
],
storeConfig: {
filters: filters,
context: this.getContext().getDataContext()
}
},
addColumn: function (columnConfig, index) {
console.log(columnConfig, index,"columnConfig, index");
var column = this._createColumnDefinition(columnConfig);
Ext.Array.insert(this.columnDefinitions, Ext.isNumber(index) ? index : this.columnDefinitions.length, [column]);
return column;
},
cardConfig: {
editable: true,
showIconsAndHighlightBorder: false,
showReadyIcon: true,
showBlockedIcon: true,
showColorIcon: true,
showPlusIcon: true,
showGearIcon: true,
fields: [
'FormattedID',
'Name',
'Parent',
'ReleaseDate',
'ReleaseStartDate',
{ name: 'Project', renderer: me._renderProject },
{ name: 'PercentDoneByStoryPlanEstimate' },
{ name: 'PreliminaryEstimate', fetch: ['PreliminaryEstimate', 'Name'], renderTpl: Ext.create('Ext.XTemplate', '{PreliminaryEstimate.Name}')},
{ name: 'LeafStoryPlanEstimateTotal', fetch: ['LeafStoryPlanEstimateTotal'], renderTpl: Ext.create('Ext.XTemplate', 'Plan Estimate Total: {LeafStoryPlanEstimateTotal}')}
],
},
listeners: {
beforeShow: this._onTeamMembersLoaded,
added: function(card,container){
//card.set('DisplayColor', "blue");
me.logger.log(this,card,container);
},
fieldClick: function(eOpts) {
me.logger.log(this,eOpts);
if ( eOpts == "PercentDoneByStoryPlanEstimate" ) {
me._showDoneTooltip(eOpts,this);
}
},
scope: this
}
});
_getLocalReleases: function(retrievedColumns, today_iso) {
var me = this;
if (today_iso == undefined) {
today_iso = Rally.util.DateTime.toIsoString(new Date(),false);
}
var filters = [{property:'ReleaseDate',operator:'>',value:today_iso}];
var iteration_names = [];
Ext.create('Rally.data.WsapiDataStore',{
model:me.attribute,
autoLoad: true,
filters: filters,
context: { projectScopeUp: false, projectScopeDown: false },
sorters: [
{
property: 'ReleaseDate',
direction: 'ASC'
}
],
//limit: Infinity,
pageSize: 4,
//buffered: true,
//purgePageCount: 4,
fetch: ['Name','ReleaseStartDate','ReleaseDate','PlannedVelocity'],
listeners: {
load: function(store,records) {
Ext.Array.each(records, function(record){
var start_date = Rally.util.DateTime.formatWithNoYearWithDefault(record.get('ReleaseStartDate'));
var end_date = Rally.util.DateTime.formatWithNoYearWithDefault(record.get('ReleaseDate'));
iteration_names.push(record.get('Name'));
//iteration_names.push(record.get('ReleaseDate'));
retrievedColumns.push({
value: record,
_planned_velocity: 0,
_missing_estimate: false,
columnHeaderConfig: {
headerTpl: "{name}<br/>{start_date} - {end_date}",
headerData: {
name: record.get('Name'),
start_date: start_date,
end_date: end_date,
planned_velocity: 0,
missing_estimate: false
}
}
});
});
this._getAllReleases(retrievedColumns,iteration_names);
},
scope: this
}
});
},
applyLocalFilters: function() {
this.applyFilters(this.localFilters);
},
_getAllReleases: function(retrievedColumns,iteration_names, today_iso) {
var me = this;
if (today_iso == undefined) {
today_iso = Rally.util.DateTime.toIsoString(new Date(),false);
}
var filters = [{property:'ReleaseDate',operator:'>',value:today_iso}];
Ext.create('Rally.data.WsapiDataStore',{
model:me.attribute,
autoLoad: true,
filters: filters,
sorters: [
{
property: 'ReleaseDate',
direction: 'ASC'
}
],
fetch: ['Name','Project','PlannedVelocity'],
listeners: {
load: function(store,records) {
Ext.Array.each(records, function(record){
var planned_velocity = record.get('PlannedVelocity') || 0;
var index = Ext.Array.indexOf(iteration_names[0],record.get('Name'));
if (planned_velocity == 0 ) {
retrievedColumns[index+1]._missing_estimate = true;
}
retrievedColumns[index+1]._planned_velocity += planned_velocity;
});
this.fireEvent('columnsretrieved',this,retrievedColumns);
this.columnDefinitions = [];
_.map(retrievedColumns,this.addColumn,this);
this._renderColumns();
},
scope: this
}
});
},
_createColumnDefinition: function (columnConfig) {
var config = Ext.merge({
enableCrossColumnRanking: this.enableCrossColumnRanking
}, this.columnConfig, columnConfig);
var enableRanking = this.enableRanking;
if (this.context) {
var workspace = this.context.getWorkspace();
if (workspace) {
enableRanking = enableRanking && workspace.WorkspaceConfiguration.DragDropRankingEnabled;
}
}
var listenersConfig = {
ready: this._onColumnReady,
select: this._onCardSelect,
deselect: this._onCardDeselect,
cardinvalid: this._onCardInvalid,
cardready: this._onCardReady,
scope: this
};
if (!this.serverSideFiltering) {
listenersConfig.filter = this.applyLocalFilters;
}
Ext.merge(config, {
cardConfig: Ext.clone(this.cardConfig),
columnHeaderConfig: Ext.clone(this.columnHeaderConfig),
model: this.models,
attribute: this.attribute,
storeConfig: Ext.clone(this.storeConfig),
enableRanking: enableRanking,
filterCollection: this.filterCollection ? this.filterCollection.clone() : undefined,
ownerCardboard: this,
listeners: listenersConfig,
ddGroup: this.ddGroup
});
if (this.readOnly) {
config.dropControllerConfig = false;
}
//merge configs, unioning collections
var cardConfig = config.cardConfig;
if (columnConfig.cardConfig) {
Ext.Object.merge(cardConfig, columnConfig.cardConfig);
cardConfig.fields = Ext.Array.merge(columnConfig.cardConfig.fields || [], this.cardConfig.fields || []);
}
var storeConfig = config.storeConfig;
if (columnConfig.storeConfig) {
Ext.Object.merge(storeConfig, columnConfig.storeConfig);
storeConfig.filters = Ext.Array.merge(columnConfig.storeConfig.filters || [], this.storeConfig.filters || []);
}
console.log("columnConfig", Ext.clone(columnConfig));
console.log("storeConfig", Ext.clone(storeConfig));
return Ext.widget(config.xtype, config);
},
});
Ext.override(Rally.ui.cardboard.Card,{
_setupPlugins: function() {
var cardContentRightPlugin = {ptype: 'rallycardcontentright'};
this.plugins.push(cardContentRightPlugin);
this.plugins.push({ptype: 'rallycardcontentleft'});
if (this.record.get('updatable')) {
if (this.editable) {
this.addCls('editable');
this.plugins.push({ptype: 'rallycardediting'});
var predicateFn = Rally.predicate.RecordPredicates.hasField('PlanEstimate');
if (predicateFn(this.record) && Ext.Array.contains(this.getFields(), 'PlanEstimate')) {
cardContentRightPlugin.showPlanEstimate = true;
}
if (this.enableValidationUi) {
this.plugins.push({ptype: 'rallycardvalidation'});
this.plugins.push({ptype: 'rallycardvalidationui', notificationFieldNames: ['PlanEstimate']});
}
}
if (this.showIconsAndHighlightBorder) {
this.plugins.push({
ptype: 'rallycardicons',
showMenus: this.showIconMenus,
showColorPopover: this.showColorPopover
});
}
}
if (this.showAge > -1) {
this.plugins.push({ptype: 'rallycardage'});
}
this.plugins.push({ptype:'tscardreleasealignment'});
}
}),
Ext.override(Rally.ui.cardboard.Column,{
getStoreFilter: function(model) {
var property = this.attribute;
var value = this.getValue();
if ( this.attribute == "Release" ) {
property = "Release.Name";
if ( value ) {
value = value.get('Name');
}
}
return {
property:property,
operator: '=',
value: value
};
},
isMatchingRecord: function(record) {
var recordValue = record.get(this.attribute);
if (recordValue) {
recordValue = recordValue.Name;
}
var columnValue = this.getValue();
if ( columnValue ) {
columnValue = columnValue.get('Name');
}
return (columnValue === recordValue );
},
addCard: function(card, index, highlight) {
var record = card.getRecord();
var target_value = this.getValue();
if ( target_value && typeof(target_value.get) === "function" ) {
target_value = this.getValue().get('_ref');
}
record.set(this.attribute,target_value);
if (target_value) {
record.set("PlannedStartDate",this.getValue().get('ReleaseStartDate'));
record.set("PlannedEndDate",this.getValue().get('ReleaseDate'));
} else {
record.set("PlannedStartDate",null);
record.set("PlannedEndDate",null);
}
if (!Ext.isNumber(index)) {
//find where it should go
var records = Ext.clone(this.getRecords());
records.push(record);
this._sortRecords(records);
var recordIndex = 0;
for (var iIndex = 0, l = records.length; iIndex < l; iIndex++) {
var i = records[iIndex];
if (i.get("ObjectID") === record.get("ObjectID")) {
recordIndex = iIndex;
break;
}
}
index = recordIndex;
}
this._renderCard(card, index);
if (highlight) {
card.highlight();
}
this.fireEvent('addcard');
card.fireEvent('ready', card);
},

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);
},
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'
}
]
});
}
});

Resources