Update new Data to the Chart in 2.0Rc1 - rally

Here's the sample code
I tried with update and other functions, none of them worked
launch: function() {
var categories = ['EMEA','APAC','AMERICAS'],
name = 'Browser brands',
data = [{
y: 55.11,
drilldown: {
name: 'EMEA versions',
categories: ['Cost', 'TechMe', 'disc', 'Matt'],
data: [
{
y: 40.11,
drilldown: {
name: 'Cost Drill',
categories: ['Page 1', 'Page 2', 'Page 3.0', 'Page 4.0'],
data: [0.20, 0.83, 1.58, 13.12, 5.43]
}
},
{
y: 40.11,
drilldown: {
name: 'Techme Drill',
categories: ['Page 1', 'Page 2', 'Page 3.0', 'Page 4.0'],
data: [1.58, 13.12, 5.43,0.20, 0.83]
}
},
{
y: 40.11,
drilldown: {
name: 'dISC Drill',
categories: ['Page 1', 'Page 2', 'Page 3.0', 'Page 4.0'],
data: [0.83, 1.58, 13.12,0.20, 5.43]
}
}
]
}
}, {
y: 21.63,
drilldown: {
name: 'Firefox versions',
categories: ['Firefox 2.0', 'Firefox 3.0', 'Firefox 3.5', 'Firefox 3.6', 'Firefox 4.0'],
data: [0.20, 0.83, 1.58, 13.12, 5.43]
}
}, {
y: 11.94,
drilldown: {
name: 'Chrome versions',
categories: ['Chrome 5.0', 'Chrome 6.0', 'Chrome 7.0', 'Chrome 8.0', 'Chrome 9.0',
'Chrome 10.0', 'Chrome 11.0', 'Chrome 12.0'],
data: [0.12, 0.19, 0.12, 0.36, 0.32, 9.91, 0.50, 0.22]
}
}, {
y: 7.15,
drilldown: {
name: 'Safari versions',
categories: ['Safari 5.0', 'Safari 4.0', 'Safari Win 5.0', 'Safari 4.1', 'Safari/Maxthon',
'Safari 3.1', 'Safari 4.1'],
data: [4.55, 1.42, 0.23, 0.21, 0.20, 0.19, 0.14]
}
}, {
y: 2.14,
drilldown: {
name: 'Opera versions',
categories: ['Opera 9.x', 'Opera 10.x', 'Opera 11.x'],
data: [ 0.12, 0.37, 1.65]
}
}];
Here's the setChart function which is called on click event of the chart
function setChart(chart,name, categories, data, color) {
var newchart=mychart;
var chartConfig={
chart: {
type: 'column'
},
title: {
text: 'Browser market share, April, 2011'
},
subtitle: {
text: 'Click the columns to view versions. Click again to view brands.'
},
xAxis: {
categories: categories
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
column: {
cursor: 'pointer',
point: {
events: {
click: function() {
var drilldown = this.drilldown;
if (drilldown) { // drill down
setChart(this,drilldown.name, drilldown.categories, drilldown.data, drilldown.color);
} else { // restore
setChart(this,name, categories, data);
}
}
}
},
dataLabels: {
enabled: true,
style: {
fontWeight: 'bold'
},
formatter: function() {
return this.y +'%';
}
}
}
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x +':<b>'+ this.y +'% market share</b><br/>';
if (point.drilldown) {
s += 'Click to view '+ point.category +' versions';
} else {
s += 'Click to return to browser brands';
}
return s;
}
}
}
console.log("Before ",newchart.chartConfig);
newchart.setChartConfig(chartConfig);
console.log("After ",newchart.chartConfig);
var chartSeries={
name: name,
data: data,
color: 'white'
}
newchart.setChartData(chartSeries);
chart.remove('#myChart');
//chart.update(newchart);
//redrawChart(this,mychart);
//console.log(mychart);
// console.log(chart.setChartConfig());
//chart.x.setCategories(categories, false);
//chart.chartData.series[0].remove(false);
/*chart.chartData.addSeries({
name: name,
data: data,
color: color || 'white'
}, false);*/
//chart.redraw();
// mychart.update();
//mychart.updateLayout();
// mychart.show();
console.log("After " , mychart);
}
Main chart is here ...
var mychart=Ext.create('Rally.ui.chart.Chart', {
autoRender:true,
autoShow:true,
id:'myChart',
storeType : 'Rally.data.WsapiDataStore',
storeConfig : {
model: 'Defect'
//fetch : ["_ValidFrom", "_ValidTo", "10778908645", "ScheduleState", "Name"]
//filters : this.getColumnFilters()
},
calculatorType: 'My.Calculator',
calculatorConfig: {},
chartConfig: {
chart: {
type: 'column'
},
title: {
text: 'Browser market share, April, 2011'
},
subtitle: {
text: 'Click the columns to view versions. Click again to view brands.'
},
xAxis: {
categories: categories
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
column: {
cursor: 'pointer',
point: {
events: {
click: function() {
var drilldown = this.drilldown;
if (drilldown) { // drill down
setChart(this,drilldown.name, drilldown.categories, drilldown.data, drilldown.color);
} else { // restore
setChart(this,name, categories, data);
}
}
}
},
dataLabels: {
enabled: true,
style: {
fontWeight: 'bold'
},
formatter: function() {
return this.y +'%';
}
}
}
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x +':<b>'+ this.y +'% market share</b><br/>';
if (point.drilldown) {
s += 'Click to view '+ point.category +' versions';
} else {
s += 'Click to return to browser brands';
}
return s;
}
}
},
chartData:{ // this works
series: [{
name: name,
data: data,
color: 'white'
}],
exporting: {
enabled: false
}
}
});
// add your code here
this.add(mychart); // add the component to rally interface
}
I want data to get changed on clicking

I have an example of chart update triggered by a button click in a github repo here.
Unlike a AppSDK2 grids that have a reconfigure method, AppSDK charts do not. In this example I delete a chart this.down("#myChart").removeAll() , modify metric definition of the calculator and then re-add the chart to the app.
You may also want to see this post.

Related

Restricting a Rally chart snapshot store to a date period

I want to show some data from Rally using snapshot sotre passed to teh chart like this:
storeConfig: {
find: {
_ItemHierarchy: 15312401235, //PI Object ID
//Release: 9045474054,
_TypeHierarchy: 'HierarchicalRequirement', //Burn on stories
Children: null, //Only include leaf stories,
_ValidTo: { $gte: me._startDateField.value },
_ValidFrom: { $lte: me._endDateField.value }
},
fetch: ['ScheduleState', 'PlanEstimate'],
hydrate: ['ScheduleState'],
sort: {
'_ValidFrom': 1
}
}
The idea is that I want the chart to show only yhe period between Start Date and End Date specified in me._startDateField.value and me._endDateField.value. What is the way of achieving this? Because now the chart displays the data starting from January and not from Start Date.
This example restricts the end date to a selection in the second rallydatepicker instead of defaulting to today's date. See Readme here.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var that = this;
var minDate = new Date(new Date() - 86400000*90); //milliseconds in day = 86400000
var datePicker = Ext.create('Ext.panel.Panel', {
title: 'Choose start and end dates:',
bodyPadding: 10,
renderTo: Ext.getBody(),
layout: 'hbox',
items: [{
xtype: 'rallydatepicker',
itemId: 'from',
minDate: minDate,
handler: function(picker, date) {
that.onStartDateSelected(date);
}
},
{
xtype: 'rallydatepicker',
itemId: 'to',
minDate: minDate,
handler: function(picker, date) {
that.onEndDateSelected(date);
}
}]
});
this.add(datePicker);
var panel = Ext.create('Ext.panel.Panel', {
id:'infoPanel',
componentCls: 'panel'
});
this.add(panel);
},
onStartDateSelected:function(date){
console.log(date);
this._startDate = date;
},
onEndDateSelected:function(date){
this._endDate = date;
console.log(date);
Ext.getCmp('infoPanel').update('showing data between ' + this._startDate + ' and ' + this._endDate);
this.defineCalculator();
this.makeChart();
},
defineCalculator: function(){
var that = this;
Ext.define("MyDefectCalculator", {
extend: "Rally.data.lookback.calculator.TimeSeriesCalculator",
getMetrics: function () {
var metrics = [
{
field: "State",
as: "Open",
display: "column",
f: "filteredCount",
filterField: "State",
filterValues: ["Submitted","Open"]
},
{
field: "State",
as: "Closed",
display: "column",
f: "filteredCount",
filterField: "State",
filterValues: ["Fixed","Closed"]
}
];
return metrics;
}
});
},
makeChart: function(){
if (this.down('#myChart')) {
this.remove('myChart');
}
var timePeriod = new Date(this._endDate - this._startDate);
var project = this.getContext().getProject().ObjectID;
var storeConfig = this.createStoreConfig(project, timePeriod);
this.chartConfig.calculatorConfig.startDate = Rally.util.DateTime.format(new Date(this._startDate), 'Y-m-d');
this.chartConfig.calculatorConfig.endDate = Rally.util.DateTime.format(new Date(this._endDate), 'Y-m-d');
this.chartConfig.storeConfig = storeConfig;
this.add(this.chartConfig);
},
createStoreConfig : function(project, interval ) {
return {
listeners : {
load : function(store,data) {
console.log("data",data.length);
}
},
filters: [
{
property: '_ProjectHierarchy',
operator : 'in',
value : [project]
},
{
property: '_TypeHierarchy',
operator: 'in',
value: ['Defect']
},
{
property: '_ValidFrom',
operator: '>=',
value: interval
}
],
autoLoad : true,
limit: Infinity,
fetch: ['State'],
hydrate: ['State']
};
},
chartConfig: {
xtype: 'rallychart',
itemId : 'myChart',
chartColors: ['Red', 'Green'],
storeConfig: { },
calculatorType: 'MyDefectCalculator',
calculatorConfig: {
},
chartConfig: {
plotOptions: {
column: { stacking: 'normal'}
},
chart: { },
title: { text: 'Open/Closed Defects'},
xAxis: {
tickInterval: 1,
labels: {
formatter: function() {
var d = new Date(this.value);
return ""+(d.getMonth()+1)+"/"+d.getDate();
}
},
title: {
text: 'Date'
}
},
yAxis: [
{
title: {
text: 'Count'
}
}
]
}
}
});

How to show task revisions in custom grid?

I have a custom grid that displays open tasks filtered by (Owner = some-user#company.com).
I would like to include the last revision for each task in a custom grid, but the Revision column is not available on the settings dialog. How to traverse from Revision History to individual revisions?
It can't be done with a custom grid, but can be done with a custom code. Here is an app example that populates a grid based on a selection in the UserSearchComboBox , and then displays the last revision of a selected task on a click event.
You may copy the html file into a custom page from this github repo:
Here is the js file:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var context = this.getContext ();
var currentProject = context.getProject()._ref;
var panel = Ext.create('Ext.panel.Panel', {
layout: 'hbox',
itemId: 'parentPanel',
componentCls: 'panel',
items: [
{
xtype: 'rallyusersearchcombobox',
fieldLabel: 'SELECT USER:',
project: currentProject,
listeners:{
ready: function(combobox){
this._onUserSelected(combobox.getRecord());
},
select: function(combobox){
if (this.down('#c').html !== 'No task is selected') {
Ext.getCmp('c').update('No task is selected');
}
this._onUserSelected(combobox.getRecord());
},
scope: this
}
},
{
xtype: 'panel',
title: 'Tasks',
width: 600,
itemId: 'childPanel1'
},
{
xtype: 'panel',
title: 'Last Revision',
width: 600,
itemId: 'childPanel2'
}
],
});
this.add(panel);
this.down('#childPanel2').add({
id: 'c',
padding: 10,
maxWidth: 600,
maxHeight: 400,
overflowX: 'auto',
overflowY: 'auto',
html: 'No task is selected'
});
},
_onUserSelected:function(record){
var user = record.data['_ref'];
if(user){
var filter = Ext.create('Rally.data.QueryFilter', {
property: 'Owner',
operator: '=',
value: user
});
filter = filter.and({
property: 'State',
operator: '<',
value: 'Completed'
});
filter.toString();
Ext.create('Rally.data.WsapiDataStore', {
model: 'Task',
fetch: [ 'DragAndDropRank','FormattedID','Name','State','RevisionHistory'],
autoLoad: true,
filters : [filter],
sorters:[
{
property: 'DragAndDropRank',
direction: 'ASC'
}
],
listeners: {
load: this._onTaskDataLoaded,
scope: this
}
});
}
},
_onTaskDataLoaded: function(store, data) {
var customRecords = [];
Ext.Array.each(data, function(task, index) {
customRecords.push({
_ref: task.get('_ref'),
FormattedID: task.get('FormattedID'),
Name: task.get('Name'),
RevisionID: Rally.util.Ref.getOidFromRef(task.get('RevisionHistory')),
});
}, this);
this._updateGrid(store,data);
},
_updateGrid: function(store, data){
if (!this.down('#g')) {
this._createGrid(store,data);
}
else{
this.down('#g').reconfigure(store);
}
},
_createGrid: function(store,data){
var that = this;
var g = Ext.create('Rally.ui.grid.Grid', {
id: 'g',
store: store,
enableRanking: true,
columnCfgs: [
{text: 'Formatted ID', dataIndex: 'FormattedID'},
{text: 'Name', dataIndex: 'Name'},
{text: 'State', dataIndex: 'State'},
{text: 'Last Revision',
renderer: function (v, m, r) {
var id = Ext.id();
Ext.defer(function () {
Ext.widget('button', {
renderTo: id,
text: 'see',
width: 50,
handler: function () {
console.log('r', r.data);
that._getRevisionHistory(data, r.data);
}
});
}, 50);
return Ext.String.format('<div id="{0}"></div>', id);
}
}
],
height: 400,
});
this.down('#childPanel1').add(g);
},
_getRevisionHistory: function(taskList, task) {
this._task = task;
this._revisionModel = Rally.data.ModelFactory.getModel({
type: 'RevisionHistory',
scope: this,
success: this._onModelCreated
});
},
_onModelCreated: function(model) {
model.load(Rally.util.Ref.getOidFromRef(this._task.RevisionHistory._ref),{
scope: this,
success: this._onModelLoaded
});
},
_onModelLoaded: function(record, operation) {
record.getCollection('Revisions').load({
fetch: true,
scope: this,
callback: function(revisions, operation, success) {
this._onRevisionsLoaded(revisions, record);
}
});
},
_onRevisionsLoaded: function(revisions, record) {
var lastRev = _.first(revisions).data;
console.log('_onRevisionsLoaded: ',lastRev.Description, lastRev.RevisionNumber, lastRev.CreationDate );
this._displayLastRevision(lastRev.Description,lastRev.RevisionNumber, lastRev.CreationDate );
},
_displayLastRevision:function(desc, num, date){
Ext.getCmp('c').update('<b>' + this._task.FormattedID + '</b><br/><b>Revision CreationDate: </b>' + date +'<br /><b>Description:</b>' + desc + '<br /><b>Revision Number:</b>' + num + '<br />');
}
});

Kendo Change SeriesDefault Chart Type Dynamically

The Code works But I wanna Change Chart Type Dynamically. I tried Change Chart Type in function WeightLine However It does not work. It changes SeriesDefault type , I see new chart type in alert but does not draw new chart type.
var mydata=[{"date":"2013-03-06","data":2916,"name":"weight"},{"date":"2013-03-05","data":3708,"name":"weight"}];
function getFilter(xMin, xMax) {
return [{
field: "date",
operator: "gt",
value: xMin
}, {
field: "date",
operator: "lt",
value: xMax
}];
}
$("#line_chart_weight").kendoChart({
title: {
text: "weight"
},
dataSource:{
data: mydata,
group: {
field: "name"
},
sort: {
field: "date",
dir: "asc"
},
schema: {
model: {
fields: {
date: {
type: "date"
}
}
}
}
},
seriesDefaults: {
type: "scatterLine"
},
series: [{
xField:"date",
yField: "data"
}],
yAxis: {
labels: {
format: "{0}"
},
title: {
text: "KG",
padding: {
left: 20
}}
}, xAxis: {
labels:
{
rotation: -90,
format:"dd-MM-yyyy"
},
title: {
text: "Date",
padding: {
top: 20
}},
type:"date",
name:"CategoryAxis"
},
tooltip: {
visible: true,
format:"dd-MM-yyyy",
color:"white"
},
transitions: false,
drag: onDragw,
zoom: onDragw
});
var weight=$("#line_chart_weight").data("kendoChart");
function onDragw(e) {
var ds = weight.dataSource;
var options = weight.options;
e.originalEvent.preventDefault();
var categoryRange = e.axisRanges.CategoryAxis;
if (categoryRange) {
var xMin = categoryRange.min;
var xMax = categoryRange.max;
options.categoryAxis.min = xMin;
options.categoryAxis.max = xMax;
ds.filter(getFilter(xMin, xMax));
weight.redraw();
}
}
function WeightLine(WeightTypeString){ weight.options.seriesDefaults.type=WeightTypeString;alert(weight.options.seriesDefaults.type); weight.redraw();}
it is a bit weird but i write something to solve this. both of them worked for me. You can modify them for your code.
1.
var chart = $("#chartId").data("kendoChart");
chart.setOptions({ seriesDefaults: {type : "radarColumn"} });
chart.dataSource.read();
chart.refresh();
2.
var chart = $("#chartId").data("kendoChart");
for(i = 0; i< chart.options.series.length;i++){
chart.options.series[i].type = "radarColumn";
}
chart.refresh();

RallyChart with the type being pie

I am trying to connect a RallyChart using the type specifier set to pie with a Rally.data.custom.Store. When the RallyChart has the type set to column or is blank, the data shows correctly. When the type is set to pie, I get a pie with all 0%s returned.
Here's what my store looks like:
var myStore = Ext.create('Rally.data.custom.Store', {
data: mySeries,
fields: [
{ name: 'WorkItems', type: 'string' },
{ name: 'Count', type: 'int' }
]
});
Here's what my chart configuration function looks like:
_buildChart: function(myStore) {
this.myChart = Ext.create('Rally.ui.chart.Chart', {
height: 400,
store: myStore,
series: [{
type: 'pie',
name: 'Count',
dataIndex: 'Count'
}],
xField: 'WorkItems',
chartConfig: {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Work Breakdown in Selected Sprint'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';
}
}
}
}
}
});
this.add(this.myChart);
}
My data incoming looks like:
['Defects', 4],
['Feature A', 4]
['Feature B', 4]
Any ideas why column charts can show it, but pie cannot?
I bet this is a bug in the 2.0p5 version of the chart. We just released version 2.0rc1 of the SDK which includes a better version of the chart. The following code example shows how to create a pie with your data and Rally.ui.chart.Chart in 2.0rc1:
//from inside your app
this.add({
xtype: 'rallychart',
height: 400,
chartData: {
series: [{
type: 'pie',
name: 'Browser share',
data: [
['Defects', 4], ['Feature A', 4], ['Feature B', 4]
]
}]
},
chartConfig: {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
xAxis: {},//must specify empty x-axis due to bug
title: {
text: 'Work Breakdown in Selected Sprint'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';
}
}
}
}
}
});
Note it is no longer necessary to create an intermediate store to pass to the chart- you can simply pass in your series as part of the chartData config.

Sencha touch 2 list with buttons

Need to create a list in sencha touch 2 with items like
label1
label2
button1 button2 button3
label1
label2
button1 button2 button3
on clicking the button a poppup should come pointing it.
I know I need to use Dataview for creating the list. But I have no idea of creating such a layout using dataview. any help would greatly appreciated.
Here is the code required to create your layout.
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
launch: function () {
Ext.define('MyListItem', {
extend: 'Ext.dataview.component.DataItem',
requires: ['Ext.Button'],
xtype: 'mylistitem',
config: {
labelPanel:{
itemId:'labelpanel',
layout:'hbox',
defaults:{
//flex:1,
xtype:'label'
}
},
fnameLabel: true,
lnameLabel: {
style:'margin-left:5px'
},
horizontalPanel: {
layout: 'hbox',
defaults:{
xtype:'button',
flex:1
},
items: [{
text: 'First Name',
btnId:1
}, {
text: 'Last Name',
btnId:2
}, {
text: 'Age',
btnId:3
}]
},
dataMap: {
getFnameLabel: {
setHtml: 'fname'
},
getLnameLabel: {
setHtml: 'lname'
}
},
layout: 'vbox'
},
applyFnameLabel: function (config) {
return Ext.factory(config, Ext.Label, this.getFnameLabel());
},
updateFnameLabel: function (newFnameLabel, oldFnameLabel) {
if (oldFnameLabel) {
this.down('panel[itemId="labelpanel"]').remove(oldFnameLabel);
}
if (newFnameLabel) {
this.down('panel[itemId="labelpanel"]').add(newFnameLabel);
}
},
applyLnameLabel: function (config) {
return Ext.factory(config, Ext.Label, this.getLnameLabel());
},
updateLnameLabel: function (newLnameLabel, oldLnameLabel) {
if (oldLnameLabel) {
this.down('panel[itemId="labelpanel"]').remove(oldLnameLabel);
}
if (newLnameLabel) {
this.down('panel[itemId="labelpanel"]').add(newLnameLabel);
}
},
applyLabelPanel: function (config) {
return Ext.factory(config, Ext.Panel, this.getLabelPanel());
},
updateLabelPanel: function (newLabelPanel, oldLabelPanel) {
if (oldLabelPanel) {
this.remove(oldLabelPanel);
}
if (newLabelPanel) {
this.add(newLabelPanel);
}
},
applyHorizontalPanel: function (config) {
return Ext.factory(config, Ext.Panel, this.getHorizontalPanel());
},
updateHorizontalPanel: function (newHorizontalPanel, oldHorizontalPanel) {
if (oldHorizontalPanel) {
this.remove(oldHorizontalPanel);
}
if (newHorizontalPanel) {
//console.info(newHorizontalPanel.down('button[btnId=1]'));
newHorizontalPanel.down('button[btnId=1]').on('tap', this.onButtonTap, this);
newHorizontalPanel.down('button[btnId=2]').on('tap', this.onButtonTap, this);
newHorizontalPanel.down('button[btnId=3]').on('tap', this.onButtonTap, this);
this.add(newHorizontalPanel);
}
},
onButtonTap: function (button, e) {
var record = this.getRecord();
var id = button.config.btnId;
switch(id){
case 1: var value = record.get('fname');break;
case 2: var value = record.get('lname');break;
case 3: var value = record.get('age').toString();break;
}
Ext.Msg.alert(value,"The value is: " +value);
}
});
Ext.create('Ext.DataView', {
fullscreen: true,
store: {
fields: ['fname','lname','age'],
data: [{
fname: 'Jamie',
lname: 'Avins',
age: 100
}, {
fname: 'Rob',
lname: 'Dougan',
age: 21
}, {
fname: 'Tommy',
lname: 'Maintz',
age: 24
}, {
fname: 'Jacky',
lname: 'Nguyen',
age: 24
}, {
fname: 'Ed',
lname: 'Spencer',
age: 26
}]
},
useComponents: true,
defaultType: 'mylistitem'
});
}
});
This fiddle should give you an idea. Read this link from the sencha blog. It explains the code.